Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i2c: designware-pci: set ideal HCNT, LCNT and SDA hold time value

On Intel BayTrail, there was case whereby the resulting fast mode
bus speed becomes slower (~20% slower compared to expected speed)
if using the HCNT/LCNT calculated in the core layer. Thus, this
patch is added to allow pci glue layer to pass in optimal
HCNT/LCNT/SDA hold time values to core layer since the core
layer supports cofigurable HCNT/LCNT/SDA hold time values now.

Signed-off-by: Chew, Chiau Ee <chiau.ee.chew@intel.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>

authored by

Chew, Chiau Ee and committed by
Wolfram Sang
8efd1e9e 4fda9962

+28
+28
drivers/i2c/busses/i2c-designware-pcidrv.c
··· 58 58 baytrail, 59 59 }; 60 60 61 + struct dw_scl_sda_cfg { 62 + u32 ss_hcnt; 63 + u32 fs_hcnt; 64 + u32 ss_lcnt; 65 + u32 fs_lcnt; 66 + u32 sda_hold; 67 + }; 68 + 61 69 struct dw_pci_controller { 62 70 u32 bus_num; 63 71 u32 bus_cfg; ··· 73 65 u32 rx_fifo_depth; 74 66 u32 clk_khz; 75 67 u32 functionality; 68 + struct dw_scl_sda_cfg *scl_sda_cfg; 76 69 }; 77 70 78 71 #define INTEL_MID_STD_CFG (DW_IC_CON_MASTER | \ ··· 85 76 I2C_FUNC_SMBUS_BYTE_DATA | \ 86 77 I2C_FUNC_SMBUS_WORD_DATA | \ 87 78 I2C_FUNC_SMBUS_I2C_BLOCK) 79 + 80 + /* BayTrail HCNT/LCNT/SDA hold time */ 81 + static struct dw_scl_sda_cfg byt_config = { 82 + .ss_hcnt = 0x200, 83 + .fs_hcnt = 0x55, 84 + .ss_lcnt = 0x200, 85 + .fs_lcnt = 0x99, 86 + .sda_hold = 0x6, 87 + }; 88 88 89 89 static struct dw_pci_controller dw_pci_controllers[] = { 90 90 [moorestown_0] = { ··· 166 148 .rx_fifo_depth = 32, 167 149 .clk_khz = 100000, 168 150 .functionality = I2C_FUNC_10BIT_ADDR, 151 + .scl_sda_cfg = &byt_config, 169 152 }, 170 153 }; 171 154 static struct i2c_algorithm i2c_dw_algo = { ··· 206 187 struct i2c_adapter *adap; 207 188 int r; 208 189 struct dw_pci_controller *controller; 190 + struct dw_scl_sda_cfg *cfg; 209 191 210 192 if (id->driver_data >= ARRAY_SIZE(dw_pci_controllers)) { 211 193 dev_err(&pdev->dev, "%s: invalid driver data %ld\n", __func__, ··· 244 224 DW_DEFAULT_FUNCTIONALITY; 245 225 246 226 dev->master_cfg = controller->bus_cfg; 227 + if (controller->scl_sda_cfg) { 228 + cfg = controller->scl_sda_cfg; 229 + dev->ss_hcnt = cfg->ss_hcnt; 230 + dev->fs_hcnt = cfg->fs_hcnt; 231 + dev->ss_lcnt = cfg->ss_lcnt; 232 + dev->fs_lcnt = cfg->fs_lcnt; 233 + dev->sda_hold_time = cfg->sda_hold; 234 + } 247 235 248 236 pci_set_drvdata(pdev, dev); 249 237