@@ -321,7 +321,9 @@ LOG_MODULE_REGISTER(i3c_dw, CONFIG_I3C_DW_LOG_LEVEL);
321
321
#define I3C_BUS_I2C_FM_TLOW_MIN_NS 1300
322
322
#define I3C_BUS_I2C_FMP_TLOW_MIN_NS 500
323
323
#define I3C_BUS_THIGH_MAX_NS 41
324
+ #define I3C_BUS_TCAS_PS 38400
324
325
#define I3C_PERIOD_NS 1000000000ULL
326
+ #define I3C_PERIOD_PS I3C_PERIOD_NS * 1000ULL
325
327
326
328
#define I3C_BUS_MAX_I3C_SCL_RATE 12900000
327
329
#define I3C_BUS_TYP_I3C_SCL_RATE 12500000
@@ -1408,13 +1410,33 @@ static int i3c_dw_irq(const struct device *dev)
1408
1410
return 0 ;
1409
1411
}
1410
1412
1413
+ #ifdef CONFIG_I3C_CONTROLLER
1414
+ /**
1415
+ * @brief Return true if any i2c device only supports fast mode
1416
+ *
1417
+ * @param dev_list Pointer to device list
1418
+ *
1419
+ * @retval true if any i2c device only supports fast mode
1420
+ * @retval false if all devices support fast mode plus
1421
+ */
1422
+ static bool i3c_any_i2c_fast_mode (const struct i3c_dev_list * dev_list )
1423
+ {
1424
+ for (int i = 0 ; i < dev_list -> num_i2c ; i ++ ) {
1425
+ if (I3C_LVR_I2C_MODE (dev_list -> i2c [i ].lvr ) == I3C_LVR_I2C_FM_MODE ) {
1426
+ return true;
1427
+ }
1428
+ }
1429
+ return false;
1430
+ }
1431
+ #endif
1432
+
1411
1433
static int dw_i3c_init_scl_timing (const struct device * dev , struct i3c_config_controller * ctrl_cfg )
1412
1434
{
1413
1435
const struct dw_i3c_config * config = dev -> config ;
1414
1436
uint32_t core_rate , scl_timing ;
1415
1437
#ifdef CONFIG_I3C_CONTROLLER
1416
1438
struct dw_i3c_data * data = dev -> data ;
1417
- uint32_t hcnt , lcnt ;
1439
+ uint32_t hcnt , lcnt , fmlcnt , fmplcnt , free_cnt ;
1418
1440
#endif /* CONFIG_I3C_CONTROLLER */
1419
1441
1420
1442
if (clock_control_get_rate (config -> clock , config -> clock_subsys , & core_rate ) != 0 ) {
@@ -1441,9 +1463,6 @@ static int dw_i3c_init_scl_timing(const struct device *dev, struct i3c_config_co
1441
1463
scl_timing = SCL_I3C_TIMING_HCNT (hcnt ) | SCL_I3C_TIMING_LCNT (lcnt );
1442
1464
sys_write32 (scl_timing , config -> regs + SCL_I3C_OD_TIMING );
1443
1465
1444
- /* Set bus free timing to match tlow setting for OD clk config. */
1445
- sys_write32 (BUS_I3C_MST_FREE (lcnt ), config -> regs + BUS_FREE_TIMING );
1446
-
1447
1466
/* I3C_PP */
1448
1467
hcnt = DIV_ROUND_UP (I3C_BUS_THIGH_MAX_NS * (uint64_t )core_rate , I3C_PERIOD_NS ) - 1 ;
1449
1468
hcnt = CLAMP (hcnt , SCL_I3C_TIMING_CNT_MIN , SCL_I3C_TIMING_CNT_MAX );
@@ -1466,21 +1485,35 @@ static int dw_i3c_init_scl_timing(const struct device *dev, struct i3c_config_co
1466
1485
sys_write32 (scl_timing , config -> regs + SCL_EXT_LCNT_TIMING );
1467
1486
1468
1487
/* I2C FM+ */
1469
- lcnt = DIV_ROUND_UP (I3C_BUS_I2C_FMP_TLOW_MIN_NS * (uint64_t )core_rate , I3C_PERIOD_NS );
1470
- hcnt = DIV_ROUND_UP (core_rate , I3C_BUS_I2C_FM_PLUS_SCL_RATE ) - lcnt ;
1471
- scl_timing = SCL_I2C_FMP_TIMING_HCNT (hcnt ) | SCL_I2C_FMP_TIMING_LCNT (lcnt );
1488
+ fmplcnt = DIV_ROUND_UP (I3C_BUS_I2C_FMP_TLOW_MIN_NS * (uint64_t )core_rate , I3C_PERIOD_NS );
1489
+ hcnt = DIV_ROUND_UP (core_rate , I3C_BUS_I2C_FM_PLUS_SCL_RATE ) - fmplcnt ;
1490
+ scl_timing = SCL_I2C_FMP_TIMING_HCNT (hcnt ) | SCL_I2C_FMP_TIMING_LCNT (fmplcnt );
1472
1491
sys_write32 (scl_timing , config -> regs + SCL_I2C_FMP_TIMING );
1473
1492
1474
1493
/* I2C FM */
1475
- lcnt = DIV_ROUND_UP (I3C_BUS_I2C_FM_TLOW_MIN_NS * (uint64_t )core_rate , I3C_PERIOD_NS );
1476
- hcnt = DIV_ROUND_UP (core_rate , I3C_BUS_I2C_FM_SCL_RATE ) - lcnt ;
1477
- scl_timing = SCL_I2C_FM_TIMING_HCNT (hcnt ) | SCL_I2C_FM_TIMING_LCNT (lcnt );
1494
+ fmlcnt = DIV_ROUND_UP (I3C_BUS_I2C_FM_TLOW_MIN_NS * (uint64_t )core_rate , I3C_PERIOD_NS );
1495
+ hcnt = DIV_ROUND_UP (core_rate , I3C_BUS_I2C_FM_SCL_RATE ) - fmlcnt ;
1496
+ scl_timing = SCL_I2C_FM_TIMING_HCNT (hcnt ) | SCL_I2C_FM_TIMING_LCNT (fmlcnt );
1478
1497
sys_write32 (scl_timing , config -> regs + SCL_I2C_FM_TIMING );
1479
1498
1480
1499
if (data -> mode != I3C_BUS_MODE_PURE ) {
1481
- sys_write32 (BUS_I3C_MST_FREE (lcnt ), config -> regs + BUS_FREE_TIMING );
1500
+ /*
1501
+ * Mixed bus: Set bus free timing to match tLOW of I2C timing. If any i2c devices
1502
+ * only support fast mode, then it to the tLOW of that, otherwise set to the tLOW
1503
+ * of fast mode plus.
1504
+ */
1505
+ sys_write32 (BUS_I3C_MST_FREE (i3c_any_i2c_fast_mode (& config -> common .dev_list )
1506
+ ? fmlcnt
1507
+ : fmplcnt ),
1508
+ config -> regs + BUS_FREE_TIMING );
1482
1509
sys_write32 (sys_read32 (config -> regs + DEVICE_CTRL ) | DEV_CTRL_I2C_SLAVE_PRESENT ,
1483
1510
config -> regs + DEVICE_CTRL );
1511
+ } else {
1512
+ /* Pure bus: Set bus free timing to t_cas of 38.4ns */
1513
+ free_cnt = DIV_ROUND_UP (I3C_BUS_TCAS_PS * (uint64_t )core_rate , I3C_PERIOD_PS );
1514
+ sys_write32 (BUS_I3C_MST_FREE (free_cnt ), config -> regs + BUS_FREE_TIMING );
1515
+ sys_write32 (sys_read32 (config -> regs + DEVICE_CTRL ) & ~DEV_CTRL_I2C_SLAVE_PRESENT ,
1516
+ config -> regs + DEVICE_CTRL );
1484
1517
}
1485
1518
#endif /* CONFIG_I3C_CONTROLLER */
1486
1519
#ifdef CONFIG_I3C_TARGET
0 commit comments