"Das U-Boot" Source Tree
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

i3c: master: dw-i3c-master: Fix OD_TIMING for spike filter

Fix the I3C device with spike filter unable to detect issue by setting
tHIGH_INIT to 200ns for first broadcast address.
This is according to MIPI SPEC 1.1.1 for first broadcast address
which is already part of linux upstreamed patch.

Signed-off-by: Dinesh Maniyam <dinesh.maniyam@altera.com>

authored by

Dinesh Maniyam and committed by
Heiko Schocher
82cc368c b5cf7cd1

+25
+23
drivers/i3c/master/dw-i3c-master.c
··· 334 334 if (hcnt < SCL_I3C_TIMING_CNT_MIN) 335 335 hcnt = SCL_I3C_TIMING_CNT_MIN; 336 336 337 + /* set back to THIGH_MAX_NS, after disable spike filter */ 338 + if (!master->first_broadcast) { 339 + lcnt = SCL_I3C_TIMING_LCNT(readl(master->regs + SCL_I3C_OD_TIMING)); 340 + scl_timing = SCL_I3C_TIMING_HCNT(hcnt) | lcnt; 341 + writel(scl_timing, master->regs + SCL_I3C_OD_TIMING); 342 + return 0; 343 + } 344 + 337 345 lcnt = DIV_ROUND_UP(core_rate, master->base.bus.scl_rate.i3c) - hcnt; 338 346 if (lcnt < SCL_I3C_TIMING_CNT_MIN) 339 347 lcnt = SCL_I3C_TIMING_CNT_MIN; ··· 350 358 351 359 lcnt = max_t(u8, 352 360 DIV_ROUND_UP(I3C_BUS_TLOW_OD_MIN_NS, core_period), lcnt); 361 + 362 + /* first broadcast thigh to 200ns, to disable spike filter */ 363 + hcnt = DIV_ROUND_UP(I3C_BUS_THIGH_INIT_OD_MIN_NS, core_period); 353 364 354 365 scl_timing = SCL_I3C_TIMING_HCNT(hcnt) | SCL_I3C_TIMING_LCNT(lcnt); 355 366 writel(scl_timing, master->regs + SCL_I3C_OD_TIMING); ··· 406 417 u32 thld_ctrl; 407 418 int ret; 408 419 420 + /* first broadcast to disable spike filter */ 421 + master->first_broadcast = true; 422 + 409 423 switch (bus->mode) { 410 424 case I3C_BUS_MODE_MIXED_FAST: 411 425 case I3C_BUS_MODE_MIXED_LIMITED: ··· 484 498 485 499 if (status & INTR_TRANSFER_ERR_STAT) 486 500 writel(INTR_TRANSFER_ERR_STAT, master->regs + INTR_STATUS); 501 + 502 + /* set back to THIGH_MAX_NS, after disable spike filter */ 503 + if (master->first_broadcast) { 504 + master->first_broadcast = false; 505 + int ret = dw_i3c_clk_cfg(master); 506 + 507 + if (ret) 508 + pr_err("Failed to set clk cfg\n"); 509 + } 487 510 488 511 spin_unlock(&master->xferqueue.lock); 489 512 }
+1
include/dw-i3c.h
··· 240 240 char version[5]; 241 241 char type[5]; 242 242 u8 addrs[MAX_DEVS]; 243 + bool first_broadcast; 243 244 }; 244 245 245 246 struct dw_i3c_i2c_dev_data {
+1
include/linux/i3c/master.h
··· 278 278 #define I3C_BUS_I2C_FM_PLUS_SCL_RATE 1000000 279 279 #define I3C_BUS_I2C_FM_SCL_RATE 400000 280 280 #define I3C_BUS_TLOW_OD_MIN_NS 200 281 + #define I3C_BUS_THIGH_INIT_OD_MIN_NS 200 281 282 282 283 /** 283 284 * enum i3c_bus_mode - I3C bus mode