Skip to content

Commit 1f1a714

Browse files
fancerWolfram Sang
authored andcommitted
i2c: designware: Detect the FIFO size in the common code
The problem with detecting the FIFO depth in the platform driver is that in order to implement this we have to access the controller IC_COMP_PARAM_1 register. Currently it's done before the i2c_dw_set_reg_access() method execution, which is errors prone since the method determines the registers endianness and access mode and we can't use dw_readl/dw_writel accessors before this information is retrieved. We also can't move the i2c_dw_set_reg_access() function invocation to after the master/slave probe functions call (when endianness and access mode are determined), since the FIFO depth information is used by them for initializations. So in order to fix the problem we have no choice but to move the FIFO size detection methods to the common code and call it at the probe stage. Signed-off-by: Serge Semin <[email protected]> Signed-off-by: Alexey Malahov <[email protected]> Reviewed-by: Andy Shevchenko <[email protected]> Acked-by: Jarkko Nikula <[email protected]> Signed-off-by: Wolfram Sang <[email protected]>
1 parent 1413ef6 commit 1f1a714

File tree

5 files changed

+27
-24
lines changed

5 files changed

+27
-24
lines changed

drivers/i2c/busses/i2c-designware-common.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,28 @@ int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev)
344344
return -EIO;
345345
}
346346

347+
void i2c_dw_set_fifo_size(struct dw_i2c_dev *dev)
348+
{
349+
u32 param, tx_fifo_depth, rx_fifo_depth;
350+
351+
/*
352+
* Try to detect the FIFO depth if not set by interface driver,
353+
* the depth could be from 2 to 256 from HW spec.
354+
*/
355+
param = dw_readl(dev, DW_IC_COMP_PARAM_1);
356+
tx_fifo_depth = ((param >> 16) & 0xff) + 1;
357+
rx_fifo_depth = ((param >> 8) & 0xff) + 1;
358+
if (!dev->tx_fifo_depth) {
359+
dev->tx_fifo_depth = tx_fifo_depth;
360+
dev->rx_fifo_depth = rx_fifo_depth;
361+
} else if (tx_fifo_depth >= 2) {
362+
dev->tx_fifo_depth = min_t(u32, dev->tx_fifo_depth,
363+
tx_fifo_depth);
364+
dev->rx_fifo_depth = min_t(u32, dev->rx_fifo_depth,
365+
rx_fifo_depth);
366+
}
367+
}
368+
347369
u32 i2c_dw_func(struct i2c_adapter *adap)
348370
{
349371
struct dw_i2c_dev *dev = i2c_get_adapdata(adap);

drivers/i2c/busses/i2c-designware-core.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ int i2c_dw_acquire_lock(struct dw_i2c_dev *dev);
297297
void i2c_dw_release_lock(struct dw_i2c_dev *dev);
298298
int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev);
299299
int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev);
300+
void i2c_dw_set_fifo_size(struct dw_i2c_dev *dev);
300301
u32 i2c_dw_func(struct i2c_adapter *adap);
301302
void i2c_dw_disable(struct dw_i2c_dev *dev);
302303
void i2c_dw_disable_int(struct dw_i2c_dev *dev);

drivers/i2c/busses/i2c-designware-master.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,8 @@ int i2c_dw_probe(struct dw_i2c_dev *dev)
698698
if (ret)
699699
return ret;
700700

701+
i2c_dw_set_fifo_size(dev);
702+
701703
ret = dev->init(dev);
702704
if (ret)
703705
return ret;

drivers/i2c/busses/i2c-designware-platdrv.c

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -219,28 +219,6 @@ static void i2c_dw_configure_slave(struct dw_i2c_dev *dev)
219219
dev->mode = DW_IC_SLAVE;
220220
}
221221

222-
static void dw_i2c_set_fifo_size(struct dw_i2c_dev *dev)
223-
{
224-
u32 param, tx_fifo_depth, rx_fifo_depth;
225-
226-
/*
227-
* Try to detect the FIFO depth if not set by interface driver,
228-
* the depth could be from 2 to 256 from HW spec.
229-
*/
230-
param = i2c_dw_read_comp_param(dev);
231-
tx_fifo_depth = ((param >> 16) & 0xff) + 1;
232-
rx_fifo_depth = ((param >> 8) & 0xff) + 1;
233-
if (!dev->tx_fifo_depth) {
234-
dev->tx_fifo_depth = tx_fifo_depth;
235-
dev->rx_fifo_depth = rx_fifo_depth;
236-
} else if (tx_fifo_depth >= 2) {
237-
dev->tx_fifo_depth = min_t(u32, dev->tx_fifo_depth,
238-
tx_fifo_depth);
239-
dev->rx_fifo_depth = min_t(u32, dev->rx_fifo_depth,
240-
rx_fifo_depth);
241-
}
242-
}
243-
244222
static void dw_i2c_plat_pm_cleanup(struct dw_i2c_dev *dev)
245223
{
246224
pm_runtime_disable(dev->dev);
@@ -362,8 +340,6 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
362340
div_u64(clk_khz * t->sda_hold_ns + 500000, 1000000);
363341
}
364342

365-
dw_i2c_set_fifo_size(dev);
366-
367343
adap = &dev->adapter;
368344
adap->owner = THIS_MODULE;
369345
adap->class = I2C_CLASS_DEPRECATED;

drivers/i2c/busses/i2c-designware-slave.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ int i2c_dw_probe_slave(struct dw_i2c_dev *dev)
260260
if (ret)
261261
return ret;
262262

263+
i2c_dw_set_fifo_size(dev);
264+
263265
ret = dev->init(dev);
264266
if (ret)
265267
return ret;

0 commit comments

Comments
 (0)