@@ -63,6 +63,8 @@
#define ICMR3_ACKWP 0x10
#define ICMR3_ACKBT 0x08
+#define ICFER_FMPE 0x80
+
#define ICIER_TIE 0x80
#define ICIER_TEIE 0x40
#define ICIER_RIE 0x20
@@ -80,6 +82,7 @@ enum riic_reg_list {
RIIC_ICCR2,
RIIC_ICMR1,
RIIC_ICMR3,
+ RIIC_ICFER,
RIIC_ICSER,
RIIC_ICIER,
RIIC_ICSR2,
@@ -92,6 +95,7 @@ enum riic_reg_list {
struct riic_of_data {
const u8 *regs;
+ bool fast_mode_plus;
};
struct riic_dev {
@@ -107,6 +111,7 @@ struct riic_dev {
struct clk *clk;
struct reset_control *rstc;
struct i2c_timings i2c_t;
+ bool fast_mode_plus;
};
struct riic_irq_desc {
@@ -316,10 +321,11 @@ static int riic_init_hw(struct riic_dev *riic)
struct i2c_timings *t = &riic->i2c_t;
struct device *dev = riic->adapter.dev.parent;
- if (t->bus_freq_hz > I2C_MAX_FAST_MODE_FREQ) {
- dev_err(dev,
- "unsupported bus speed (%dHz). %d max\n",
- t->bus_freq_hz, I2C_MAX_FAST_MODE_FREQ);
+ if ((!riic->fast_mode_plus && t->bus_freq_hz > I2C_MAX_FAST_MODE_FREQ) ||
+ (riic->fast_mode_plus && t->bus_freq_hz > I2C_MAX_FAST_MODE_PLUS_FREQ)) {
+ dev_err(dev, "unsupported bus speed (%dHz). %d max\n", t->bus_freq_hz,
+ riic->fast_mode_plus ? I2C_MAX_FAST_MODE_PLUS_FREQ :
+ I2C_MAX_FAST_MODE_FREQ);
return -EINVAL;
}
@@ -407,6 +413,9 @@ static int riic_init_hw(struct riic_dev *riic)
riic_writeb(riic, 0, RIIC_ICSER);
riic_writeb(riic, ICMR3_ACKWP | ICMR3_RDRFS, RIIC_ICMR3);
+ if (riic->fast_mode_plus && t->bus_freq_hz == I2C_MAX_FAST_MODE_PLUS_FREQ)
+ riic_clear_set_bit(riic, 0, ICFER_FMPE, RIIC_ICFER);
+
riic_clear_set_bit(riic, ICCR1_IICRST, 0, RIIC_ICCR1);
pm_runtime_mark_last_busy(dev);
@@ -487,6 +496,14 @@ static int riic_i2c_probe(struct platform_device *pdev)
init_completion(&riic->msg_done);
i2c_parse_fw_timings(dev, &riic->i2c_t, true);
+ if (riic->info->fast_mode_plus) {
+ /*
+ * On the same SoC it may happen to have IP variants that support
+ * fast mode plus as well as IP variants that doesn't support it.
+ */
+ riic->fast_mode_plus = !of_property_read_bool(dev->of_node,
+ "renesas,riic-no-fast-mode-plus");
+ }
pm_runtime_set_autosuspend_delay(dev, 0);
pm_runtime_use_autosuspend(dev);
@@ -535,6 +552,7 @@ static const u8 riic_rz_a_regs[RIIC_REG_END] = {
[RIIC_ICCR2] = 0x04,
[RIIC_ICMR1] = 0x08,
[RIIC_ICMR3] = 0x10,
+ [RIIC_ICFER] = 0x14,
[RIIC_ICSER] = 0x18,
[RIIC_ICIER] = 0x1c,
[RIIC_ICSR2] = 0x24,
@@ -548,11 +566,17 @@ static const struct riic_of_data riic_rz_a_info = {
.regs = riic_rz_a_regs,
};
+static const struct riic_of_data riic_rz_g2_info = {
+ .regs = riic_rz_a_regs,
+ .fast_mode_plus = true,
+};
+
static const u8 riic_rz_v2h_regs[RIIC_REG_END] = {
[RIIC_ICCR1] = 0x00,
[RIIC_ICCR2] = 0x01,
[RIIC_ICMR1] = 0x02,
[RIIC_ICMR3] = 0x04,
+ [RIIC_ICFER] = 0x05,
[RIIC_ICSER] = 0x06,
[RIIC_ICIER] = 0x07,
[RIIC_ICSR2] = 0x09,
@@ -564,6 +588,7 @@ static const u8 riic_rz_v2h_regs[RIIC_REG_END] = {
static const struct riic_of_data riic_rz_v2h_info = {
.regs = riic_rz_v2h_regs,
+ .fast_mode_plus = true,
};
static int riic_i2c_suspend(struct device *dev)
@@ -610,6 +635,9 @@ static const struct dev_pm_ops riic_i2c_pm_ops = {
static const struct of_device_id riic_i2c_dt_ids[] = {
{ .compatible = "renesas,riic-rz", .data = &riic_rz_a_info },
+ { .compatible = "renesas,riic-r9a07g043", .data = &riic_rz_g2_info, },
+ { .compatible = "renesas,riic-r9a07g044", .data = &riic_rz_g2_info, },
+ { .compatible = "renesas,riic-r9a07g054", .data = &riic_rz_g2_info, },
{ .compatible = "renesas,riic-r9a09g057", .data = &riic_rz_v2h_info },
{ /* Sentinel */ },
};