summaryrefslogtreecommitdiffstats
path: root/drivers/slimbus/slimbus.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/slimbus/slimbus.h')
-rw-r--r--drivers/slimbus/slimbus.h53
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/slimbus/slimbus.h b/drivers/slimbus/slimbus.h
index 0d40c2578c28..db089134f673 100644
--- a/drivers/slimbus/slimbus.h
+++ b/drivers/slimbus/slimbus.h
@@ -14,6 +14,16 @@
/* SLIMbus message types. Related to interpretation of message code. */
#define SLIM_MSG_MT_CORE 0x0
+/* Clock pause Reconfiguration messages */
+#define SLIM_MSG_MC_BEGIN_RECONFIGURATION 0x40
+#define SLIM_MSG_MC_NEXT_PAUSE_CLOCK 0x4A
+#define SLIM_MSG_MC_RECONFIGURE_NOW 0x5F
+
+/* Clock pause values per SLIMbus spec */
+#define SLIM_CLK_FAST 0
+#define SLIM_CLK_CONST_PHASE 1
+#define SLIM_CLK_UNSPECIFIED 2
+
/* Destination type Values */
#define SLIM_MSG_DEST_LOGICALADDR 0
#define SLIM_MSG_DEST_ENUMADDR 1
@@ -80,6 +90,42 @@ struct slim_msg_txn {
#define DEFINE_SLIM_LDEST_TXN(name, mc, rl, la, msg) \
struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_LOGICALADDR, 0,\
0, la, msg, }
+
+#define DEFINE_SLIM_BCAST_TXN(name, mc, rl, la, msg) \
+ struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_BROADCAST, 0,\
+ 0, la, msg, }
+/**
+ * enum slim_clk_state: SLIMbus controller's clock state used internally for
+ * maintaining current clock state.
+ * @SLIM_CLK_ACTIVE: SLIMbus clock is active
+ * @SLIM_CLK_ENTERING_PAUSE: SLIMbus clock pause sequence is being sent on the
+ * bus. If this succeeds, state changes to SLIM_CLK_PAUSED. If the
+ * transition fails, state changes back to SLIM_CLK_ACTIVE
+ * @SLIM_CLK_PAUSED: SLIMbus controller clock has paused.
+ */
+enum slim_clk_state {
+ SLIM_CLK_ACTIVE,
+ SLIM_CLK_ENTERING_PAUSE,
+ SLIM_CLK_PAUSED,
+};
+
+/**
+ * struct slim_sched: Framework uses this structure internally for scheduling.
+ * @clk_state: Controller's clock state from enum slim_clk_state
+ * @pause_comp: Signals completion of clock pause sequence. This is useful when
+ * client tries to call SLIMbus transaction when controller is entering
+ * clock pause.
+ * @m_reconf: This mutex is held until current reconfiguration (data channel
+ * scheduling, message bandwidth reservation) is done. Message APIs can
+ * use the bus concurrently when this mutex is held since elemental access
+ * messages can be sent on the bus when reconfiguration is in progress.
+ */
+struct slim_sched {
+ enum slim_clk_state clk_state;
+ struct completion pause_comp;
+ struct mutex m_reconf;
+};
+
/**
* struct slim_controller - Controls every instance of SLIMbus
* (similar to 'master' on SPI)
@@ -95,6 +141,7 @@ struct slim_msg_txn {
* @devices: Slim device list
* @tid_idr: tid id allocator
* @txn_lock: Lock to protect table of transactions
+ * @sched: scheduler structure used by the controller
* @xfer_msg: Transfer a message on this controller (this can be a broadcast
* control/status message like data channel setup, or a unicast message
* like value element read/write.
@@ -105,6 +152,9 @@ struct slim_msg_txn {
* address table and get_laddr can be used in that case so that controller
* can do this assignment. Use case is when the master is on the remote
* processor side, who is resposible for allocating laddr.
+ * @wakeup: This function pointer implements controller-specific procedure
+ * to wake it up from clock-pause. Framework will call this to bring
+ * the controller out of clock pause.
*
* 'Manager device' is responsible for device management, bandwidth
* allocation, channel setup, and port associations per channel.
@@ -139,12 +189,14 @@ struct slim_controller {
struct list_head devices;
struct idr tid_idr;
spinlock_t txn_lock;
+ struct slim_sched sched;
int (*xfer_msg)(struct slim_controller *ctrl,
struct slim_msg_txn *tx);
int (*set_laddr)(struct slim_controller *ctrl,
struct slim_eaddr *ea, u8 laddr);
int (*get_laddr)(struct slim_controller *ctrl,
struct slim_eaddr *ea, u8 *laddr);
+ int (*wakeup)(struct slim_controller *ctrl);
};
int slim_device_report_present(struct slim_controller *ctrl,
@@ -154,6 +206,7 @@ int slim_register_controller(struct slim_controller *ctrl);
int slim_unregister_controller(struct slim_controller *ctrl);
void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 l);
int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn);
+int slim_ctrl_clk_pause(struct slim_controller *ctrl, bool wakeup, u8 restart);
static inline bool slim_tid_txn(u8 mt, u8 mc)
{