Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

i2c: tegra: Introduce tegra_i2c_variant to identify DVC and VI

Replace the per-instance DVC/VI boolean flags with a tegra_i2c_variant
enum and move the variant field into tegra_i2c_hw_feature so it is
populated via SoC match data.

Add dedicated SoC data entries for the "nvidia,tegra20-i2c-dvc" and
"nvidia,tegra210-i2c-vi" compatibles and drop compatible-string checks
from tegra_i2c_parse_dt.

Suggested-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Kartik Rajput <kkartik@nvidia.com>
Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://lore.kernel.org/r/20260324055843.549808-2-kkartik@nvidia.com

authored by

Kartik Rajput and committed by
Andi Shyti
4eeb19aa 4f1e5c96

+95 -17
+95 -17
drivers/i2c/busses/i2c-tegra.c
··· 171 171 MSG_END_CONTINUE, 172 172 }; 173 173 174 + /* 175 + * tegra_i2c_variant: Identifies the variant of I2C controller. 176 + * @TEGRA_I2C_VARIANT_DEFAULT: Identifies the default I2C controller. 177 + * @TEGRA_I2C_VARIANT_DVC: Identifies the DVC I2C controller, has a different register layout. 178 + * @TEGRA_I2C_VARIANT_VI: Identifies the VI I2C controller, has a different register layout. 179 + */ 180 + enum tegra_i2c_variant { 181 + TEGRA_I2C_VARIANT_DEFAULT, 182 + TEGRA_I2C_VARIANT_DVC, 183 + TEGRA_I2C_VARIANT_VI, 184 + }; 185 + 174 186 /** 175 187 * struct tegra_i2c_hw_feature : per hardware generation features 176 188 * @has_continue_xfer_support: continue-transfer supported ··· 235 223 * timing settings. 236 224 * @enable_hs_mode_support: Enable support for high speed (HS) mode transfers. 237 225 * @has_mutex: Has mutex register for mutual exclusion with other firmwares or VMs. 226 + * @variant: This represents the I2C controller variant. 238 227 */ 239 228 struct tegra_i2c_hw_feature { 240 229 bool has_continue_xfer_support; ··· 267 254 bool has_interface_timing_reg; 268 255 bool enable_hs_mode_support; 269 256 bool has_mutex; 257 + enum tegra_i2c_variant variant; 270 258 }; 271 259 272 260 /** ··· 282 268 * @base_phys: physical base address of the I2C controller 283 269 * @cont_id: I2C controller ID, used for packet header 284 270 * @irq: IRQ number of transfer complete interrupt 285 - * @is_dvc: identifies the DVC I2C controller, has a different register layout 286 - * @is_vi: identifies the VI I2C controller, has a different register layout 287 271 * @msg_complete: transfer completion notifier 288 272 * @msg_buf_remaining: size of unsent data in the message buffer 289 273 * @msg_len: length of message in current transfer ··· 333 321 bool atomic_mode; 334 322 bool dma_mode; 335 323 bool msg_read; 336 - bool is_dvc; 337 - bool is_vi; 338 324 }; 339 325 340 - #define IS_DVC(dev) (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && (dev)->is_dvc) 341 - #define IS_VI(dev) (IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) && (dev)->is_vi) 326 + #define IS_DVC(dev) (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && \ 327 + (dev)->hw->variant == TEGRA_I2C_VARIANT_DVC) 328 + #define IS_VI(dev) (IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) && \ 329 + (dev)->hw->variant == TEGRA_I2C_VARIANT_VI) 342 330 343 331 static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val, 344 332 unsigned int reg) ··· 1647 1635 .has_interface_timing_reg = false, 1648 1636 .enable_hs_mode_support = false, 1649 1637 .has_mutex = false, 1638 + .variant = TEGRA_I2C_VARIANT_DEFAULT, 1650 1639 }; 1640 + 1641 + #if IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) 1642 + static const struct tegra_i2c_hw_feature tegra20_dvc_i2c_hw = { 1643 + .has_continue_xfer_support = false, 1644 + .has_per_pkt_xfer_complete_irq = false, 1645 + .clk_divisor_hs_mode = 3, 1646 + .clk_divisor_std_mode = 0, 1647 + .clk_divisor_fast_mode = 0, 1648 + .clk_divisor_fast_plus_mode = 0, 1649 + .has_config_load_reg = false, 1650 + .has_multi_master_mode = false, 1651 + .has_slcg_override_reg = false, 1652 + .has_mst_fifo = false, 1653 + .has_mst_reset = false, 1654 + .quirks = &tegra_i2c_quirks, 1655 + .supports_bus_clear = false, 1656 + .has_apb_dma = true, 1657 + .tlow_std_mode = 0x4, 1658 + .thigh_std_mode = 0x2, 1659 + .tlow_fast_mode = 0x4, 1660 + .thigh_fast_mode = 0x2, 1661 + .tlow_fastplus_mode = 0x4, 1662 + .thigh_fastplus_mode = 0x2, 1663 + .setup_hold_time_std_mode = 0x0, 1664 + .setup_hold_time_fast_mode = 0x0, 1665 + .setup_hold_time_fastplus_mode = 0x0, 1666 + .setup_hold_time_hs_mode = 0x0, 1667 + .has_interface_timing_reg = false, 1668 + .enable_hs_mode_support = false, 1669 + .has_mutex = false, 1670 + .variant = TEGRA_I2C_VARIANT_DVC, 1671 + }; 1672 + #endif 1651 1673 1652 1674 static const struct tegra_i2c_hw_feature tegra30_i2c_hw = { 1653 1675 .has_continue_xfer_support = true, ··· 1711 1665 .has_interface_timing_reg = false, 1712 1666 .enable_hs_mode_support = false, 1713 1667 .has_mutex = false, 1668 + .variant = TEGRA_I2C_VARIANT_DEFAULT, 1714 1669 }; 1715 1670 1716 1671 static const struct tegra_i2c_hw_feature tegra114_i2c_hw = { ··· 1742 1695 .has_interface_timing_reg = false, 1743 1696 .enable_hs_mode_support = false, 1744 1697 .has_mutex = false, 1698 + .variant = TEGRA_I2C_VARIANT_DEFAULT, 1745 1699 }; 1746 1700 1747 1701 static const struct tegra_i2c_hw_feature tegra124_i2c_hw = { ··· 1773 1725 .has_interface_timing_reg = true, 1774 1726 .enable_hs_mode_support = false, 1775 1727 .has_mutex = false, 1728 + .variant = TEGRA_I2C_VARIANT_DEFAULT, 1776 1729 }; 1777 1730 1778 1731 static const struct tegra_i2c_hw_feature tegra210_i2c_hw = { ··· 1804 1755 .has_interface_timing_reg = true, 1805 1756 .enable_hs_mode_support = false, 1806 1757 .has_mutex = false, 1758 + .variant = TEGRA_I2C_VARIANT_DEFAULT, 1807 1759 }; 1760 + 1761 + #if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) 1762 + static const struct tegra_i2c_hw_feature tegra210_vi_i2c_hw = { 1763 + .has_continue_xfer_support = true, 1764 + .has_per_pkt_xfer_complete_irq = true, 1765 + .clk_divisor_hs_mode = 1, 1766 + .clk_divisor_std_mode = 0x19, 1767 + .clk_divisor_fast_mode = 0x19, 1768 + .clk_divisor_fast_plus_mode = 0x10, 1769 + .has_config_load_reg = true, 1770 + .has_multi_master_mode = false, 1771 + .has_slcg_override_reg = true, 1772 + .has_mst_fifo = false, 1773 + .has_mst_reset = false, 1774 + .quirks = &tegra_i2c_quirks, 1775 + .supports_bus_clear = true, 1776 + .has_apb_dma = true, 1777 + .tlow_std_mode = 0x4, 1778 + .thigh_std_mode = 0x2, 1779 + .tlow_fast_mode = 0x4, 1780 + .thigh_fast_mode = 0x2, 1781 + .tlow_fastplus_mode = 0x4, 1782 + .thigh_fastplus_mode = 0x2, 1783 + .setup_hold_time_std_mode = 0, 1784 + .setup_hold_time_fast_mode = 0, 1785 + .setup_hold_time_fastplus_mode = 0, 1786 + .setup_hold_time_hs_mode = 0, 1787 + .has_interface_timing_reg = true, 1788 + .enable_hs_mode_support = false, 1789 + .has_mutex = false, 1790 + .variant = TEGRA_I2C_VARIANT_VI, 1791 + }; 1792 + #endif 1808 1793 1809 1794 static const struct tegra_i2c_hw_feature tegra186_i2c_hw = { 1810 1795 .has_continue_xfer_support = true, ··· 1868 1785 .has_interface_timing_reg = true, 1869 1786 .enable_hs_mode_support = false, 1870 1787 .has_mutex = false, 1788 + .variant = TEGRA_I2C_VARIANT_DEFAULT, 1871 1789 }; 1872 1790 1873 1791 static const struct tegra_i2c_hw_feature tegra194_i2c_hw = { ··· 1901 1817 .has_interface_timing_reg = true, 1902 1818 .enable_hs_mode_support = true, 1903 1819 .has_mutex = false, 1820 + .variant = TEGRA_I2C_VARIANT_DEFAULT, 1904 1821 }; 1905 1822 1906 1823 static const struct tegra_i2c_hw_feature tegra256_i2c_hw = { ··· 1934 1849 .has_interface_timing_reg = true, 1935 1850 .enable_hs_mode_support = true, 1936 1851 .has_mutex = true, 1852 + .variant = TEGRA_I2C_VARIANT_DEFAULT, 1937 1853 }; 1938 1854 1939 1855 static const struct tegra_i2c_hw_feature tegra264_i2c_hw = { ··· 1967 1881 .has_interface_timing_reg = true, 1968 1882 .enable_hs_mode_support = true, 1969 1883 .has_mutex = true, 1884 + .variant = TEGRA_I2C_VARIANT_DEFAULT, 1970 1885 }; 1971 1886 1972 1887 static const struct of_device_id tegra_i2c_of_match[] = { ··· 1976 1889 { .compatible = "nvidia,tegra194-i2c", .data = &tegra194_i2c_hw, }, 1977 1890 { .compatible = "nvidia,tegra186-i2c", .data = &tegra186_i2c_hw, }, 1978 1891 #if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) 1979 - { .compatible = "nvidia,tegra210-i2c-vi", .data = &tegra210_i2c_hw, }, 1892 + { .compatible = "nvidia,tegra210-i2c-vi", .data = &tegra210_vi_i2c_hw, }, 1980 1893 #endif 1981 1894 { .compatible = "nvidia,tegra210-i2c", .data = &tegra210_i2c_hw, }, 1982 1895 { .compatible = "nvidia,tegra124-i2c", .data = &tegra124_i2c_hw, }, ··· 1984 1897 { .compatible = "nvidia,tegra30-i2c", .data = &tegra30_i2c_hw, }, 1985 1898 { .compatible = "nvidia,tegra20-i2c", .data = &tegra20_i2c_hw, }, 1986 1899 #if IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) 1987 - { .compatible = "nvidia,tegra20-i2c-dvc", .data = &tegra20_i2c_hw, }, 1900 + { .compatible = "nvidia,tegra20-i2c-dvc", .data = &tegra20_dvc_i2c_hw, }, 1988 1901 #endif 1989 1902 {}, 1990 1903 }; ··· 1992 1905 1993 1906 static void tegra_i2c_parse_dt(struct tegra_i2c_dev *i2c_dev) 1994 1907 { 1995 - struct device_node *np = i2c_dev->dev->of_node; 1996 1908 bool multi_mode; 1997 1909 1998 1910 i2c_parse_fw_timings(i2c_dev->dev, &i2c_dev->timings, true); 1999 1911 2000 1912 multi_mode = device_property_read_bool(i2c_dev->dev, "multi-master"); 2001 1913 i2c_dev->multimaster_mode = multi_mode; 2002 - 2003 - if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && 2004 - of_device_is_compatible(np, "nvidia,tegra20-i2c-dvc")) 2005 - i2c_dev->is_dvc = true; 2006 - 2007 - if (IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) && 2008 - of_device_is_compatible(np, "nvidia,tegra210-i2c-vi")) 2009 - i2c_dev->is_vi = true; 2010 1914 } 2011 1915 2012 1916 static int tegra_i2c_init_clocks(struct tegra_i2c_dev *i2c_dev)