Skip to content

Commit 70dbb12

Browse files
committed
Merge tag 'i2c-for-6.13-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux
Pull more i2c updates from Wolfram Sang: "Andi was super busy the last weeks, so this pull requests contains one series (nomadik) and a number of smaller additions which were ready to go but nearly overlooked. New feature support: - Added support for frequencies up to 3.4 MHz on Nomadik I2C - DesignWare now accounts for bus capacitance and clock optimisation (declared as new parameters in the binding) to improve the calculation of signal rise and fall times (t_high and t_low) New Hardware support: - DWAPB I2C controller on FUJITSU-MONAKA (new ACPI HID) - Allwinner A523 (new compatible ID) - Mobileye EyeQ6H (new compatible ID)" * tag 'i2c-for-6.13-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux: MAINTAINERS: transfer i2c-aspeed maintainership from Brendan to Ryan i2c: designware: determine HS tHIGH and tLOW based on HW parameters dt-bindings: i2c: snps,designware-i2c: declare bus capacitance and clk freq optimized i2c: nomadik: support >=1MHz speed modes i2c: nomadik: fix BRCR computation i2c: nomadik: support Mobileye EyeQ6H I2C controller i2c: nomadik: switch from of_device_is_compatible() to of_match_device() dt-bindings: i2c: nomadik: support 400kHz < clock-frequency <= 3.4MHz dt-bindings: i2c: nomadik: add mobileye,eyeq6h-i2c bindings dt-bindings: i2c: mv64xxx: Add Allwinner A523 compatible string i2c: designware: Add ACPI HID for DWAPB I2C controller on FUJITSU-MONAKA i2c: qup: use generic device property accessors
2 parents 5d38cb9 + 16470f6 commit 70dbb12

File tree

10 files changed

+115
-45
lines changed

10 files changed

+115
-45
lines changed

Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ properties:
3333
- allwinner,sun50i-a100-i2c
3434
- allwinner,sun50i-h616-i2c
3535
- allwinner,sun50i-r329-i2c
36+
- allwinner,sun55i-a523-i2c
3637
- const: allwinner,sun8i-v536-i2c
3738
- const: allwinner,sun6i-a31-i2c
3839
- const: marvell,mv64xxx-i2c

Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,22 @@ properties:
9797
- const: tx
9898
- const: rx
9999

100+
snps,bus-capacitance-pf:
101+
$ref: /schemas/types.yaml#/definitions/uint32
102+
description:
103+
This property indicates the bus capacitance in picofarads (pF).
104+
This value is used to compute the tHIGH and tLOW periods for high speed
105+
mode.
106+
enum: [100, 400]
107+
default: 100
108+
109+
snps,clk-freq-optimized:
110+
description:
111+
This property indicates whether the hardware reduce its clock frequency
112+
by reducing the internal latency required to generate the high period and
113+
low period of SCL line.
114+
type: boolean
115+
100116
unevaluatedProperties: false
101117

