8989#define TMDMAE BIT(0) /* DMA Master Transmitted Enable */
9090
9191/* ICCCR2 */
92+ #define FMPE BIT(7) /* Fast Mode Plus Enable */
9293#define CDFD BIT(2) /* CDF Disable */
9394#define HLSE BIT(1) /* HIGH/LOW Separate Control Enable */
9495#define SME BIT(0) /* SCL Mask Enable */
122123#define ID_NACK BIT(4)
123124#define ID_EPROTO BIT(5)
124125/* persistent flags */
126+ #define ID_P_FMPLUS BIT(27)
125127#define ID_P_NOT_ATOMIC BIT(28)
126128#define ID_P_HOST_NOTIFY BIT(29)
127129#define ID_P_NO_RXDMA BIT(30) /* HW forbids RXDMA sometimes */
128130#define ID_P_PM_BLOCKED BIT(31)
129- #define ID_P_MASK GENMASK(31, 28 )
131+ #define ID_P_MASK GENMASK(31, 27 )
130132
131133enum rcar_i2c_type {
132134 I2C_RCAR_GEN1 ,
@@ -149,6 +151,7 @@ struct rcar_i2c_priv {
149151 u32 icccr ;
150152 u16 schd ;
151153 u16 scld ;
154+ u8 smd ;
152155 u8 recovery_icmcr ; /* protected by adapter lock */
153156 enum rcar_i2c_type devtype ;
154157 struct i2c_client * slave ;
@@ -240,9 +243,14 @@ static void rcar_i2c_init(struct rcar_i2c_priv *priv)
240243 if (priv -> devtype < I2C_RCAR_GEN3 ) {
241244 rcar_i2c_write (priv , ICCCR , priv -> icccr );
242245 } else {
243- rcar_i2c_write (priv , ICCCR2 , CDFD | HLSE | SME );
246+ u32 icccr2 = CDFD | HLSE | SME ;
247+
248+ if (priv -> flags & ID_P_FMPLUS )
249+ icccr2 |= FMPE ;
250+
251+ rcar_i2c_write (priv , ICCCR2 , icccr2 );
244252 rcar_i2c_write (priv , ICCCR , priv -> icccr );
245- rcar_i2c_write (priv , ICMPR , RCAR_DEFAULT_SMD );
253+ rcar_i2c_write (priv , ICMPR , priv -> smd );
246254 rcar_i2c_write (priv , ICHPR , priv -> schd );
247255 rcar_i2c_write (priv , ICLPR , priv -> scld );
248256 rcar_i2c_write (priv , ICFBSCR , TCYC17 );
@@ -279,6 +287,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv)
279287
280288 /* Fall back to previously used values if not supplied */
281289 i2c_parse_fw_timings (dev , & t , false);
290+ priv -> smd = RCAR_DEFAULT_SMD ;
282291
283292 /*
284293 * calculate SCL clock
@@ -304,6 +313,11 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv)
304313 if (cdf >= 1U << cdf_width )
305314 goto err_no_val ;
306315
316+ if (t .bus_freq_hz > I2C_MAX_FAST_MODE_FREQ && priv -> devtype >= I2C_RCAR_GEN4 )
317+ priv -> flags |= ID_P_FMPLUS ;
318+ else
319+ priv -> flags &= ~ID_P_FMPLUS ;
320+
307321 /* On Gen3+, we use cdf only for the filters, not as a SCL divider */
308322 ick = rate / (priv -> devtype < I2C_RCAR_GEN3 ? (cdf + 1 ) : 1 );
309323
@@ -345,30 +359,30 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv)
345359 * x as a base value for the SCLD/SCHD ratio:
346360 *
347361 * SCL = clkp / (8 + 2 * SMD + SCLD + SCHD + F[(ticf + tr + intd) * clkp])
348- * SCL = clkp / (8 + 2 * RCAR_DEFAULT_SMD + RCAR_SCLD_RATIO * x
362+ * SCL = clkp / (8 + 2 * SMD + RCAR_SCLD_RATIO * x
349363 * + RCAR_SCHD_RATIO * x + F[...])
350364 *
351365 * with: sum_ratio = RCAR_SCLD_RATIO + RCAR_SCHD_RATIO
352- * and: smd = RCAR_DEFAULT_SMD
353366 *
354367 * SCL = clkp / (8 + 2 * smd + sum_ratio * x + F[...])
355368 * 8 + 2 * smd + sum_ratio * x + F[...] = clkp / SCL
356369 * x = ((clkp / SCL) - 8 - 2 * smd - F[...]) / sum_ratio
357370 */
358371 x = DIV_ROUND_UP (rate , t .bus_freq_hz ?: 1 );
359- x = DIV_ROUND_UP (x - 8 - 2 * RCAR_DEFAULT_SMD - round , sum_ratio );
360- scl = rate / (8 + 2 * RCAR_DEFAULT_SMD + sum_ratio * x + round );
372+ x = DIV_ROUND_UP (x - 8 - 2 * priv -> smd - round , sum_ratio );
373+ scl = rate / (8 + 2 * priv -> smd + sum_ratio * x + round );
361374
362- /* Bail out if values don't fit into 16 bit or SMD became too large */
363- if (x * RCAR_SCLD_RATIO > 0xffff || RCAR_DEFAULT_SMD > x * RCAR_SCHD_RATIO )
375+ if (x == 0 || x * RCAR_SCLD_RATIO > 0xffff )
364376 goto err_no_val ;
365377
366378 priv -> icccr = cdf ;
367379 priv -> schd = RCAR_SCHD_RATIO * x ;
368380 priv -> scld = RCAR_SCLD_RATIO * x ;
381+ if (priv -> smd >= priv -> schd )
382+ priv -> smd = priv -> schd - 1 ;
369383
370- dev_dbg (dev , "clk %u/%u(%lu), round %u, CDF: %u SCHD %u SCLD %u\n" ,
371- scl , t .bus_freq_hz , rate , round , cdf , priv -> schd , priv -> scld );
384+ dev_dbg (dev , "clk %u/%u(%lu), round %u, CDF: %u SCHD %u SCLD %u SMD %u \n" ,
385+ scl , t .bus_freq_hz , rate , round , cdf , priv -> schd , priv -> scld , priv -> smd );
372386 }
373387
374388 return 0 ;
@@ -1073,6 +1087,8 @@ static const struct of_device_id rcar_i2c_dt_ids[] = {
10731087 { .compatible = "renesas,i2c-r8a7794" , .data = (void * )I2C_RCAR_GEN2 },
10741088 { .compatible = "renesas,i2c-r8a7795" , .data = (void * )I2C_RCAR_GEN3 },
10751089 { .compatible = "renesas,i2c-r8a7796" , .data = (void * )I2C_RCAR_GEN3 },
1090+ /* S4 has no FM+ bit */
1091+ { .compatible = "renesas,i2c-r8a779f0" , .data = (void * )I2C_RCAR_GEN3 },
10761092 { .compatible = "renesas,rcar-gen1-i2c" , .data = (void * )I2C_RCAR_GEN1 },
10771093 { .compatible = "renesas,rcar-gen2-i2c" , .data = (void * )I2C_RCAR_GEN2 },
10781094 { .compatible = "renesas,rcar-gen3-i2c" , .data = (void * )I2C_RCAR_GEN3 },
0 commit comments