[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20251117102530.903555-4-kkartik@nvidia.com>
Date: Mon, 17 Nov 2025 15:55:29 +0530
From: Kartik Rajput <kkartik@...dia.com>
To: <ldewangan@...dia.com>, <digetx@...il.com>, <andi.shyti@...nel.org>,
<thierry.reding@...il.com>, <jonathanh@...dia.com>, <akhilrajeev@...dia.com>,
<smangipudi@...dia.com>, <linux-i2c@...r.kernel.org>,
<linux-tegra@...r.kernel.org>, <linux-kernel@...r.kernel.org>
CC: Kartik Rajput <kkartik@...dia.com>
Subject: [PATCH v2 3/4] i2c: tegra: Add logic to support different register offsets
Tegra410 use different offsets for existing I2C registers, update
the logic to use appropriate offsets per SoC.
As the registers offsets are now also defined for dvc and vi, following
function are not required and they are removed:
- tegra_i2c_reg_addr(): No translation required.
- dvc_writel(): Replaced with i2c_writel() with DVC check.
- dvc_readl(): Replaced with i2c_readl().
Signed-off-by: Kartik Rajput <kkartik@...dia.com>
---
Changes in v2:
* Replace individual is_dvc and is_vi flags with an I2C variant.
* Add tegra20_dvc_i2c_hw and tegra210_vi_i2c_hw in a separate
patch.
* Use calculated offsets for tegra20_dvc_i2c_regs and
tegra210_vi_i2c_regs.
* Initialize registers only if they are used on the given SoC.
---
drivers/i2c/busses/i2c-tegra.c | 390 +++++++++++++++++++++------------
1 file changed, 248 insertions(+), 142 deletions(-)
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 84255cdf406b..b571001b90db 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -30,47 +30,35 @@
#define BYTES_PER_FIFO_WORD 4
-#define I2C_CNFG 0x000
#define I2C_CNFG_DEBOUNCE_CNT GENMASK(14, 12)
#define I2C_CNFG_PACKET_MODE_EN BIT(10)
#define I2C_CNFG_NEW_MASTER_FSM BIT(11)
#define I2C_CNFG_MULTI_MASTER_MODE BIT(17)
-#define I2C_STATUS 0x01c
-#define I2C_SL_CNFG 0x020
+
#define I2C_SL_CNFG_NACK BIT(1)
#define I2C_SL_CNFG_NEWSL BIT(2)
-#define I2C_SL_ADDR1 0x02c
-#define I2C_SL_ADDR2 0x030
-#define I2C_TLOW_SEXT 0x034
-#define I2C_TX_FIFO 0x050
-#define I2C_RX_FIFO 0x054
-#define I2C_PACKET_TRANSFER_STATUS 0x058
-#define I2C_FIFO_CONTROL 0x05c
+
#define I2C_FIFO_CONTROL_TX_FLUSH BIT(1)
#define I2C_FIFO_CONTROL_RX_FLUSH BIT(0)
#define I2C_FIFO_CONTROL_TX_TRIG(x) (((x) - 1) << 5)
#define I2C_FIFO_CONTROL_RX_TRIG(x) (((x) - 1) << 2)
-#define I2C_FIFO_STATUS 0x060
#define I2C_FIFO_STATUS_TX GENMASK(7, 4)
#define I2C_FIFO_STATUS_RX GENMASK(3, 0)
-#define I2C_INT_MASK 0x064
-#define I2C_INT_STATUS 0x068
+
#define I2C_INT_BUS_CLR_DONE BIT(11)
#define I2C_INT_PACKET_XFER_COMPLETE BIT(7)
#define I2C_INT_NO_ACK BIT(3)
#define I2C_INT_ARBITRATION_LOST BIT(2)
#define I2C_INT_TX_FIFO_DATA_REQ BIT(1)
#define I2C_INT_RX_FIFO_DATA_REQ BIT(0)
-#define I2C_CLK_DIVISOR 0x06c
+
#define I2C_CLK_DIVISOR_STD_FAST_MODE GENMASK(31, 16)
#define I2C_CLK_DIVISOR_HSMODE GENMASK(15, 0)
-#define DVC_CTRL_REG1 0x000
#define DVC_CTRL_REG1_INTR_EN BIT(10)
-#define DVC_CTRL_REG3 0x008
#define DVC_CTRL_REG3_SW_PROG BIT(26)
#define DVC_CTRL_REG3_I2C_DONE_INTR_EN BIT(30)
-#define DVC_STATUS 0x00c
+
#define DVC_STATUS_I2C_DONE_INTR BIT(30)
#define I2C_ERR_NONE 0x00
@@ -94,50 +82,37 @@
#define I2C_HEADER_HS_MODE BIT(22)
#define I2C_HEADER_SLAVE_ADDR_SHIFT 1
-#define I2C_BUS_CLEAR_CNFG 0x084
#define I2C_BC_SCLK_THRESHOLD GENMASK(23, 16)
#define I2C_BC_STOP_COND BIT(2)
#define I2C_BC_TERMINATE BIT(1)
#define I2C_BC_ENABLE BIT(0)
-#define I2C_BUS_CLEAR_STATUS 0x088
#define I2C_BC_STATUS BIT(0)
-#define I2C_CONFIG_LOAD 0x08c
#define I2C_MSTR_CONFIG_LOAD BIT(0)
-#define I2C_CLKEN_OVERRIDE 0x090
#define I2C_MST_CORE_CLKEN_OVR BIT(0)
-#define I2C_INTERFACE_TIMING_0 0x094
-#define I2C_INTERFACE_TIMING_THIGH GENMASK(13, 8)
-#define I2C_INTERFACE_TIMING_TLOW GENMASK(5, 0)
-#define I2C_INTERFACE_TIMING_1 0x098
-#define I2C_INTERFACE_TIMING_TBUF GENMASK(29, 24)
-#define I2C_INTERFACE_TIMING_TSU_STO GENMASK(21, 16)
-#define I2C_INTERFACE_TIMING_THD_STA GENMASK(13, 8)
-#define I2C_INTERFACE_TIMING_TSU_STA GENMASK(5, 0)
-
-#define I2C_HS_INTERFACE_TIMING_0 0x09c
-#define I2C_HS_INTERFACE_TIMING_THIGH GENMASK(13, 8)
-#define I2C_HS_INTERFACE_TIMING_TLOW GENMASK(5, 0)
-#define I2C_HS_INTERFACE_TIMING_1 0x0a0
-#define I2C_HS_INTERFACE_TIMING_TSU_STO GENMASK(21, 16)
-#define I2C_HS_INTERFACE_TIMING_THD_STA GENMASK(13, 8)
-#define I2C_HS_INTERFACE_TIMING_TSU_STA GENMASK(5, 0)
-
-#define I2C_MST_FIFO_CONTROL 0x0b4
+#define I2C_INTERFACE_TIMING_THIGH GENMASK(13, 8)
+#define I2C_INTERFACE_TIMING_TLOW GENMASK(5, 0)
+#define I2C_INTERFACE_TIMING_TBUF GENMASK(29, 24)
+#define I2C_INTERFACE_TIMING_TSU_STO GENMASK(21, 16)
+#define I2C_INTERFACE_TIMING_THD_STA GENMASK(13, 8)
+#define I2C_INTERFACE_TIMING_TSU_STA GENMASK(5, 0)
+
+#define I2C_HS_INTERFACE_TIMING_THIGH GENMASK(13, 8)
+#define I2C_HS_INTERFACE_TIMING_TLOW GENMASK(5, 0)
+#define I2C_HS_INTERFACE_TIMING_TSU_STO GENMASK(21, 16)
+#define I2C_HS_INTERFACE_TIMING_THD_STA GENMASK(13, 8)
+#define I2C_HS_INTERFACE_TIMING_TSU_STA GENMASK(5, 0)
+
#define I2C_MST_FIFO_CONTROL_RX_FLUSH BIT(0)
#define I2C_MST_FIFO_CONTROL_TX_FLUSH BIT(1)
#define I2C_MST_FIFO_CONTROL_RX_TRIG(x) (((x) - 1) << 4)
#define I2C_MST_FIFO_CONTROL_TX_TRIG(x) (((x) - 1) << 16)
-#define I2C_MST_FIFO_STATUS 0x0b8
#define I2C_MST_FIFO_STATUS_TX GENMASK(23, 16)
#define I2C_MST_FIFO_STATUS_RX GENMASK(7, 0)
-#define I2C_MASTER_RESET_CNTRL 0x0a8
-
-#define I2C_SW_MUTEX 0x0ec
#define I2C_SW_MUTEX_REQUEST GENMASK(3, 0)
#define I2C_SW_MUTEX_GRANT GENMASK(7, 4)
#define I2C_SW_MUTEX_ID_CCPLEX 9
@@ -159,6 +134,149 @@
*/
#define I2C_PIO_MODE_PREFERRED_LEN 32
+struct tegra_i2c_regs {
+ unsigned int cnfg;
+ unsigned int status;
+ unsigned int sl_cnfg;
+ unsigned int sl_addr1;
+ unsigned int sl_addr2;
+ unsigned int tlow_sext;
+ unsigned int tx_fifo;
+ unsigned int rx_fifo;
+ unsigned int packet_transfer_status;
+ unsigned int fifo_control;
+ unsigned int fifo_status;
+ unsigned int int_mask;
+ unsigned int int_status;
+ unsigned int clk_divisor;
+ unsigned int bus_clear_cnfg;
+ unsigned int bus_clear_status;
+ unsigned int config_load;
+ unsigned int clken_override;
+ unsigned int interface_timing_0;
+ unsigned int interface_timing_1;
+ unsigned int hs_interface_timing_0;
+ unsigned int hs_interface_timing_1;
+ unsigned int master_reset_cntrl;
+ unsigned int mst_fifo_control;
+ unsigned int mst_fifo_status;
+ unsigned int sw_mutex;
+ unsigned int dvc_ctrl_reg1;
+ unsigned int dvc_ctrl_reg3;
+ unsigned int dvc_status;
+};
+
+static const struct tegra_i2c_regs tegra20_i2c_regs = {
+ .cnfg = 0x000,
+ .status = 0x01c,
+ .sl_cnfg = 0x020,
+ .sl_addr1 = 0x02c,
+ .sl_addr2 = 0x030,
+ .tx_fifo = 0x050,
+ .rx_fifo = 0x054,
+ .packet_transfer_status = 0x058,
+ .fifo_control = 0x05c,
+ .fifo_status = 0x060,
+ .int_mask = 0x064,
+ .int_status = 0x068,
+ .clk_divisor = 0x06c,
+ .bus_clear_cnfg = 0x084,
+ .bus_clear_status = 0x088,
+ .config_load = 0x08c,
+ .clken_override = 0x090,
+ .interface_timing_0 = 0x094,
+ .interface_timing_1 = 0x098,
+ .hs_interface_timing_0 = 0x09c,
+ .hs_interface_timing_1 = 0x0a0,
+ .master_reset_cntrl = 0x0a8,
+ .mst_fifo_control = 0x0b4,
+ .mst_fifo_status = 0x0b8,
+};
+
+#if IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)
+static const struct tegra_i2c_regs tegra20_dvc_i2c_regs = {
+ .dvc_ctrl_reg1 = 0x000,
+ .dvc_ctrl_reg3 = 0x008,
+ .dvc_status = 0x00c,
+ .cnfg = 0x040,
+ .status = 0x05c,
+ .tx_fifo = 0x060,
+ .rx_fifo = 0x064,
+ .packet_transfer_status = 0x068,
+ .fifo_control = 0x06c,
+ .fifo_status = 0x070,
+ .int_mask = 0x074,
+ .int_status = 0x078,
+ .clk_divisor = 0x07c,
+ .bus_clear_cnfg = 0x0c4,
+ .bus_clear_status = 0x0c8,
+ .config_load = 0x0cc,
+ .clken_override = 0x0d0,
+ .interface_timing_0 = 0x0d4,
+ .interface_timing_1 = 0x0d8,
+ .hs_interface_timing_0 = 0x0dc,
+ .hs_interface_timing_1 = 0x0e0,
+ .master_reset_cntrl = 0x0e8,
+ .mst_fifo_control = 0x0c4,
+ .mst_fifo_status = 0x0c8,
+};
+#endif
+
+#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
+static const struct tegra_i2c_regs tegra210_vi_i2c_regs = {
+ .cnfg = 0x0c00,
+ .status = 0x0c70,
+ .tlow_sext = 0x0cd0,
+ .tx_fifo = 0x0d40,
+ .rx_fifo = 0x0d50,
+ .packet_transfer_status = 0x0d60,
+ .fifo_control = 0x0d70,
+ .fifo_status = 0x0d80,
+ .int_mask = 0x0d90,
+ .int_status = 0x0da0,
+ .clk_divisor = 0x0db0,
+ .bus_clear_cnfg = 0x0e10,
+ .bus_clear_status = 0x0e20,
+ .config_load = 0x0e30,
+ .clken_override = 0x0e40,
+ .interface_timing_0 = 0x0e50,
+ .interface_timing_1 = 0x0e60,
+ .hs_interface_timing_0 = 0x0e70,
+ .hs_interface_timing_1 = 0x0e80,
+ .master_reset_cntrl = 0x0ea0,
+ .mst_fifo_control = 0x0ed0,
+ .mst_fifo_status = 0x0ee0,
+};
+#endif
+
+static const struct tegra_i2c_regs tegra264_i2c_regs = {
+ .cnfg = 0x000,
+ .status = 0x01c,
+ .sl_cnfg = 0x020,
+ .sl_addr1 = 0x02c,
+ .sl_addr2 = 0x030,
+ .tx_fifo = 0x050,
+ .rx_fifo = 0x054,
+ .packet_transfer_status = 0x058,
+ .fifo_control = 0x05c,
+ .fifo_status = 0x060,
+ .int_mask = 0x064,
+ .int_status = 0x068,
+ .clk_divisor = 0x06c,
+ .bus_clear_cnfg = 0x084,
+ .bus_clear_status = 0x088,
+ .config_load = 0x08c,
+ .clken_override = 0x090,
+ .interface_timing_0 = 0x094,
+ .interface_timing_1 = 0x098,
+ .hs_interface_timing_0 = 0x09c,
+ .hs_interface_timing_1 = 0x0a0,
+ .master_reset_cntrl = 0x0a8,
+ .mst_fifo_control = 0x0b4,
+ .mst_fifo_status = 0x0b8,
+ .sw_mutex = 0x0ec,
+};
+
/*
* msg_end_type: The bus control which needs to be sent at end of transfer.
* @MSG_END_STOP: Send stop pulse.
@@ -236,6 +354,7 @@ enum tegra_i2c_variant {
* @has_hs_mode_support: Has support for high speed (HS) mode transfers.
* @has_mutex: Has mutex register for mutual exclusion with other firmwares or VMs.
* @variant: This represents the I2C controller variant.
+ * @regs: Register offsets for the specific SoC variant.
*/
struct tegra_i2c_hw_feature {
bool has_continue_xfer_support;
@@ -268,6 +387,7 @@ struct tegra_i2c_hw_feature {
bool has_hs_mode_support;
bool has_mutex;
enum tegra_i2c_variant variant;
+ const struct tegra_i2c_regs *regs;
};
/**
@@ -340,51 +460,26 @@ struct tegra_i2c_dev {
#define IS_DVC(dev) ((dev)->hw->variant == TEGRA_I2C_VARIANT_DVC)
#define IS_VI(dev) ((dev)->hw->variant == TEGRA_I2C_VARIANT_VI)
-static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val,
- unsigned int reg)
-{
- writel_relaxed(val, i2c_dev->base + reg);
-}
-
-static u32 dvc_readl(struct tegra_i2c_dev *i2c_dev, unsigned int reg)
-{
- return readl_relaxed(i2c_dev->base + reg);
-}
-
-/*
- * If necessary, i2c_writel() and i2c_readl() will offset the register
- * in order to talk to the I2C block inside the DVC block.
- */
-static u32 tegra_i2c_reg_addr(struct tegra_i2c_dev *i2c_dev, unsigned int reg)
-{
- if (IS_DVC(i2c_dev))
- reg += (reg >= I2C_TX_FIFO) ? 0x10 : 0x40;
- else if (IS_VI(i2c_dev))
- reg = 0xc00 + (reg << 2);
-
- return reg;
-}
-
static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned int reg)
{
- writel_relaxed(val, i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
+ writel_relaxed(val, i2c_dev->base + reg);
/* read back register to make sure that register writes completed */
- if (reg != I2C_TX_FIFO)
- readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
+ if (!IS_DVC(i2c_dev) && reg != i2c_dev->hw->regs->tx_fifo)
+ readl_relaxed(i2c_dev->base + reg);
else if (IS_VI(i2c_dev))
- readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, I2C_INT_STATUS));
+ readl_relaxed(i2c_dev->base + i2c_dev->hw->regs->int_status);
}
static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned int reg)
{
- return readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
+ return readl_relaxed(i2c_dev->base + reg);
}
static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, void *data,
unsigned int reg, unsigned int len)
{
- writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
+ writesl(i2c_dev->base + reg, data, len);
}
static void i2c_writesl_vi(struct tegra_i2c_dev *i2c_dev, void *data,
@@ -405,12 +500,12 @@ static void i2c_writesl_vi(struct tegra_i2c_dev *i2c_dev, void *data,
static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data,
unsigned int reg, unsigned int len)
{
- readsl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
+ readsl(i2c_dev->base + reg, data, len);
}
static bool tegra_i2c_mutex_acquired(struct tegra_i2c_dev *i2c_dev)
{
- unsigned int reg = tegra_i2c_reg_addr(i2c_dev, I2C_SW_MUTEX);
+ unsigned int reg = i2c_dev->hw->regs->sw_mutex;
u32 val, id;
val = readl(i2c_dev->base + reg);
@@ -421,7 +516,7 @@ static bool tegra_i2c_mutex_acquired(struct tegra_i2c_dev *i2c_dev)
static bool tegra_i2c_mutex_trylock(struct tegra_i2c_dev *i2c_dev)
{
- unsigned int reg = tegra_i2c_reg_addr(i2c_dev, I2C_SW_MUTEX);
+ unsigned int reg = i2c_dev->hw->regs->sw_mutex;
u32 val, id;
val = readl(i2c_dev->base + reg);
@@ -459,7 +554,7 @@ static int tegra_i2c_mutex_lock(struct tegra_i2c_dev *i2c_dev)
static int tegra_i2c_mutex_unlock(struct tegra_i2c_dev *i2c_dev)
{
- unsigned int reg = tegra_i2c_reg_addr(i2c_dev, I2C_SW_MUTEX);
+ unsigned int reg = i2c_dev->hw->regs->sw_mutex;
u32 val, id;
if (!i2c_dev->hw->has_mutex)
@@ -482,16 +577,16 @@ static void tegra_i2c_mask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask)
{
u32 int_mask;
- int_mask = i2c_readl(i2c_dev, I2C_INT_MASK) & ~mask;
- i2c_writel(i2c_dev, int_mask, I2C_INT_MASK);
+ int_mask = i2c_readl(i2c_dev, i2c_dev->hw->regs->int_mask) & ~mask;
+ i2c_writel(i2c_dev, int_mask, i2c_dev->hw->regs->int_mask);
}
static void tegra_i2c_unmask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask)
{
u32 int_mask;
- int_mask = i2c_readl(i2c_dev, I2C_INT_MASK) | mask;
- i2c_writel(i2c_dev, int_mask, I2C_INT_MASK);
+ int_mask = i2c_readl(i2c_dev, i2c_dev->hw->regs->int_mask) | mask;
+ i2c_writel(i2c_dev, int_mask, i2c_dev->hw->regs->int_mask);
}
static void tegra_i2c_dma_complete(void *args)
@@ -619,14 +714,14 @@ static void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
{
u32 val;
- val = dvc_readl(i2c_dev, DVC_CTRL_REG3);
+ val = i2c_readl(i2c_dev, i2c_dev->hw->regs->dvc_ctrl_reg3);
val |= DVC_CTRL_REG3_SW_PROG;
val |= DVC_CTRL_REG3_I2C_DONE_INTR_EN;
- dvc_writel(i2c_dev, val, DVC_CTRL_REG3);
+ i2c_writel(i2c_dev, val, i2c_dev->hw->regs->dvc_ctrl_reg3);
- val = dvc_readl(i2c_dev, DVC_CTRL_REG1);
+ val = i2c_readl(i2c_dev, i2c_dev->hw->regs->dvc_ctrl_reg1);
val |= DVC_CTRL_REG1_INTR_EN;
- dvc_writel(i2c_dev, val, DVC_CTRL_REG1);
+ i2c_writel(i2c_dev, val, i2c_dev->hw->regs->dvc_ctrl_reg1);
}
static void tegra_i2c_vi_init(struct tegra_i2c_dev *i2c_dev)
@@ -635,34 +730,34 @@ static void tegra_i2c_vi_init(struct tegra_i2c_dev *i2c_dev)
value = FIELD_PREP(I2C_INTERFACE_TIMING_THIGH, 2) |
FIELD_PREP(I2C_INTERFACE_TIMING_TLOW, 4);
- i2c_writel(i2c_dev, value, I2C_INTERFACE_TIMING_0);
+ i2c_writel(i2c_dev, value, i2c_dev->hw->regs->interface_timing_0);
value = FIELD_PREP(I2C_INTERFACE_TIMING_TBUF, 4) |
FIELD_PREP(I2C_INTERFACE_TIMING_TSU_STO, 7) |
FIELD_PREP(I2C_INTERFACE_TIMING_THD_STA, 4) |
FIELD_PREP(I2C_INTERFACE_TIMING_TSU_STA, 4);
- i2c_writel(i2c_dev, value, I2C_INTERFACE_TIMING_1);
+ i2c_writel(i2c_dev, value, i2c_dev->hw->regs->interface_timing_1);
value = FIELD_PREP(I2C_HS_INTERFACE_TIMING_THIGH, 3) |
FIELD_PREP(I2C_HS_INTERFACE_TIMING_TLOW, 8);
- i2c_writel(i2c_dev, value, I2C_HS_INTERFACE_TIMING_0);
+ i2c_writel(i2c_dev, value, i2c_dev->hw->regs->hs_interface_timing_0);
value = FIELD_PREP(I2C_HS_INTERFACE_TIMING_TSU_STO, 11) |
FIELD_PREP(I2C_HS_INTERFACE_TIMING_THD_STA, 11) |
FIELD_PREP(I2C_HS_INTERFACE_TIMING_TSU_STA, 11);
- i2c_writel(i2c_dev, value, I2C_HS_INTERFACE_TIMING_1);
+ i2c_writel(i2c_dev, value, i2c_dev->hw->regs->hs_interface_timing_1);
value = FIELD_PREP(I2C_BC_SCLK_THRESHOLD, 9) | I2C_BC_STOP_COND;
- i2c_writel(i2c_dev, value, I2C_BUS_CLEAR_CNFG);
+ i2c_writel(i2c_dev, value, i2c_dev->hw->regs->bus_clear_cnfg);
- i2c_writel(i2c_dev, 0x0, I2C_TLOW_SEXT);
+ i2c_writel(i2c_dev, 0x0, i2c_dev->hw->regs->tlow_sext);
}
static int tegra_i2c_poll_register(struct tegra_i2c_dev *i2c_dev,
u32 reg, u32 mask, u32 delay_us,
u32 timeout_us)
{
- void __iomem *addr = i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg);
+ void __iomem *addr = i2c_dev->base + reg;
u32 val;
if (!i2c_dev->atomic_mode)
@@ -681,11 +776,11 @@ static int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
if (i2c_dev->hw->has_mst_fifo) {
mask = I2C_MST_FIFO_CONTROL_TX_FLUSH |
I2C_MST_FIFO_CONTROL_RX_FLUSH;
- offset = I2C_MST_FIFO_CONTROL;
+ offset = i2c_dev->hw->regs->mst_fifo_control;
} else {
mask = I2C_FIFO_CONTROL_TX_FLUSH |
I2C_FIFO_CONTROL_RX_FLUSH;
- offset = I2C_FIFO_CONTROL;
+ offset = i2c_dev->hw->regs->fifo_control;
}
val = i2c_readl(i2c_dev, offset);
@@ -708,9 +803,9 @@ static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
if (!i2c_dev->hw->has_config_load_reg)
return 0;
- i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD);
+ i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, i2c_dev->hw->regs->config_load);
- err = tegra_i2c_poll_register(i2c_dev, I2C_CONFIG_LOAD, 0xffffffff,
+ err = tegra_i2c_poll_register(i2c_dev, i2c_dev->hw->regs->config_load, 0xffffffff,
1000, I2C_CONFIG_LOAD_TIMEOUT);
if (err) {
dev_err(i2c_dev->dev, "failed to load config\n");
@@ -731,10 +826,10 @@ static int tegra_i2c_master_reset(struct tegra_i2c_dev *i2c_dev)
* SW needs to wait for 2us after assertion and de-assertion of this soft
* reset.
*/
- i2c_writel(i2c_dev, 0x1, I2C_MASTER_RESET_CNTRL);
+ i2c_writel(i2c_dev, 0x1, i2c_dev->hw->regs->master_reset_cntrl);
fsleep(2);
- i2c_writel(i2c_dev, 0x0, I2C_MASTER_RESET_CNTRL);
+ i2c_writel(i2c_dev, 0x0, i2c_dev->hw->regs->master_reset_cntrl);
fsleep(2);
return 0;
@@ -776,8 +871,8 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
if (i2c_dev->hw->has_multi_master_mode)
val |= I2C_CNFG_MULTI_MASTER_MODE;
- i2c_writel(i2c_dev, val, I2C_CNFG);
- i2c_writel(i2c_dev, 0, I2C_INT_MASK);
+ i2c_writel(i2c_dev, val, i2c_dev->hw->regs->cnfg);
+ i2c_writel(i2c_dev, 0, i2c_dev->hw->regs->int_mask);
if (IS_VI(i2c_dev))
tegra_i2c_vi_init(i2c_dev);
@@ -822,12 +917,12 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
clk_divisor = FIELD_PREP(I2C_CLK_DIVISOR_HSMODE,
i2c_dev->hw->clk_divisor_hs_mode) |
FIELD_PREP(I2C_CLK_DIVISOR_STD_FAST_MODE, non_hs_mode);
- i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR);
+ i2c_writel(i2c_dev, clk_divisor, i2c_dev->hw->regs->clk_divisor);
if (i2c_dev->hw->has_interface_timing_reg) {
val = FIELD_PREP(I2C_INTERFACE_TIMING_THIGH, thigh) |
FIELD_PREP(I2C_INTERFACE_TIMING_TLOW, tlow);
- i2c_writel(i2c_dev, val, I2C_INTERFACE_TIMING_0);
+ i2c_writel(i2c_dev, val, i2c_dev->hw->regs->interface_timing_0);
}
/*
@@ -835,7 +930,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
* Otherwise, preserve the chip default values.
*/
if (i2c_dev->hw->has_interface_timing_reg && tsu_thd)
- i2c_writel(i2c_dev, tsu_thd, I2C_INTERFACE_TIMING_1);
+ i2c_writel(i2c_dev, tsu_thd, i2c_dev->hw->regs->interface_timing_1);
/* Write HS mode registers. These will get used only for HS mode*/
if (i2c_dev->hw->has_hs_mode_support) {
@@ -845,8 +940,8 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
val = FIELD_PREP(I2C_HS_INTERFACE_TIMING_THIGH, thigh) |
FIELD_PREP(I2C_HS_INTERFACE_TIMING_TLOW, tlow);
- i2c_writel(i2c_dev, val, I2C_HS_INTERFACE_TIMING_0);
- i2c_writel(i2c_dev, tsu_thd, I2C_HS_INTERFACE_TIMING_1);
+ i2c_writel(i2c_dev, val, i2c_dev->hw->regs->hs_interface_timing_0);
+ i2c_writel(i2c_dev, tsu_thd, i2c_dev->hw->regs->hs_interface_timing_1);
}
clk_multiplier = (tlow + thigh + 2) * (non_hs_mode + 1);
@@ -859,12 +954,12 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
}
if (!IS_DVC(i2c_dev) && !IS_VI(i2c_dev)) {
- u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
+ u32 sl_cfg = i2c_readl(i2c_dev, i2c_dev->hw->regs->sl_cnfg);
sl_cfg |= I2C_SL_CNFG_NACK | I2C_SL_CNFG_NEWSL;
- i2c_writel(i2c_dev, sl_cfg, I2C_SL_CNFG);
- i2c_writel(i2c_dev, 0xfc, I2C_SL_ADDR1);
- i2c_writel(i2c_dev, 0x00, I2C_SL_ADDR2);
+ i2c_writel(i2c_dev, sl_cfg, i2c_dev->hw->regs->sl_cnfg);
+ i2c_writel(i2c_dev, 0xfc, i2c_dev->hw->regs->sl_addr1);
+ i2c_writel(i2c_dev, 0x00, i2c_dev->hw->regs->sl_addr2);
}
err = tegra_i2c_flush_fifos(i2c_dev);
@@ -872,7 +967,7 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
return err;
if (i2c_dev->multimaster_mode && i2c_dev->hw->has_slcg_override_reg)
- i2c_writel(i2c_dev, I2C_MST_CORE_CLKEN_OVR, I2C_CLKEN_OVERRIDE);
+ i2c_writel(i2c_dev, I2C_MST_CORE_CLKEN_OVR, i2c_dev->hw->regs->clken_override);
err = tegra_i2c_wait_for_config_load(i2c_dev);
if (err)
@@ -893,9 +988,9 @@ static int tegra_i2c_disable_packet_mode(struct tegra_i2c_dev *i2c_dev)
*/
udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->timings.bus_freq_hz));
- cnfg = i2c_readl(i2c_dev, I2C_CNFG);
+ cnfg = i2c_readl(i2c_dev, i2c_dev->hw->regs->cnfg);
if (cnfg & I2C_CNFG_PACKET_MODE_EN)
- i2c_writel(i2c_dev, cnfg & ~I2C_CNFG_PACKET_MODE_EN, I2C_CNFG);
+ i2c_writel(i2c_dev, cnfg & ~I2C_CNFG_PACKET_MODE_EN, i2c_dev->hw->regs->cnfg);
return tegra_i2c_wait_for_config_load(i2c_dev);
}
@@ -915,10 +1010,10 @@ static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)
return -EINVAL;
if (i2c_dev->hw->has_mst_fifo) {
- val = i2c_readl(i2c_dev, I2C_MST_FIFO_STATUS);
+ val = i2c_readl(i2c_dev, i2c_dev->hw->regs->mst_fifo_status);
rx_fifo_avail = FIELD_GET(I2C_MST_FIFO_STATUS_RX, val);
} else {
- val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);
+ val = i2c_readl(i2c_dev, i2c_dev->hw->regs->fifo_status);
rx_fifo_avail = FIELD_GET(I2C_FIFO_STATUS_RX, val);
}
@@ -927,7 +1022,7 @@ static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)
if (words_to_transfer > rx_fifo_avail)
words_to_transfer = rx_fifo_avail;
- i2c_readsl(i2c_dev, buf, I2C_RX_FIFO, words_to_transfer);
+ i2c_readsl(i2c_dev, buf, i2c_dev->hw->regs->rx_fifo, words_to_transfer);
buf += words_to_transfer * BYTES_PER_FIFO_WORD;
buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;
@@ -943,7 +1038,7 @@ static int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)
* when (words_to_transfer was > rx_fifo_avail) earlier
* in this function.
*/
- val = i2c_readl(i2c_dev, I2C_RX_FIFO);
+ val = i2c_readl(i2c_dev, i2c_dev->hw->regs->rx_fifo);
val = cpu_to_le32(val);
memcpy(buf, &val, buf_remaining);
buf_remaining = 0;
@@ -968,10 +1063,10 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
u32 val;
if (i2c_dev->hw->has_mst_fifo) {
- val = i2c_readl(i2c_dev, I2C_MST_FIFO_STATUS);
+ val = i2c_readl(i2c_dev, i2c_dev->hw->regs->mst_fifo_status);
tx_fifo_avail = FIELD_GET(I2C_MST_FIFO_STATUS_TX, val);
} else {
- val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);
+ val = i2c_readl(i2c_dev, i2c_dev->hw->regs->fifo_status);
tx_fifo_avail = FIELD_GET(I2C_FIFO_STATUS_TX, val);
}
@@ -1002,9 +1097,9 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
i2c_dev->msg_buf = buf + words_to_transfer * BYTES_PER_FIFO_WORD;
if (IS_VI(i2c_dev))
- i2c_writesl_vi(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
+ i2c_writesl_vi(i2c_dev, buf, i2c_dev->hw->regs->tx_fifo, words_to_transfer);
else
- i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
+ i2c_writesl(i2c_dev, buf, i2c_dev->hw->regs->tx_fifo, words_to_transfer);
buf += words_to_transfer * BYTES_PER_FIFO_WORD;
}
@@ -1026,7 +1121,7 @@ static int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
i2c_dev->msg_buf_remaining = 0;
i2c_dev->msg_buf = NULL;
- i2c_writel(i2c_dev, val, I2C_TX_FIFO);
+ i2c_writel(i2c_dev, val, i2c_dev->hw->regs->tx_fifo);
}
return 0;
@@ -1038,13 +1133,13 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
struct tegra_i2c_dev *i2c_dev = dev_id;
u32 status;
- status = i2c_readl(i2c_dev, I2C_INT_STATUS);
+ status = i2c_readl(i2c_dev, i2c_dev->hw->regs->int_status);
if (status == 0) {
dev_warn(i2c_dev->dev, "IRQ status 0 %08x %08x %08x\n",
- i2c_readl(i2c_dev, I2C_PACKET_TRANSFER_STATUS),
- i2c_readl(i2c_dev, I2C_STATUS),
- i2c_readl(i2c_dev, I2C_CNFG));
+ i2c_readl(i2c_dev, i2c_dev->hw->regs->packet_transfer_status),
+ i2c_readl(i2c_dev, i2c_dev->hw->regs->status),
+ i2c_readl(i2c_dev, i2c_dev->hw->regs->cnfg));
i2c_dev->msg_err |= I2C_ERR_UNKNOWN_INTERRUPT;
goto err;
}
@@ -1087,9 +1182,9 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
}
}
- i2c_writel(i2c_dev, status, I2C_INT_STATUS);
+ i2c_writel(i2c_dev, status, i2c_dev->hw->regs->int_status);
if (IS_DVC(i2c_dev))
- dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
+ i2c_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, i2c_dev->hw->regs->dvc_status);
/*
* During message read XFER_COMPLETE interrupt is triggered prior to
@@ -1125,10 +1220,10 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
if (i2c_dev->hw->supports_bus_clear)
tegra_i2c_mask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE);
- i2c_writel(i2c_dev, status, I2C_INT_STATUS);
+ i2c_writel(i2c_dev, status, i2c_dev->hw->regs->int_status);
if (IS_DVC(i2c_dev))
- dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
+ i2c_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, i2c_dev->hw->regs->dvc_status);
if (i2c_dev->dma_mode) {
dmaengine_terminate_async(i2c_dev->dma_chan);
@@ -1148,9 +1243,9 @@ static void tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev,
int err;
if (i2c_dev->hw->has_mst_fifo)
- reg = I2C_MST_FIFO_CONTROL;
+ reg = i2c_dev->hw->regs->mst_fifo_control;
else
- reg = I2C_FIFO_CONTROL;
+ reg = i2c_dev->hw->regs->fifo_control;
if (i2c_dev->dma_mode) {
if (len & 0xF)
@@ -1161,7 +1256,7 @@ static void tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev,
dma_burst = 8;
if (i2c_dev->msg_read) {
- reg_offset = tegra_i2c_reg_addr(i2c_dev, I2C_RX_FIFO);
+ reg_offset = i2c_dev->hw->regs->rx_fifo;
slv_config.src_addr = i2c_dev->base_phys + reg_offset;
slv_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
@@ -1172,7 +1267,7 @@ static void tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev,
else
val = I2C_FIFO_CONTROL_RX_TRIG(dma_burst);
} else {
- reg_offset = tegra_i2c_reg_addr(i2c_dev, I2C_TX_FIFO);
+ reg_offset = i2c_dev->hw->regs->tx_fifo;
slv_config.dst_addr = i2c_dev->base_phys + reg_offset;
slv_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
@@ -1215,7 +1310,7 @@ static unsigned long tegra_i2c_poll_completion(struct tegra_i2c_dev *i2c_dev,
ktime_t ktimeout = ktime_add_ms(ktime, timeout_ms);
do {
- u32 status = i2c_readl(i2c_dev, I2C_INT_STATUS);
+ u32 status = i2c_readl(i2c_dev, i2c_dev->hw->regs->int_status);
if (status)
tegra_i2c_isr(i2c_dev->irq, i2c_dev);
@@ -1274,14 +1369,14 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
val = FIELD_PREP(I2C_BC_SCLK_THRESHOLD, 9) | I2C_BC_STOP_COND |
I2C_BC_TERMINATE;
- i2c_writel(i2c_dev, val, I2C_BUS_CLEAR_CNFG);
+ i2c_writel(i2c_dev, val, i2c_dev->hw->regs->bus_clear_cnfg);
err = tegra_i2c_wait_for_config_load(i2c_dev);
if (err)
return err;
val |= I2C_BC_ENABLE;
- i2c_writel(i2c_dev, val, I2C_BUS_CLEAR_CNFG);
+ i2c_writel(i2c_dev, val, i2c_dev->hw->regs->bus_clear_cnfg);
tegra_i2c_unmask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE);
time_left = tegra_i2c_wait_completion(i2c_dev, &i2c_dev->msg_complete, 50);
@@ -1292,7 +1387,7 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
return -ETIMEDOUT;
}
- val = i2c_readl(i2c_dev, I2C_BUS_CLEAR_STATUS);
+ val = i2c_readl(i2c_dev, i2c_dev->hw->regs->bus_clear_status);
if (!(val & I2C_BC_STATUS)) {
dev_err(i2c_dev->dev, "un-recovered arbitration lost\n");
return -EIO;
@@ -1317,14 +1412,14 @@ static void tegra_i2c_push_packet_header(struct tegra_i2c_dev *i2c_dev,
if (i2c_dev->dma_mode && !i2c_dev->msg_read)
*dma_buf++ = packet_header;
else
- i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
+ i2c_writel(i2c_dev, packet_header, i2c_dev->hw->regs->tx_fifo);
packet_header = i2c_dev->msg_len - 1;
if (i2c_dev->dma_mode && !i2c_dev->msg_read)
*dma_buf++ = packet_header;
else
- i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
+ i2c_writel(i2c_dev, packet_header, i2c_dev->hw->regs->tx_fifo);
packet_header = I2C_HEADER_IE_ENABLE;
@@ -1352,7 +1447,7 @@ static void tegra_i2c_push_packet_header(struct tegra_i2c_dev *i2c_dev,
if (i2c_dev->dma_mode && !i2c_dev->msg_read)
*dma_buf++ = packet_header;
else
- i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
+ i2c_writel(i2c_dev, packet_header, i2c_dev->hw->regs->tx_fifo);
}
static int tegra_i2c_error_recover(struct tegra_i2c_dev *i2c_dev,
@@ -1473,7 +1568,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
tegra_i2c_unmask_irq(i2c_dev, int_mask);
dev_dbg(i2c_dev->dev, "unmasked IRQ: %02x\n",
- i2c_readl(i2c_dev, I2C_INT_MASK));
+ i2c_readl(i2c_dev, i2c_dev->hw->regs->int_mask));
if (i2c_dev->dma_mode) {
time_left = tegra_i2c_wait_completion(i2c_dev,
@@ -1648,6 +1743,7 @@ static const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
.has_hs_mode_support = false,
.has_mutex = false,
.variant = TEGRA_I2C_VARIANT_DEFAULT,
+ .regs = &tegra20_i2c_regs,
};
#if IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)
@@ -1680,6 +1776,7 @@ static const struct tegra_i2c_hw_feature tegra20_dvc_i2c_hw = {
.has_hs_mode_support = false,
.has_mutex = false,
.variant = TEGRA_I2C_VARIANT_DVC,
+ .regs = &tegra20_dvc_i2c_regs,
};
#endif
@@ -1712,6 +1809,7 @@ static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
.has_hs_mode_support = false,
.has_mutex = false,
.variant = TEGRA_I2C_VARIANT_DEFAULT,
+ .regs = &tegra20_i2c_regs,
};
static const struct tegra_i2c_hw_feature tegra114_i2c_hw = {
@@ -1743,6 +1841,7 @@ static const struct tegra_i2c_hw_feature tegra114_i2c_hw = {
.has_hs_mode_support = false,
.has_mutex = false,
.variant = TEGRA_I2C_VARIANT_DEFAULT,
+ .regs = &tegra20_i2c_regs,
};
static const struct tegra_i2c_hw_feature tegra124_i2c_hw = {
@@ -1774,6 +1873,7 @@ static const struct tegra_i2c_hw_feature tegra124_i2c_hw = {
.has_hs_mode_support = false,
.has_mutex = false,
.variant = TEGRA_I2C_VARIANT_DEFAULT,
+ .regs = &tegra20_i2c_regs,
};
static const struct tegra_i2c_hw_feature tegra210_i2c_hw = {
@@ -1805,6 +1905,7 @@ static const struct tegra_i2c_hw_feature tegra210_i2c_hw = {
.has_hs_mode_support = false,
.has_mutex = false,
.variant = TEGRA_I2C_VARIANT_DEFAULT,
+ .regs = &tegra20_i2c_regs,
};
#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
@@ -1837,6 +1938,7 @@ static const struct tegra_i2c_hw_feature tegra210_vi_i2c_hw = {
.has_hs_mode_support = false,
.has_mutex = false,
.variant = TEGRA_I2C_VARIANT_VI,
+ .regs = &tegra210_vi_i2c_regs,
};
#endif
@@ -1869,6 +1971,7 @@ static const struct tegra_i2c_hw_feature tegra186_i2c_hw = {
.has_hs_mode_support = false,
.has_mutex = false,
.variant = TEGRA_I2C_VARIANT_DEFAULT,
+ .regs = &tegra20_i2c_regs,
};
static const struct tegra_i2c_hw_feature tegra194_i2c_hw = {
@@ -1902,6 +2005,7 @@ static const struct tegra_i2c_hw_feature tegra194_i2c_hw = {
.has_hs_mode_support = true,
.has_mutex = false,
.variant = TEGRA_I2C_VARIANT_DEFAULT,
+ .regs = &tegra20_i2c_regs,
};
static const struct tegra_i2c_hw_feature tegra256_i2c_hw = {
.has_continue_xfer_support = true,
@@ -1934,6 +2038,7 @@ static const struct tegra_i2c_hw_feature tegra256_i2c_hw = {
.has_hs_mode_support = true,
.has_mutex = true,
.variant = TEGRA_I2C_VARIANT_DEFAULT,
+ .regs = &tegra20_i2c_regs,
};
static const struct tegra_i2c_hw_feature tegra264_i2c_hw = {
@@ -1967,6 +2072,7 @@ static const struct tegra_i2c_hw_feature tegra264_i2c_hw = {
.has_hs_mode_support = true,
.has_mutex = true,
.variant = TEGRA_I2C_VARIANT_DEFAULT,
+ .regs = &tegra264_i2c_regs,
};
static const struct of_device_id tegra_i2c_of_match[] = {
--
2.43.0
Powered by blists - more mailing lists