102118
required:
@@ -121,6 +137,8 @@ examples:
121137
i2c-sda-hold-time-ns = <300>;
122138
i2c-sda-falling-time-ns = <300>;
123139
i2c-scl-falling-time-ns = <300>;
140+
snps,bus-capacitance-pf = <400>;
141+
snps,clk-freq-optimized;
124142
};
125143
- |
126144
i2c@2000 {

Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,23 @@ select:
2222
enum:
2323
- st,nomadik-i2c
2424
- mobileye,eyeq5-i2c
25+
- mobileye,eyeq6h-i2c
2526
required:
2627
- compatible
2728

2829
properties:
2930
compatible:
3031
oneOf:
3132
- items:
32-
- const: st,nomadik-i2c
33+
- enum:
34+
- st,nomadik-i2c
35+
- mobileye,eyeq5-i2c
36+
- mobileye,eyeq6h-i2c
3337
- const: arm,primecell
3438
- items:
3539
- const: stericsson,db8500-i2c
3640
- const: st,nomadik-i2c
3741
- const: arm,primecell
38-
- items:
39-
- const: mobileye,eyeq5-i2c
40-
- const: arm,primecell
4142

4243
reg:
4344
maxItems: 1
@@ -54,7 +55,7 @@ properties:
5455
- items:
5556
- const: mclk
5657
- const: apb_pclk
57-
# Clock name in DB8500 or EyeQ5
58+
# Clock name in DB8500 or EyeQ
5859
- items:
5960
- const: i2cclk
6061
- const: apb_pclk
@@ -67,7 +68,7 @@ properties:
6768

6869
clock-frequency:
6970
minimum: 1
70-
maximum: 400000
71+
maximum: 3400000
7172

7273
mobileye,olb:
7374
$ref: /schemas/types.yaml#/definitions/phandle-array

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2213,7 +2213,7 @@ F: drivers/mmc/host/usdhi6rol0.c
22132213
F: drivers/pinctrl/pinctrl-artpec*
22142214

22152215
ARM/ASPEED I2C DRIVER
2216-
M: Brendan Higgins <brendanhiggins@google.com>
2216+
M: Ryan Chen <ryan_chen@aspeedtech.com>
22172217
R: Benjamin Herrenschmidt <[email protected]>
22182218
R: Joel Stanley <[email protected]>
22192219

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,11 @@ int i2c_dw_fw_parse_and_configure(struct dw_i2c_dev *dev)
382382

383383
i2c_parse_fw_timings(device, t, false);
384384

385+
if (device_property_read_u32(device, "snps,bus-capacitance-pf", &dev->bus_capacitance_pF))
386+
dev->bus_capacitance_pF = 100;
387+
388+
dev->clk_freq_optimized = device_property_read_bool(device, "snps,clk-freq-optimized");
389+
385390
i2c_dw_adjust_bus_speed(dev);
386391

387392
if (is_of_node(fwnode))

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,10 @@ struct reset_control;
242242
* @set_sda_hold_time: callback to retrieve IP specific SDA hold timing
243243
* @mode: operation mode - DW_IC_MASTER or DW_IC_SLAVE
244244
* @rinfo: I²C GPIO recovery information
245+
* @bus_capacitance_pF: bus capacitance in picofarads
246+
* @clk_freq_optimized: if this value is true, it means the hardware reduces
247+
* its internal clock frequency by reducing the internal latency required
248+
* to generate the high period and low period of SCL line.
245249
*
246250
* HCNT and LCNT parameters can be used if the platform knows more accurate
247251
* values than the one computed based only on the input clock frequency.
@@ -299,6 +303,8 @@ struct dw_i2c_dev {
299303
int (*set_sda_hold_time)(struct dw_i2c_dev *dev);
300304
int mode;
301305
struct i2c_bus_recovery_info rinfo;
306+
u32 bus_capacitance_pF;
307+
bool clk_freq_optimized;
302308
};
303309

304310
#define ACCESS_INTR_MASK BIT(0)

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

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,19 +151,38 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev)
151151
dev->hs_hcnt = 0;
152152
dev->hs_lcnt = 0;
153153
} else if (!dev->hs_hcnt || !dev->hs_lcnt) {
154+
u32 t_high, t_low;
155+
156+
/*
157+
* The legal values stated in the databook for bus
158+
* capacitance are only 100pF and 400pF.
159+
* If dev->bus_capacitance_pF is greater than or equals
160+
* to 400, t_high and t_low are assumed to be
161+
* appropriate values for 400pF, otherwise 100pF.
162+
*/
163+
if (dev->bus_capacitance_pF >= 400) {
164+
/* assume bus capacitance is 400pF */
165+
t_high = dev->clk_freq_optimized ? 160 : 120;
166+
t_low = 320;
167+
} else {
168+
/* assume bus capacitance is 100pF */
169+
t_high = 60;
170+
t_low = dev->clk_freq_optimized ? 120 : 160;
171+
}
172+
154173
ic_clk = i2c_dw_clk_rate(dev);
155174
dev->hs_hcnt =
156175
i2c_dw_scl_hcnt(dev,
157176
DW_IC_HS_SCL_HCNT,
158177
ic_clk,
159-
160, /* tHIGH = 160 ns */
178+
t_high,
160179
sda_falling_time,
161180
0); /* No offset */
162181
dev->hs_lcnt =
163182
i2c_dw_scl_lcnt(dev,
164183
DW_IC_HS_SCL_LCNT,
165184
ic_clk,
166-
320, /* tLOW = 320 ns */
185+
t_low,
167186
scl_falling_time,
168187
0); /* No offset */
169188
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
349349
{ "AMDI0019", ACCESS_INTR_MASK | ARBITRATION_SEMAPHORE },
350350
{ "AMDI0510", 0 },
351351
{ "APMC0D0F", 0 },
352+
{ "FUJI200B", 0 },
352353
{ "HISI02A1", 0 },
353354
{ "HISI02A2", 0 },
354355
{ "HISI02A3", 0 },

drivers/i2c/busses/i2c-nomadik.c

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
* I2C master mode controller driver, used in Nomadik 8815
77
* and Ux500 platforms.
88
*
9-
* The Mobileye EyeQ5 platform is also supported; it uses
9+
* The Mobileye EyeQ5 and EyeQ6H platforms are also supported; they use
1010
* the same Ux500/DB8500 IP block with two quirks:
1111
* - The memory bus only supports 32-bit accesses.
12-
* - A register must be configured for the I2C speed mode;
12+
* - (only EyeQ5) A register must be configured for the I2C speed mode;
1313
* it is located in a shared register region called OLB.
1414
*
1515
* Author: Srinidhi Kasagar <[email protected]>
@@ -26,6 +26,7 @@
2626
#include <linux/mfd/syscon.h>
2727
#include <linux/module.h>
2828
#include <linux/of.h>
29+
#include <linux/of_device.h>
2930
#include <linux/pinctrl/consumer.h>
3031
#include <linux/pm_runtime.h>
3132
#include <linux/regmap.h>
@@ -396,7 +397,7 @@ static u32 load_i2c_mcr_reg(struct nmk_i2c_dev *priv, u16 flags)
396397
*/
397398
static void setup_i2c_controller(struct nmk_i2c_dev *priv)
398399
{
399-
u32 brcr1, brcr2;
400+
u32 brcr;
400401
u32 i2c_clk, div;
401402
u32 ns;
402403
u16 slsu;
@@ -443,38 +444,31 @@ static void setup_i2c_controller(struct nmk_i2c_dev *priv)
443444
/*
444445
* The spec says, in case of std. mode the divider is
445446
* 2 whereas it is 3 for fast and fastplus mode of
446-
* operation. TODO - high speed support.
447+
* operation.
447448
*/
448449
div = (priv->clk_freq > I2C_MAX_STANDARD_MODE_FREQ) ? 3 : 2;
449450

450451
/*
451452
* generate the mask for baud rate counters. The controller
452453
* has two baud rate counters. One is used for High speed
453454
* operation, and the other is for std, fast mode, fast mode
454-
* plus operation. Currently we do not supprt high speed mode
455-
* so set brcr1 to 0.
455+
* plus operation.
456+
*
457+
* BRCR is a clock divider amount. Pick highest value that
458+
* leads to rate strictly below target. Eg when asking for
459+
* 400kHz you want a bus rate <=400kHz (and not >=400kHz).
456460
*/
457-
brcr1 = FIELD_PREP(I2C_BRCR_BRCNT1, 0);
458-
brcr2 = FIELD_PREP(I2C_BRCR_BRCNT2, i2c_clk / (priv->clk_freq * div));
461+
brcr = DIV_ROUND_UP(i2c_clk, priv->clk_freq * div);
462+
463+
if (priv->sm == I2C_FREQ_MODE_HIGH_SPEED)
464+
brcr = FIELD_PREP(I2C_BRCR_BRCNT1, brcr);
465+
else
466+
brcr = FIELD_PREP(I2C_BRCR_BRCNT2, brcr);
459467

460468
/* set the baud rate counter register */
461-
writel((brcr1 | brcr2), priv->virtbase + I2C_BRCR);
469+
writel(brcr, priv->virtbase + I2C_BRCR);
462470

463-
/*
464-
* set the speed mode. Currently we support
465-
* only standard and fast mode of operation
466-
* TODO - support for fast mode plus (up to 1Mb/s)
467-
* and high speed (up to 3.4 Mb/s)
468-
*/
469-
if (priv->sm > I2C_FREQ_MODE_FAST) {
470-
dev_err(&priv->adev->dev,
471-
"do not support this mode defaulting to std. mode\n");
472-
brcr2 = FIELD_PREP(I2C_BRCR_BRCNT2,
473-
i2c_clk / (I2C_MAX_STANDARD_MODE_FREQ * 2));
474-
writel((brcr1 | brcr2), priv->virtbase + I2C_BRCR);
475-
writel(FIELD_PREP(I2C_CR_SM, I2C_FREQ_MODE_STANDARD),
476-
priv->virtbase + I2C_CR);
477-
}
471+
/* set the speed mode */
478472
writel(FIELD_PREP(I2C_CR_SM, priv->sm), priv->virtbase + I2C_CR);
479473

480474
/* set the Tx and Rx FIFO threshold */
@@ -1015,11 +1009,14 @@ static void nmk_i2c_of_probe(struct device_node *np,
10151009
if (of_property_read_u32(np, "clock-frequency", &priv->clk_freq))
10161010
priv->clk_freq = I2C_MAX_STANDARD_MODE_FREQ;
10171011

1018-
/* This driver only supports 'standard' and 'fast' modes of operation. */
10191012
if (priv->clk_freq <= I2C_MAX_STANDARD_MODE_FREQ)
10201013
priv->sm = I2C_FREQ_MODE_STANDARD;
1021-
else
1014+
else if (priv->clk_freq <= I2C_MAX_FAST_MODE_FREQ)
10221015
priv->sm = I2C_FREQ_MODE_FAST;
1016+
else if (priv->clk_freq <= I2C_MAX_FAST_MODE_PLUS_FREQ)
1017+
priv->sm = I2C_FREQ_MODE_FAST_PLUS;
1018+
else
1019+
priv->sm = I2C_FREQ_MODE_HIGH_SPEED;
10231020
priv->tft = 1; /* Tx FIFO threshold */
10241021
priv->rft = 8; /* Rx FIFO threshold */
10251022

@@ -1046,8 +1043,6 @@ static int nmk_i2c_eyeq5_probe(struct nmk_i2c_dev *priv)
10461043
struct regmap *olb;
10471044
unsigned int id;
10481045

1049-
priv->has_32b_bus = true;
1050-
10511046
olb = syscon_regmap_lookup_by_phandle_args(np, "mobileye,olb", 1, &id);
10521047
if (IS_ERR(olb))
10531048
return PTR_ERR(olb);
@@ -1068,26 +1063,50 @@ static int nmk_i2c_eyeq5_probe(struct nmk_i2c_dev *priv)
10681063
return 0;
10691064
}
10701065

1066+
#define NMK_I2C_EYEQ_FLAG_32B_BUS BIT(0)
1067+
#define NMK_I2C_EYEQ_FLAG_IS_EYEQ5 BIT(1)
1068+
1069+
static const struct of_device_id nmk_i2c_eyeq_match_table[] = {
1070+
{
1071+
.compatible = "mobileye,eyeq5-i2c",
1072+
.data = (void *)(NMK_I2C_EYEQ_FLAG_32B_BUS | NMK_I2C_EYEQ_FLAG_IS_EYEQ5),
1073+
},
1074+
{
1075+
.compatible = "mobileye,eyeq6h-i2c",
1076+
.data = (void *)NMK_I2C_EYEQ_FLAG_32B_BUS,
1077+
},
1078+
};
1079+
10711080
static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
10721081
{
1073-
int ret = 0;
1074-
struct nmk_i2c_dev *priv;
1082+
struct i2c_vendor_data *vendor = id->data;
1083+
u32 max_fifo_threshold = (vendor->fifodepth / 2) - 1;
10751084
struct device_node *np = adev->dev.of_node;
1085+
const struct of_device_id *match;
10761086
struct device *dev = &adev->dev;
1087+
unsigned long match_flags = 0;
1088+
struct nmk_i2c_dev *priv;
10771089
struct i2c_adapter *adap;
1078-
struct i2c_vendor_data *vendor = id->data;
1079-
u32 max_fifo_threshold = (vendor->fifodepth / 2) - 1;
1090+
int ret = 0;
1091+
1092+
/*
1093+
* We do not want to attach a .of_match_table to our amba driver.
1094+
* Do not convert to device_get_match_data().
1095+
*/
1096+
match = of_match_device(nmk_i2c_eyeq_match_table, dev);
1097+
if (match)
1098+
match_flags = (unsigned long)match->data;
10801099

10811100
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
10821101
if (!priv)
10831102
return -ENOMEM;
10841103

10851104
priv->vendor = vendor;
10861105
priv->adev = adev;
1087-
priv->has_32b_bus = false;
1106+
priv->has_32b_bus = match_flags & NMK_I2C_EYEQ_FLAG_32B_BUS;
10881107
nmk_i2c_of_probe(np, priv);
10891108

1090-
if (of_device_is_compatible(np, "mobileye,eyeq5-i2c")) {
1109+
if (match_flags & NMK_I2C_EYEQ_FLAG_IS_EYEQ5) {
10911110
ret = nmk_i2c_eyeq5_probe(priv);
10921111
if (ret)
10931112
return dev_err_probe(dev, ret, "failed OLB lookup\n");

drivers/i2c/busses/i2c-qup.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@
1717
#include <linux/interrupt.h>
1818
#include <linux/io.h>
1919
#include <linux/module.h>
20-
#include <linux/of.h>
2120
#include <linux/platform_device.h>
2221
#include <linux/pm_runtime.h>
22+
#include <linux/property.h>
2323
#include <linux/scatterlist.h>
2424

2525
/* QUP Registers */
@@ -1683,7 +1683,7 @@ static int qup_i2c_probe(struct platform_device *pdev)
16831683
}
16841684
}
16851685

1686-
if (of_device_is_compatible(pdev->dev.of_node, "qcom,i2c-qup-v1.1.1")) {
1686+
if (device_is_compatible(&pdev->dev, "qcom,i2c-qup-v1.1.1")) {
16871687
qup->adap.algo = &qup_i2c_algo;
16881688
qup->adap.quirks = &qup_i2c_quirks;
16891689
is_qup_v1 = true;

0 commit comments

Comments
 (0)