7676
7777#define RX_TX_DATA_PORT 0x14
7878#define IBI_QUEUE_STATUS 0x18
79+ #define IBI_QUEUE_STATUS_IBI_ID (x ) (((x) & GENMASK(15, 8)) >> 8)
80+ #define IBI_QUEUE_STATUS_DATA_LEN (x ) ((x) & GENMASK(7, 0))
81+ #define IBI_QUEUE_IBI_ADDR (x ) (IBI_QUEUE_STATUS_IBI_ID(x) >> 1)
82+ #define IBI_QUEUE_IBI_RNW (x ) (IBI_QUEUE_STATUS_IBI_ID(x) & BIT(0))
83+ #define IBI_TYPE_MR (x ) \
84+ ((IBI_QUEUE_IBI_ADDR(x) != I3C_HOT_JOIN_ADDR) && !IBI_QUEUE_IBI_RNW(x))
85+ #define IBI_TYPE_HJ (x ) \
86+ ((IBI_QUEUE_IBI_ADDR(x) == I3C_HOT_JOIN_ADDR) && !IBI_QUEUE_IBI_RNW(x))
87+ #define IBI_TYPE_SIRQ (x ) \
88+ ((IBI_QUEUE_IBI_ADDR(x) != I3C_HOT_JOIN_ADDR) && IBI_QUEUE_IBI_RNW(x))
89+
7990#define QUEUE_THLD_CTRL 0x1c
91+ #define QUEUE_THLD_CTRL_IBI_STAT_MASK GENMASK(31, 24)
92+ #define QUEUE_THLD_CTRL_IBI_STAT (x ) (((x) - 1) << 24)
93+ #define QUEUE_THLD_CTRL_IBI_DATA_MASK GENMASK(20, 16)
94+ #define QUEUE_THLD_CTRL_IBI_DATA (x ) ((x) << 16)
8095#define QUEUE_THLD_CTRL_RESP_BUF_MASK GENMASK(15, 8)
8196#define QUEUE_THLD_CTRL_RESP_BUF (x ) (((x) - 1) << 8)
8297
186201#define EXTENDED_CAPABILITY 0xe8
187202#define SLAVE_CONFIG 0xec
188203
204+ #define DEV_ADDR_TABLE_IBI_MDB BIT(12)
205+ #define DEV_ADDR_TABLE_SIR_REJECT BIT(13)
189206#define DEV_ADDR_TABLE_LEGACY_I2C_DEV BIT(31)
190207#define DEV_ADDR_TABLE_DYNAMIC_ADDR (x ) (((x) << 16) & GENMASK(23, 16))
191208#define DEV_ADDR_TABLE_STATIC_ADDR (x ) ((x) & GENMASK(6, 0))
@@ -221,6 +238,7 @@ struct dw_i3c_xfer {
221238
222239struct dw_i3c_i2c_dev_data {
223240 u8 index ;
241+ struct i3c_generic_ibi_pool * ibi_pool ;
224242};
225243
226244static u8 even_parity (u8 p )
@@ -336,6 +354,12 @@ static void dw_i3c_master_read_rx_fifo(struct dw_i3c_master *master,
336354 return dw_i3c_master_read_fifo (master , RX_TX_DATA_PORT , bytes , nbytes );
337355}
338356
357+ static void dw_i3c_master_read_ibi_fifo (struct dw_i3c_master * master ,
358+ u8 * bytes , int nbytes )
359+ {
360+ return dw_i3c_master_read_fifo (master , IBI_QUEUE_STATUS , bytes , nbytes );
361+ }
362+
339363static struct dw_i3c_xfer *
340364dw_i3c_master_alloc_xfer (struct dw_i3c_master * master , unsigned int ncmds )
341365{
@@ -605,7 +629,11 @@ static int dw_i3c_master_bus_init(struct i3c_master_controller *m)
605629 }
606630
607631 thld_ctrl = readl (master -> regs + QUEUE_THLD_CTRL );
608- thld_ctrl &= ~QUEUE_THLD_CTRL_RESP_BUF_MASK ;
632+ thld_ctrl &= ~(QUEUE_THLD_CTRL_RESP_BUF_MASK |
633+ QUEUE_THLD_CTRL_IBI_STAT_MASK |
634+ QUEUE_THLD_CTRL_IBI_STAT_MASK );
635+ thld_ctrl |= QUEUE_THLD_CTRL_IBI_STAT (1 ) |
636+ QUEUE_THLD_CTRL_IBI_DATA (31 );
609637 writel (thld_ctrl , master -> regs + QUEUE_THLD_CTRL );
610638
611639 thld_ctrl = readl (master -> regs + DATA_BUFFER_THLD_CTRL );
@@ -1074,6 +1102,226 @@ static void dw_i3c_master_detach_i2c_dev(struct i2c_dev_desc *dev)
10741102 kfree (data );
10751103}
10761104
1105+ static int dw_i3c_master_request_ibi (struct i3c_dev_desc * dev ,
1106+ const struct i3c_ibi_setup * req )
1107+ {
1108+ struct dw_i3c_i2c_dev_data * data = i3c_dev_get_master_data (dev );
1109+ struct i3c_master_controller * m = i3c_dev_get_master (dev );
1110+ struct dw_i3c_master * master = to_dw_i3c_master (m );
1111+ unsigned long flags ;
1112+
1113+ data -> ibi_pool = i3c_generic_ibi_alloc_pool (dev , req );
1114+ if (IS_ERR (data -> ibi_pool ))
1115+ return PTR_ERR (data -> ibi_pool );
1116+
1117+ spin_lock_irqsave (& master -> devs_lock , flags );
1118+ master -> devs [data -> index ].ibi_dev = dev ;
1119+ spin_unlock_irqrestore (& master -> devs_lock , flags );
1120+
1121+ return 0 ;
1122+ }
1123+
1124+ static void dw_i3c_master_free_ibi (struct i3c_dev_desc * dev )
1125+ {
1126+ struct dw_i3c_i2c_dev_data * data = i3c_dev_get_master_data (dev );
1127+ struct i3c_master_controller * m = i3c_dev_get_master (dev );
1128+ struct dw_i3c_master * master = to_dw_i3c_master (m );
1129+ unsigned long flags ;
1130+
1131+ spin_lock_irqsave (& master -> devs_lock , flags );
1132+ master -> devs [data -> index ].ibi_dev = NULL ;
1133+ spin_unlock_irqrestore (& master -> devs_lock , flags );
1134+
1135+ i3c_generic_ibi_free_pool (data -> ibi_pool );
1136+ data -> ibi_pool = NULL ;
1137+ }
1138+
1139+ static void dw_i3c_master_set_sir_enabled (struct dw_i3c_master * master ,
1140+ struct i3c_dev_desc * dev ,
1141+ u8 idx , bool enable )
1142+ {
1143+ unsigned long flags ;
1144+ u32 dat_entry , reg ;
1145+ bool global ;
1146+
1147+ dat_entry = DEV_ADDR_TABLE_LOC (master -> datstartaddr , idx );
1148+
1149+ spin_lock_irqsave (& master -> devs_lock , flags );
1150+ reg = readl (master -> regs + dat_entry );
1151+ if (enable ) {
1152+ reg &= ~DEV_ADDR_TABLE_SIR_REJECT ;
1153+ if (dev -> info .bcr & I3C_BCR_IBI_PAYLOAD )
1154+ reg |= DEV_ADDR_TABLE_IBI_MDB ;
1155+ } else {
1156+ reg |= DEV_ADDR_TABLE_SIR_REJECT ;
1157+ }
1158+ writel (reg , master -> regs + dat_entry );
1159+
1160+ reg = readl (master -> regs + IBI_SIR_REQ_REJECT );
1161+ if (enable ) {
1162+ global = reg == 0xffffffff ;
1163+ reg &= ~BIT (idx );
1164+ } else {
1165+ global = reg == 0 ;
1166+ reg |= BIT (idx );
1167+ }
1168+ writel (reg , master -> regs + IBI_SIR_REQ_REJECT );
1169+
1170+ if (global ) {
1171+ reg = readl (master -> regs + INTR_STATUS_EN );
1172+ reg &= ~INTR_IBI_THLD_STAT ;
1173+ if (enable )
1174+ reg |= INTR_IBI_THLD_STAT ;
1175+ writel (reg , master -> regs + INTR_STATUS_EN );
1176+
1177+ reg = readl (master -> regs + INTR_SIGNAL_EN );
1178+ reg &= ~INTR_IBI_THLD_STAT ;
1179+ if (enable )
1180+ reg |= INTR_IBI_THLD_STAT ;
1181+ writel (reg , master -> regs + INTR_SIGNAL_EN );
1182+ }
1183+
1184+ spin_unlock_irqrestore (& master -> devs_lock , flags );
1185+ }
1186+
1187+ static int dw_i3c_master_enable_ibi (struct i3c_dev_desc * dev )
1188+ {
1189+ struct dw_i3c_i2c_dev_data * data = i3c_dev_get_master_data (dev );
1190+ struct i3c_master_controller * m = i3c_dev_get_master (dev );
1191+ struct dw_i3c_master * master = to_dw_i3c_master (m );
1192+ int rc ;
1193+
1194+ dw_i3c_master_set_sir_enabled (master , dev , data -> index , true);
1195+
1196+ rc = i3c_master_enec_locked (m , dev -> info .dyn_addr , I3C_CCC_EVENT_SIR );
1197+
1198+ if (rc )
1199+ dw_i3c_master_set_sir_enabled (master , dev , data -> index , false);
1200+
1201+ return rc ;
1202+ }
1203+
1204+ static int dw_i3c_master_disable_ibi (struct i3c_dev_desc * dev )
1205+ {
1206+ struct dw_i3c_i2c_dev_data * data = i3c_dev_get_master_data (dev );
1207+ struct i3c_master_controller * m = i3c_dev_get_master (dev );
1208+ struct dw_i3c_master * master = to_dw_i3c_master (m );
1209+ int rc ;
1210+
1211+ rc = i3c_master_disec_locked (m , dev -> info .dyn_addr , I3C_CCC_EVENT_SIR );
1212+ if (rc )
1213+ return rc ;
1214+
1215+ dw_i3c_master_set_sir_enabled (master , dev , data -> index , false);
1216+
1217+ return 0 ;
1218+ }
1219+
1220+ static void dw_i3c_master_recycle_ibi_slot (struct i3c_dev_desc * dev ,
1221+ struct i3c_ibi_slot * slot )
1222+ {
1223+ struct dw_i3c_i2c_dev_data * data = i3c_dev_get_master_data (dev );
1224+
1225+ i3c_generic_ibi_recycle_slot (data -> ibi_pool , slot );
1226+ }
1227+
1228+ static void dw_i3c_master_drain_ibi_queue (struct dw_i3c_master * master ,
1229+ int len )
1230+ {
1231+ int i ;
1232+
1233+ for (i = 0 ; i < DIV_ROUND_UP (len , 4 ); i ++ )
1234+ readl (master -> regs + IBI_QUEUE_STATUS );
1235+ }
1236+
1237+ static void dw_i3c_master_handle_ibi_sir (struct dw_i3c_master * master ,
1238+ u32 status )
1239+ {
1240+ struct dw_i3c_i2c_dev_data * data ;
1241+ struct i3c_ibi_slot * slot ;
1242+ struct i3c_dev_desc * dev ;
1243+ unsigned long flags ;
1244+ u8 addr , len ;
1245+ int idx ;
1246+
1247+ addr = IBI_QUEUE_IBI_ADDR (status );
1248+ len = IBI_QUEUE_STATUS_DATA_LEN (status );
1249+
1250+ spin_lock_irqsave (& master -> devs_lock , flags );
1251+ idx = dw_i3c_master_get_addr_pos (master , addr );
1252+ if (idx < 0 ) {
1253+ dev_dbg_ratelimited (& master -> base .dev ,
1254+ "IBI from unknown addr 0x%x\n" , addr );
1255+ goto err_drain ;
1256+ }
1257+
1258+ dev = master -> devs [idx ].ibi_dev ;
1259+ if (!dev || !dev -> ibi ) {
1260+ dev_dbg_ratelimited (& master -> base .dev ,
1261+ "IBI from non-requested dev idx %d\n" , idx );
1262+ goto err_drain ;
1263+ }
1264+
1265+ data = i3c_dev_get_master_data (dev );
1266+ slot = i3c_generic_ibi_get_free_slot (data -> ibi_pool );
1267+ if (!slot ) {
1268+ dev_dbg_ratelimited (& master -> base .dev ,
1269+ "No IBI slots available\n" );
1270+ goto err_drain ;
1271+ }
1272+
1273+ if (dev -> ibi -> max_payload_len < len ) {
1274+ dev_dbg_ratelimited (& master -> base .dev ,
1275+ "IBI payload len %d greater than max %d\n" ,
1276+ len , dev -> ibi -> max_payload_len );
1277+ goto err_drain ;
1278+ }
1279+
1280+ if (len ) {
1281+ dw_i3c_master_read_ibi_fifo (master , slot -> data , len );
1282+ slot -> len = len ;
1283+ }
1284+ i3c_master_queue_ibi (dev , slot );
1285+
1286+ spin_unlock_irqrestore (& master -> devs_lock , flags );
1287+
1288+ return ;
1289+
1290+ err_drain :
1291+ dw_i3c_master_drain_ibi_queue (master , len );
1292+
1293+ spin_unlock_irqrestore (& master -> devs_lock , flags );
1294+ }
1295+
1296+ /* "ibis": referring to In-Band Interrupts, and not
1297+ * https://en.wikipedia.org/wiki/Australian_white_ibis. The latter should
1298+ * not be handled.
1299+ */
1300+ static void dw_i3c_master_irq_handle_ibis (struct dw_i3c_master * master )
1301+ {
1302+ unsigned int i , len , n_ibis ;
1303+ u32 reg ;
1304+
1305+ reg = readl (master -> regs + QUEUE_STATUS_LEVEL );
1306+ n_ibis = QUEUE_STATUS_IBI_STATUS_CNT (reg );
1307+ if (!n_ibis )
1308+ return ;
1309+
1310+ for (i = 0 ; i < n_ibis ; i ++ ) {
1311+ reg = readl (master -> regs + IBI_QUEUE_STATUS );
1312+
1313+ if (IBI_TYPE_SIRQ (reg )) {
1314+ dw_i3c_master_handle_ibi_sir (master , reg );
1315+ } else {
1316+ len = IBI_QUEUE_STATUS_DATA_LEN (reg );
1317+ dev_info (& master -> base .dev ,
1318+ "unsupported IBI type 0x%lx len %d\n" ,
1319+ IBI_QUEUE_STATUS_IBI_ID (reg ), len );
1320+ dw_i3c_master_drain_ibi_queue (master , len );
1321+ }
1322+ }
1323+ }
1324+
10771325static irqreturn_t dw_i3c_master_irq_handler (int irq , void * dev_id )
10781326{
10791327 struct dw_i3c_master * master = dev_id ;
@@ -1092,6 +1340,9 @@ static irqreturn_t dw_i3c_master_irq_handler(int irq, void *dev_id)
10921340 writel (INTR_TRANSFER_ERR_STAT , master -> regs + INTR_STATUS );
10931341 spin_unlock (& master -> xferqueue .lock );
10941342
1343+ if (status & INTR_IBI_THLD_STAT )
1344+ dw_i3c_master_irq_handle_ibis (master );
1345+
10951346 return IRQ_HANDLED ;
10961347}
10971348
@@ -1110,6 +1361,26 @@ static const struct i3c_master_controller_ops dw_mipi_i3c_ops = {
11101361 .i2c_xfers = dw_i3c_master_i2c_xfers ,
11111362};
11121363
1364+ static const struct i3c_master_controller_ops dw_mipi_i3c_ibi_ops = {
1365+ .bus_init = dw_i3c_master_bus_init ,
1366+ .bus_cleanup = dw_i3c_master_bus_cleanup ,
1367+ .attach_i3c_dev = dw_i3c_master_attach_i3c_dev ,
1368+ .reattach_i3c_dev = dw_i3c_master_reattach_i3c_dev ,
1369+ .detach_i3c_dev = dw_i3c_master_detach_i3c_dev ,
1370+ .do_daa = dw_i3c_master_daa ,
1371+ .supports_ccc_cmd = dw_i3c_master_supports_ccc_cmd ,
1372+ .send_ccc_cmd = dw_i3c_master_send_ccc_cmd ,
1373+ .priv_xfers = dw_i3c_master_priv_xfers ,
1374+ .attach_i2c_dev = dw_i3c_master_attach_i2c_dev ,
1375+ .detach_i2c_dev = dw_i3c_master_detach_i2c_dev ,
1376+ .i2c_xfers = dw_i3c_master_i2c_xfers ,
1377+ .request_ibi = dw_i3c_master_request_ibi ,
1378+ .free_ibi = dw_i3c_master_free_ibi ,
1379+ .enable_ibi = dw_i3c_master_enable_ibi ,
1380+ .disable_ibi = dw_i3c_master_disable_ibi ,
1381+ .recycle_ibi_slot = dw_i3c_master_recycle_ibi_slot ,
1382+ };
1383+
11131384/* default platform ops implementations */
11141385static int dw_i3c_platform_init_nop (struct dw_i3c_master * i3c )
11151386{
@@ -1123,6 +1394,7 @@ static const struct dw_i3c_platform_ops dw_i3c_platform_ops_default = {
11231394int dw_i3c_common_probe (struct dw_i3c_master * master ,
11241395 struct platform_device * pdev )
11251396{
1397+ const struct i3c_master_controller_ops * ops ;
11261398 int ret , irq ;
11271399
11281400 if (!master -> platform_ops )
@@ -1172,8 +1444,11 @@ int dw_i3c_common_probe(struct dw_i3c_master *master,
11721444 master -> maxdevs = ret >> 16 ;
11731445 master -> free_pos = GENMASK (master -> maxdevs - 1 , 0 );
11741446
1175- ret = i3c_master_register (& master -> base , & pdev -> dev ,
1176- & dw_mipi_i3c_ops , false);
1447+ ops = & dw_mipi_i3c_ops ;
1448+ if (master -> ibi_capable )
1449+ ops = & dw_mipi_i3c_ibi_ops ;
1450+
1451+ ret = i3c_master_register (& master -> base , & pdev -> dev , ops , false);
11771452 if (ret )
11781453 goto err_assert_rst ;
11791454
0 commit comments