Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Copyright (c) 2011-2017, The Linux Foundation
0004  */
0005 
0006 #ifndef _DRIVERS_SLIMBUS_H
0007 #define _DRIVERS_SLIMBUS_H
0008 #include <linux/module.h>
0009 #include <linux/device.h>
0010 #include <linux/mutex.h>
0011 #include <linux/completion.h>
0012 #include <linux/slimbus.h>
0013 
0014 /* Standard values per SLIMbus spec needed by controllers and devices */
0015 #define SLIM_CL_PER_SUPERFRAME      6144
0016 #define SLIM_CL_PER_SUPERFRAME_DIV8 (SLIM_CL_PER_SUPERFRAME >> 3)
0017 
0018 /* SLIMbus message types. Related to interpretation of message code. */
0019 #define SLIM_MSG_MT_CORE            0x0
0020 #define SLIM_MSG_MT_DEST_REFERRED_USER      0x2
0021 #define SLIM_MSG_MT_SRC_REFERRED_USER       0x6
0022 
0023 /*
0024  * SLIM Broadcast header format
0025  * BYTE 0: MT[7:5] RL[4:0]
0026  * BYTE 1: RSVD[7] MC[6:0]
0027  * BYTE 2: RSVD[7:6] DT[5:4] PI[3:0]
0028  */
0029 #define SLIM_MSG_MT_MASK    GENMASK(2, 0)
0030 #define SLIM_MSG_MT_SHIFT   5
0031 #define SLIM_MSG_RL_MASK    GENMASK(4, 0)
0032 #define SLIM_MSG_RL_SHIFT   0
0033 #define SLIM_MSG_MC_MASK    GENMASK(6, 0)
0034 #define SLIM_MSG_MC_SHIFT   0
0035 #define SLIM_MSG_DT_MASK    GENMASK(1, 0)
0036 #define SLIM_MSG_DT_SHIFT   4
0037 
0038 #define SLIM_HEADER_GET_MT(b)   ((b >> SLIM_MSG_MT_SHIFT) & SLIM_MSG_MT_MASK)
0039 #define SLIM_HEADER_GET_RL(b)   ((b >> SLIM_MSG_RL_SHIFT) & SLIM_MSG_RL_MASK)
0040 #define SLIM_HEADER_GET_MC(b)   ((b >> SLIM_MSG_MC_SHIFT) & SLIM_MSG_MC_MASK)
0041 #define SLIM_HEADER_GET_DT(b)   ((b >> SLIM_MSG_DT_SHIFT) & SLIM_MSG_DT_MASK)
0042 
0043 /* Device management messages used by this framework */
0044 #define SLIM_MSG_MC_REPORT_PRESENT               0x1
0045 #define SLIM_MSG_MC_ASSIGN_LOGICAL_ADDRESS       0x2
0046 #define SLIM_MSG_MC_REPORT_ABSENT                0xF
0047 
0048 /* Data channel management messages */
0049 #define SLIM_MSG_MC_CONNECT_SOURCE      0x10
0050 #define SLIM_MSG_MC_CONNECT_SINK        0x11
0051 #define SLIM_MSG_MC_DISCONNECT_PORT     0x14
0052 #define SLIM_MSG_MC_CHANGE_CONTENT      0x18
0053 
0054 /* Clock pause Reconfiguration messages */
0055 #define SLIM_MSG_MC_BEGIN_RECONFIGURATION        0x40
0056 #define SLIM_MSG_MC_NEXT_PAUSE_CLOCK             0x4A
0057 #define SLIM_MSG_MC_NEXT_DEFINE_CHANNEL          0x50
0058 #define SLIM_MSG_MC_NEXT_DEFINE_CONTENT          0x51
0059 #define SLIM_MSG_MC_NEXT_ACTIVATE_CHANNEL        0x54
0060 #define SLIM_MSG_MC_NEXT_DEACTIVATE_CHANNEL      0x55
0061 #define SLIM_MSG_MC_NEXT_REMOVE_CHANNEL          0x58
0062 #define SLIM_MSG_MC_RECONFIGURE_NOW              0x5F
0063 
0064 /* Clock pause values per SLIMbus spec */
0065 #define SLIM_CLK_FAST               0
0066 #define SLIM_CLK_CONST_PHASE            1
0067 #define SLIM_CLK_UNSPECIFIED            2
0068 
0069 /* Destination type Values */
0070 #define SLIM_MSG_DEST_LOGICALADDR   0
0071 #define SLIM_MSG_DEST_ENUMADDR      1
0072 #define SLIM_MSG_DEST_BROADCAST     3
0073 
0074 /* Standard values per SLIMbus spec needed by controllers and devices */
0075 #define SLIM_MAX_CLK_GEAR       10
0076 #define SLIM_MIN_CLK_GEAR       1
0077 #define SLIM_SLOT_LEN_BITS      4
0078 
0079 /* Indicate that the frequency of the flow and the bus frequency are locked */
0080 #define SLIM_CHANNEL_CONTENT_FL     BIT(7)
0081 
0082 /* Standard values per SLIMbus spec needed by controllers and devices */
0083 #define SLIM_CL_PER_SUPERFRAME      6144
0084 #define SLIM_SLOTS_PER_SUPERFRAME   (SLIM_CL_PER_SUPERFRAME >> 2)
0085 #define SLIM_SL_PER_SUPERFRAME      (SLIM_CL_PER_SUPERFRAME >> 2)
0086 /* Manager's logical address is set to 0xFF per spec */
0087 #define SLIM_LA_MANAGER 0xFF
0088 
0089 #define SLIM_MAX_TIDS           256
0090 /**
0091  * struct slim_framer - Represents SLIMbus framer.
0092  * Every controller may have multiple framers. There is 1 active framer device
0093  * responsible for clocking the bus.
0094  * Manager is responsible for framer hand-over.
0095  * @dev: Driver model representation of the device.
0096  * @e_addr: Enumeration address of the framer.
0097  * @rootfreq: Root Frequency at which the framer can run. This is maximum
0098  *  frequency ('clock gear 10') at which the bus can operate.
0099  * @superfreq: Superframes per root frequency. Every frame is 6144 bits.
0100  */
0101 struct slim_framer {
0102     struct device       dev;
0103     struct slim_eaddr   e_addr;
0104     int         rootfreq;
0105     int         superfreq;
0106 };
0107 
0108 #define to_slim_framer(d) container_of(d, struct slim_framer, dev)
0109 
0110 /**
0111  * struct slim_msg_txn - Message to be sent by the controller.
0112  *          This structure has packet header,
0113  *          payload and buffer to be filled (if any)
0114  * @rl: Header field. remaining length.
0115  * @mt: Header field. Message type.
0116  * @mc: Header field. LSB is message code for type mt.
0117  * @dt: Header field. Destination type.
0118  * @ec: Element code. Used for elemental access APIs.
0119  * @tid: Transaction ID. Used for messages expecting response.
0120  *  (relevant for message-codes involving read operation)
0121  * @la: Logical address of the device this message is going to.
0122  *  (Not used when destination type is broadcast.)
0123  * @msg: Elemental access message to be read/written
0124  * @comp: completion if read/write is synchronous, used internally
0125  *  for tid based transactions.
0126  */
0127 struct slim_msg_txn {
0128     u8          rl;
0129     u8          mt;
0130     u8          mc;
0131     u8          dt;
0132     u16         ec;
0133     u8          tid;
0134     u8          la;
0135     struct slim_val_inf *msg;
0136     struct  completion  *comp;
0137 };
0138 
0139 /* Frequently used message transaction structures */
0140 #define DEFINE_SLIM_LDEST_TXN(name, mc, rl, la, msg) \
0141     struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_LOGICALADDR, 0,\
0142                     0, la, msg, }
0143 
0144 #define DEFINE_SLIM_BCAST_TXN(name, mc, rl, la, msg) \
0145     struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_BROADCAST, 0,\
0146                     0, la, msg, }
0147 
0148 #define DEFINE_SLIM_EDEST_TXN(name, mc, rl, la, msg) \
0149     struct slim_msg_txn name = { rl, 0, mc, SLIM_MSG_DEST_ENUMADDR, 0,\
0150                     0, la, msg, }
0151 /**
0152  * enum slim_clk_state: SLIMbus controller's clock state used internally for
0153  *  maintaining current clock state.
0154  * @SLIM_CLK_ACTIVE: SLIMbus clock is active
0155  * @SLIM_CLK_ENTERING_PAUSE: SLIMbus clock pause sequence is being sent on the
0156  *  bus. If this succeeds, state changes to SLIM_CLK_PAUSED. If the
0157  *  transition fails, state changes back to SLIM_CLK_ACTIVE
0158  * @SLIM_CLK_PAUSED: SLIMbus controller clock has paused.
0159  */
0160 enum slim_clk_state {
0161     SLIM_CLK_ACTIVE,
0162     SLIM_CLK_ENTERING_PAUSE,
0163     SLIM_CLK_PAUSED,
0164 };
0165 
0166 /**
0167  * struct slim_sched: Framework uses this structure internally for scheduling.
0168  * @clk_state: Controller's clock state from enum slim_clk_state
0169  * @pause_comp: Signals completion of clock pause sequence. This is useful when
0170  *  client tries to call SLIMbus transaction when controller is entering
0171  *  clock pause.
0172  * @m_reconf: This mutex is held until current reconfiguration (data channel
0173  *  scheduling, message bandwidth reservation) is done. Message APIs can
0174  *  use the bus concurrently when this mutex is held since elemental access
0175  *  messages can be sent on the bus when reconfiguration is in progress.
0176  */
0177 struct slim_sched {
0178     enum slim_clk_state clk_state;
0179     struct completion   pause_comp;
0180     struct mutex        m_reconf;
0181 };
0182 
0183 /**
0184  * enum slim_port_direction: SLIMbus port direction
0185  *
0186  * @SLIM_PORT_SINK: SLIMbus port is a sink
0187  * @SLIM_PORT_SOURCE: SLIMbus port is a source
0188  */
0189 enum slim_port_direction {
0190     SLIM_PORT_SINK = 0,
0191     SLIM_PORT_SOURCE,
0192 };
0193 /**
0194  * enum slim_port_state: SLIMbus Port/Endpoint state machine
0195  *  according to SLIMbus Spec 2.0
0196  * @SLIM_PORT_DISCONNECTED: SLIMbus port is disconnected
0197  *  entered from Unconfigure/configured state after
0198  *  DISCONNECT_PORT or REMOVE_CHANNEL core command
0199  * @SLIM_PORT_UNCONFIGURED: SLIMbus port is in unconfigured state.
0200  *  entered from disconnect state after CONNECT_SOURCE/SINK core command
0201  * @SLIM_PORT_CONFIGURED: SLIMbus port is in configured state.
0202  *  entered from unconfigured state after DEFINE_CHANNEL, DEFINE_CONTENT
0203  *  and ACTIVATE_CHANNEL core commands. Ready for data transmission.
0204  */
0205 enum slim_port_state {
0206     SLIM_PORT_DISCONNECTED = 0,
0207     SLIM_PORT_UNCONFIGURED,
0208     SLIM_PORT_CONFIGURED,
0209 };
0210 
0211 /**
0212  * enum slim_channel_state: SLIMbus channel state machine used by core.
0213  * @SLIM_CH_STATE_DISCONNECTED: SLIMbus channel is disconnected
0214  * @SLIM_CH_STATE_ALLOCATED: SLIMbus channel is allocated
0215  * @SLIM_CH_STATE_ASSOCIATED: SLIMbus channel is associated with port
0216  * @SLIM_CH_STATE_DEFINED: SLIMbus channel parameters are defined
0217  * @SLIM_CH_STATE_CONTENT_DEFINED: SLIMbus channel content is defined
0218  * @SLIM_CH_STATE_ACTIVE: SLIMbus channel is active and ready for data
0219  * @SLIM_CH_STATE_REMOVED: SLIMbus channel is inactive and removed
0220  */
0221 enum slim_channel_state {
0222     SLIM_CH_STATE_DISCONNECTED = 0,
0223     SLIM_CH_STATE_ALLOCATED,
0224     SLIM_CH_STATE_ASSOCIATED,
0225     SLIM_CH_STATE_DEFINED,
0226     SLIM_CH_STATE_CONTENT_DEFINED,
0227     SLIM_CH_STATE_ACTIVE,
0228     SLIM_CH_STATE_REMOVED,
0229 };
0230 
0231 /**
0232  * enum slim_ch_data_fmt: SLIMbus channel data Type identifiers according to
0233  *  Table 60 of SLIMbus Spec 1.01.01
0234  * @SLIM_CH_DATA_FMT_NOT_DEFINED: Undefined
0235  * @SLIM_CH_DATA_FMT_LPCM_AUDIO: LPCM audio
0236  * @SLIM_CH_DATA_FMT_IEC61937_COMP_AUDIO: IEC61937 Compressed audio
0237  * @SLIM_CH_DATA_FMT_PACKED_PDM_AUDIO: Packed PDM audio
0238  */
0239 enum slim_ch_data_fmt {
0240     SLIM_CH_DATA_FMT_NOT_DEFINED = 0,
0241     SLIM_CH_DATA_FMT_LPCM_AUDIO = 1,
0242     SLIM_CH_DATA_FMT_IEC61937_COMP_AUDIO = 2,
0243     SLIM_CH_DATA_FMT_PACKED_PDM_AUDIO = 3,
0244 };
0245 
0246 /**
0247  * enum slim_ch_aux_bit_fmt: SLIMbus channel Aux Field format IDs according to
0248  *  Table 63 of SLIMbus Spec 2.0
0249  * @SLIM_CH_AUX_FMT_NOT_APPLICABLE: Undefined
0250  * @SLIM_CH_AUX_FMT_ZCUV_TUNNEL_IEC60958: ZCUV for tunneling IEC60958
0251  * @SLIM_CH_AUX_FMT_USER_DEFINED: User defined
0252  */
0253 enum slim_ch_aux_bit_fmt {
0254     SLIM_CH_AUX_FMT_NOT_APPLICABLE = 0,
0255     SLIM_CH_AUX_FMT_ZCUV_TUNNEL_IEC60958 = 1,
0256     SLIM_CH_AUX_FMT_USER_DEFINED = 0xF,
0257 };
0258 
0259 /**
0260  * struct slim_channel  - SLIMbus channel, used for state machine
0261  *
0262  * @id: ID of channel
0263  * @prrate: Presense rate of channel from Table 66 of SLIMbus 2.0 Specs
0264  * @seg_dist: segment distribution code from Table 20 of SLIMbus 2.0 Specs
0265  * @data_fmt: Data format of channel.
0266  * @aux_fmt: Aux format for this channel.
0267  * @state: channel state machine
0268  */
0269 struct slim_channel {
0270     int id;
0271     int prrate;
0272     int seg_dist;
0273     enum slim_ch_data_fmt data_fmt;
0274     enum slim_ch_aux_bit_fmt aux_fmt;
0275     enum slim_channel_state state;
0276 };
0277 
0278 /**
0279  * struct slim_port  - SLIMbus port
0280  *
0281  * @id: Port id
0282  * @direction: Port direction, Source or Sink.
0283  * @state: state machine of port.
0284  * @ch: channel associated with this port.
0285  */
0286 struct slim_port {
0287     int id;
0288     enum slim_port_direction direction;
0289     enum slim_port_state state;
0290     struct slim_channel ch;
0291 };
0292 
0293 /**
0294  * enum slim_transport_protocol: SLIMbus Transport protocol list from
0295  *  Table 47 of SLIMbus 2.0 specs.
0296  * @SLIM_PROTO_ISO: Isochronous Protocol, no flow control as data rate match
0297  *      channel rate flow control embedded in the data.
0298  * @SLIM_PROTO_PUSH: Pushed Protocol, includes flow control, Used to carry
0299  *      data whose rate is equal to, or lower than the channel rate.
0300  * @SLIM_PROTO_PULL: Pulled Protocol, similar usage as pushed protocol
0301  *      but pull is a unicast.
0302  * @SLIM_PROTO_LOCKED: Locked Protocol
0303  * @SLIM_PROTO_ASYNC_SMPLX: Asynchronous Protocol-Simplex
0304  * @SLIM_PROTO_ASYNC_HALF_DUP: Asynchronous Protocol-Half-duplex
0305  * @SLIM_PROTO_EXT_SMPLX: Extended Asynchronous Protocol-Simplex
0306  * @SLIM_PROTO_EXT_HALF_DUP: Extended Asynchronous Protocol-Half-duplex
0307  */
0308 enum slim_transport_protocol {
0309     SLIM_PROTO_ISO = 0,
0310     SLIM_PROTO_PUSH,
0311     SLIM_PROTO_PULL,
0312     SLIM_PROTO_LOCKED,
0313     SLIM_PROTO_ASYNC_SMPLX,
0314     SLIM_PROTO_ASYNC_HALF_DUP,
0315     SLIM_PROTO_EXT_SMPLX,
0316     SLIM_PROTO_EXT_HALF_DUP,
0317 };
0318 
0319 /**
0320  * struct slim_stream_runtime  - SLIMbus stream runtime instance
0321  *
0322  * @name: Name of the stream
0323  * @dev: SLIM Device instance associated with this stream
0324  * @direction: direction of stream
0325  * @prot: Transport protocol used in this stream
0326  * @rate: Data rate of samples *
0327  * @bps: bits per sample
0328  * @ratem: rate multipler which is super frame rate/data rate
0329  * @num_ports: number of ports
0330  * @ports: pointer to instance of ports
0331  * @node: list head for stream associated with slim device.
0332  */
0333 struct slim_stream_runtime {
0334     const char *name;
0335     struct slim_device *dev;
0336     int direction;
0337     enum slim_transport_protocol prot;
0338     unsigned int rate;
0339     unsigned int bps;
0340     unsigned int ratem;
0341     int num_ports;
0342     struct slim_port *ports;
0343     struct list_head node;
0344 };
0345 
0346 /**
0347  * struct slim_controller  - Controls every instance of SLIMbus
0348  *              (similar to 'master' on SPI)
0349  * @dev: Device interface to this driver
0350  * @id: Board-specific number identifier for this controller/bus
0351  * @name: Name for this controller
0352  * @min_cg: Minimum clock gear supported by this controller (default value: 1)
0353  * @max_cg: Maximum clock gear supported by this controller (default value: 10)
0354  * @clkgear: Current clock gear in which this bus is running
0355  * @laddr_ida: logical address id allocator
0356  * @a_framer: Active framer which is clocking the bus managed by this controller
0357  * @lock: Mutex protecting controller data structures
0358  * @devices: Slim device list
0359  * @tid_idr: tid id allocator
0360  * @txn_lock: Lock to protect table of transactions
0361  * @sched: scheduler structure used by the controller
0362  * @xfer_msg: Transfer a message on this controller (this can be a broadcast
0363  *  control/status message like data channel setup, or a unicast message
0364  *  like value element read/write.
0365  * @set_laddr: Setup logical address at laddr for the slave with elemental
0366  *  address e_addr. Drivers implementing controller will be expected to
0367  *  send unicast message to this device with its logical address.
0368  * @get_laddr: It is possible that controller needs to set fixed logical
0369  *  address table and get_laddr can be used in that case so that controller
0370  *  can do this assignment. Use case is when the master is on the remote
0371  *  processor side, who is resposible for allocating laddr.
0372  * @wakeup: This function pointer implements controller-specific procedure
0373  *  to wake it up from clock-pause. Framework will call this to bring
0374  *  the controller out of clock pause.
0375  * @enable_stream: This function pointer implements controller-specific procedure
0376  *  to enable a stream.
0377  * @disable_stream: This function pointer implements controller-specific procedure
0378  *  to disable stream.
0379  *
0380  *  'Manager device' is responsible for  device management, bandwidth
0381  *  allocation, channel setup, and port associations per channel.
0382  *  Device management means Logical address assignment/removal based on
0383  *  enumeration (report-present, report-absent) of a device.
0384  *  Bandwidth allocation is done dynamically by the manager based on active
0385  *  channels on the bus, message-bandwidth requests made by SLIMbus devices.
0386  *  Based on current bandwidth usage, manager chooses a frequency to run
0387  *  the bus at (in steps of 'clock-gear', 1 through 10, each clock gear
0388  *  representing twice the frequency than the previous gear).
0389  *  Manager is also responsible for entering (and exiting) low-power-mode
0390  *  (known as 'clock pause').
0391  *  Manager can do handover of framer if there are multiple framers on the
0392  *  bus and a certain usecase warrants using certain framer to avoid keeping
0393  *  previous framer being powered-on.
0394  *
0395  *  Controller here performs duties of the manager device, and 'interface
0396  *  device'. Interface device is responsible for monitoring the bus and
0397  *  reporting information such as loss-of-synchronization, data
0398  *  slot-collision.
0399  */
0400 struct slim_controller {
0401     struct device       *dev;
0402     unsigned int        id;
0403     char            name[SLIMBUS_NAME_SIZE];
0404     int         min_cg;
0405     int         max_cg;
0406     int         clkgear;
0407     struct ida      laddr_ida;
0408     struct slim_framer  *a_framer;
0409     struct mutex        lock;
0410     struct list_head    devices;
0411     struct idr      tid_idr;
0412     spinlock_t      txn_lock;
0413     struct slim_sched   sched;
0414     int         (*xfer_msg)(struct slim_controller *ctrl,
0415                         struct slim_msg_txn *tx);
0416     int         (*set_laddr)(struct slim_controller *ctrl,
0417                          struct slim_eaddr *ea, u8 laddr);
0418     int         (*get_laddr)(struct slim_controller *ctrl,
0419                          struct slim_eaddr *ea, u8 *laddr);
0420     int     (*enable_stream)(struct slim_stream_runtime *rt);
0421     int     (*disable_stream)(struct slim_stream_runtime *rt);
0422     int         (*wakeup)(struct slim_controller *ctrl);
0423 };
0424 
0425 int slim_device_report_present(struct slim_controller *ctrl,
0426                    struct slim_eaddr *e_addr, u8 *laddr);
0427 void slim_report_absent(struct slim_device *sbdev);
0428 int slim_register_controller(struct slim_controller *ctrl);
0429 int slim_unregister_controller(struct slim_controller *ctrl);
0430 void slim_msg_response(struct slim_controller *ctrl, u8 *reply, u8 tid, u8 l);
0431 int slim_do_transfer(struct slim_controller *ctrl, struct slim_msg_txn *txn);
0432 int slim_ctrl_clk_pause(struct slim_controller *ctrl, bool wakeup, u8 restart);
0433 int slim_alloc_txn_tid(struct slim_controller *ctrl, struct slim_msg_txn *txn);
0434 void slim_free_txn_tid(struct slim_controller *ctrl, struct slim_msg_txn *txn);
0435 
0436 static inline bool slim_tid_txn(u8 mt, u8 mc)
0437 {
0438     return (mt == SLIM_MSG_MT_CORE &&
0439         (mc == SLIM_MSG_MC_REQUEST_INFORMATION ||
0440          mc == SLIM_MSG_MC_REQUEST_CLEAR_INFORMATION ||
0441          mc == SLIM_MSG_MC_REQUEST_VALUE ||
0442          mc == SLIM_MSG_MC_REQUEST_CHANGE_VALUE));
0443 }
0444 
0445 static inline bool slim_ec_txn(u8 mt, u8 mc)
0446 {
0447     return (mt == SLIM_MSG_MT_CORE &&
0448         ((mc >= SLIM_MSG_MC_REQUEST_INFORMATION &&
0449           mc <= SLIM_MSG_MC_REPORT_INFORMATION) ||
0450          (mc >= SLIM_MSG_MC_REQUEST_VALUE &&
0451           mc <= SLIM_MSG_MC_CHANGE_VALUE)));
0452 }
0453 #endif /* _LINUX_SLIMBUS_H */