diff --git a/drivers/net/can/mttcan/hal/m_ttcan.c b/drivers/net/can/mttcan/hal/m_ttcan.c index bb08e47c..1d3037a2 100644 --- a/drivers/net/can/mttcan/hal/m_ttcan.c +++ b/drivers/net/can/mttcan/hal/m_ttcan.c @@ -9,10 +9,8 @@ #define MTTCAN_INIT_TIMEOUT 1000 -#if KERNEL_VERSION(5, 16, 0) >= LINUX_VERSION_CODE #define MTTCAN_SPEED_5MBPS 5000000 #define MTTCAN_SPEED_8MBPS 8333333 -#endif void ttcan_print_version(struct ttcan_controller *ttcan) { @@ -293,7 +291,7 @@ inline u32 ttcan_read_ecr(struct ttcan_controller *ttcan) return ttcan_read32(ttcan, ADR_MTTCAN_ECR); } -#if KERNEL_VERSION(5, 16, 0) >= LINUX_VERSION_CODE +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0) static void tegra_mttcan_config_prod_settings(struct mttcan_priv *priv) { struct ttcan_controller *ttcan = priv->ttcan; @@ -317,6 +315,47 @@ static void tegra_mttcan_config_prod_settings(struct mttcan_priv *priv) if (ret == 0) dev_dbg(priv->device, "setting prod: %s\n", prod_name); } +#else +static void tegra_mttcan_write_prod_settings(struct mttcan_priv *priv, const char *prod_name) +{ + struct ttcan_controller *ttcan = priv->ttcan; + struct tegra_prod_reg_info *reg_info; + struct tegra_prod_cfg_info *prod_cfg; + u32 rval; + int i; + + prod_cfg = tegra_prod_get_by_name_from_list(priv->device, ttcan->prod_list, prod_name); + if (prod_cfg == NULL) + return; + + reg_info = prod_cfg->reg_info; + for (i = 0; i < prod_cfg->num_reg_info; ++i) { + rval = ttcan_read32(ttcan, reg_info[i].reg_offset); + rval &= ~reg_info[i].reg_mask; + rval |= reg_info[i].reg_value; + ttcan_write32(ttcan, reg_info[i].reg_offset, rval); + } +} + +static void tegra_mttcan_config_prod_settings(struct mttcan_priv *priv) +{ + struct ttcan_controller *ttcan = priv->ttcan; + char *prod_name; + + switch (ttcan->bt_config.data.bitrate) { + case MTTCAN_SPEED_5MBPS: + prod_name = "prod_c_can_5m"; + break; + case MTTCAN_SPEED_8MBPS: + prod_name = "prod_c_can_8m"; + break; + default: + prod_name = "prod_c_can_2m_1m"; + break; + } + + tegra_mttcan_write_prod_settings(priv, prod_name); +} #endif int ttcan_set_bitrate(struct mttcan_priv *priv) @@ -327,9 +366,6 @@ int ttcan_set_bitrate(struct mttcan_priv *priv) u32 cccr_reg; u32 nbtp_reg; u32 dbtp_reg; -#if KERNEL_VERSION(5, 16, 0) < LINUX_VERSION_CODE - u32 tdcr_reg; -#endif nbtp_reg = ((ttcan->bt_config.nominal.phase_seg2 - 1) << MTT_NBTP_NTSEG2_SHIFT) & MTT_NBTP_NTSEG2_MASK; @@ -366,12 +402,6 @@ int ttcan_set_bitrate(struct mttcan_priv *priv) dbtp_reg |= (ttcan->bt_config.data.tdc << MTT_DBTP_TDC_SHIFT) & MTT_DBTP_TDC_MASK; -#if KERNEL_VERSION(5, 16, 0) < LINUX_VERSION_CODE - tdcr_reg = (ttcan->bt_config.data.tdc_offset << - MTT_TDCR_TDCO_SHIFT) & MTT_TDCR_TDCO_MASK; - - tdcr_reg |= ttcan->tdc_offset; -#endif dev_dbg(priv->device, "%s DBTP(0x%x) value (0x%x)\n", __func__, ADR_MTTCAN_DBTP, dbtp_reg); ret = ttcan_write32_check(ttcan, ADR_MTTCAN_DBTP, @@ -381,18 +411,8 @@ int ttcan_set_bitrate(struct mttcan_priv *priv) return ret; } -#if KERNEL_VERSION(5, 16, 0) >= LINUX_VERSION_CODE if (ttcan->prod_list) tegra_mttcan_config_prod_settings(priv); -#else - ret = ttcan_write32_check(ttcan, ADR_MTTCAN_TDCR, - tdcr_reg, MTTCAN_TDCR_MSK); - if (ret) { - dev_err(priv->device, "%s: Fast bitrate configuration failed\n", - __func__); - return ret; - } -#endif temp_reg = cccr_reg = ttcan_read32(ttcan, ADR_MTTCAN_CCCR); if (ttcan->bt_config.fd_flags & CAN_FD_FLAG) diff --git a/drivers/net/can/mttcan/include/m_ttcan.h b/drivers/net/can/mttcan/include/m_ttcan.h index f6ebec3f..9155f8ee 100644 --- a/drivers/net/can/mttcan/include/m_ttcan.h +++ b/drivers/net/can/mttcan/include/m_ttcan.h @@ -287,8 +287,10 @@ struct ttcan_controller { struct list_head rx_q1; struct list_head rx_b; struct list_head tx_evt; -#if KERNEL_VERSION(5, 16, 0) >= LINUX_VERSION_CODE +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0) struct tegra_prod *prod_list; +#else + struct tegra_prod_cfg_list *prod_list; #endif void __iomem *base; /* controller regs space should be remapped. */ void __iomem *xbase; /* extra registers are mapped */ diff --git a/drivers/net/can/mttcan/include/m_ttcan_linux.h b/drivers/net/can/mttcan/include/m_ttcan_linux.h index fef729a6..9e48cb1c 100644 --- a/drivers/net/can/mttcan/include/m_ttcan_linux.h +++ b/drivers/net/can/mttcan/include/m_ttcan_linux.h @@ -31,9 +31,7 @@ #include #include #include -#if KERNEL_VERSION(5, 16, 0) >= LINUX_VERSION_CODE #include -#endif #include #include #ifdef CONFIG_CLK_SRC_TEGRA18_US_TIMER diff --git a/drivers/net/can/mttcan/include/m_ttcan_regdef.h b/drivers/net/can/mttcan/include/m_ttcan_regdef.h index 51a7b4b3..7a6707b9 100644 --- a/drivers/net/can/mttcan/include/m_ttcan_regdef.h +++ b/drivers/net/can/mttcan/include/m_ttcan_regdef.h @@ -14,6 +14,8 @@ #define ADR_MTTCAN_DBTP 0x00C #define DEF_MTTCAN_DBTP 0x00000A33 #define MTTCAN_DBTP_MSK 0x009F1FFF +#define MTTCAN_CORE_DBTP_TDC_FIELD_START 23 +#define MTTCAN_CORE_DBTP_TDC_FIELD_WIDTH 1 #define ADR_MTTCAN_TEST 0x010 #define DEF_MTTCAN_TEST 0x00000080 @@ -51,6 +53,8 @@ #define ADR_MTTCAN_TDCR 0x048 #define DEF_MTTCAN_TDCR 0x00000000 #define MTTCAN_TDCR_MSK 0x00007F7F +#define MTTCAN_CORE_TDCR_TDCO_FIELD_START 8 +#define MTTCAN_CORE_TDCR_TDCO_FIELD_WIDTH 7 #define ADR_MTTCAN_IR 0x050 #define DEF_MTTCAN_IR 0x00000000 diff --git a/drivers/net/can/mttcan/native/m_ttcan_linux.c b/drivers/net/can/mttcan/native/m_ttcan_linux.c index 639afbe1..b7adff8e 100644 --- a/drivers/net/can/mttcan/native/m_ttcan_linux.c +++ b/drivers/net/can/mttcan/native/m_ttcan_linux.c @@ -12,6 +12,28 @@ #define CAN_MSG_FLUSH_TIMEOUT 100 static void mttcan_start(struct net_device *dev); +#if LINUX_VERSION_CODE > KERNEL_VERSION(5, 16, 0) +#define MTTCAN_PROD_FIELD(name, rindex, roffset, fname) \ +{ \ + .field_name = name, \ + .reg_index = rindex, \ + .reg_offset = roffset, \ + .field_start = fname##_FIELD_START, \ + .field_len = fname##_FIELD_WIDTH, \ +} + +static const struct tegra_prod_dev_reg_field mttcan_prod_dev_reg_field[] = { + MTTCAN_PROD_FIELD("nvidia,can-enable-tdc-dbtp", 0, ADR_MTTCAN_DBTP, MTTCAN_CORE_DBTP_TDC), + MTTCAN_PROD_FIELD("nvidia,can-tdco-value-tdcr", 0, ADR_MTTCAN_TDCR, MTTCAN_CORE_TDCR_TDCO), +}; + +static const struct tegra_prod_dev_info mttcan_prod_dev_info = { + .num_total_dev_reg = 2, + .num_dev_reg_field = ARRAY_SIZE(mttcan_prod_dev_reg_field), + .dev_reg_field = mttcan_prod_dev_reg_field, +}; +#endif + /* We are reading cntvct_el0 for TSC time. We are not issuing ISB * before reading the counter as by the time CAN irq comes and * CAN softirq is executed, we would have lot of instruction executed. @@ -1855,13 +1877,15 @@ static int mttcan_probe(struct platform_device *pdev) if (ret) goto exit_free_device; -#if KERNEL_VERSION(5, 16, 0) >= LINUX_VERSION_CODE +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0) priv->ttcan->prod_list = devm_tegra_prod_get(&pdev->dev); +#else + priv->ttcan->prod_list = devm_tegra_prod_get_list(&pdev->dev, &mttcan_prod_dev_info); +#endif if (IS_ERR_OR_NULL(priv->ttcan->prod_list)) { dev_dbg(&pdev->dev, "Prod-setting not available\n"); priv->ttcan->prod_list = NULL; } -#endif ret = register_mttcan_dev(dev); if (ret) {