|
1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | 2 |
|
| 3 | +#include <linux/bitfield.h> |
3 | 4 | #include <linux/delay.h> |
4 | 5 | #include <linux/clk-provider.h> |
5 | 6 | #include <linux/io.h> |
|
11 | 12 | #include <dt-bindings/clock/en7523-clk.h> |
12 | 13 | #include <dt-bindings/reset/airoha,en7523-reset.h> |
13 | 14 | #include <dt-bindings/reset/airoha,en7581-reset.h> |
| 15 | +#include <dt-bindings/clock/econet,en751221-scu.h> |
| 16 | +#include <dt-bindings/reset/econet,en751221-scu.h> |
14 | 17 |
|
15 | 18 | #define RST_NR_PER_BANK 32 |
16 | 19 |
|
|
33 | 36 | #define REG_RESET_CONTROL_PCIEHB BIT(29) |
34 | 37 | #define REG_RESET_CONTROL_PCIE1 BIT(27) |
35 | 38 | #define REG_RESET_CONTROL_PCIE2 BIT(26) |
| 39 | +#define REG_HIR 0x064 |
| 40 | +#define REG_HIR_MASK GENMASK(31, 16) |
36 | 41 | /* EN7581 */ |
37 | 42 | #define REG_NP_SCU_PCIC 0x88 |
38 | 43 | #define REG_NP_SCU_SSTR 0x9c |
39 | 44 | #define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13) |
40 | 45 | #define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11) |
41 | 46 | #define REG_CRYPTO_CLKSRC2 0x20c |
| 47 | +/* EN751221 */ |
| 48 | +#define EN751221_REG_SPI_DIV 0x0cc |
| 49 | +#define EN751221_REG_SPI_DIV_MASK GENMASK(31, 8) |
| 50 | +#define EN751221_SPI_BASE 500000000 |
| 51 | +#define EN751221_SPI_BASE_EN7526C 400000000 |
| 52 | +#define EN751221_SPI_DIV_DEFAULT 40 |
| 53 | +#define EN751221_REG_BUS 0x284 |
| 54 | +#define EN751221_REG_BUS_MASK GENMASK(21, 12) |
| 55 | +#define EN751221_REG_SSR3 0x094 |
| 56 | +#define EN751221_REG_SSR3_GSW_MASK GENMASK(9, 8) |
42 | 57 |
|
43 | 58 | #define REG_RST_CTRL2 0x830 |
44 | 59 | #define REG_RST_CTRL1 0x834 |
| 60 | +#define EN751221_REG_RST_DMT 0x84 |
| 61 | +#define EN751221_REG_RST_USB 0xec |
| 62 | + |
| 63 | +#define EN751221_MAX_CLKS 5 |
| 64 | + |
| 65 | +enum en_hir { |
| 66 | + HIR_UNKNOWN = -1, |
| 67 | + HIR_TC3169 = 0, |
| 68 | + HIR_TC3182 = 1, |
| 69 | + HIR_RT65168 = 2, |
| 70 | + HIR_RT63165 = 3, |
| 71 | + HIR_RT63365 = 4, |
| 72 | + HIR_MT751020 = 5, |
| 73 | + HIR_MT7505 = 6, |
| 74 | + HIR_EN751221 = 7, |
| 75 | + HIR_EN7526C = 8, |
| 76 | + HIR_EN751627 = 9, |
| 77 | + HIR_EN7580 = 10, |
| 78 | + HIR_EN7528 = 11, |
| 79 | + HIR_EN7523 = 12, |
| 80 | + HIR_EN7581 = 13, |
| 81 | + HIR_MAX = 14, |
| 82 | +}; |
45 | 83 |
|
46 | 84 | struct en_clk_desc { |
47 | 85 | int id; |
@@ -93,6 +131,8 @@ static const u32 bus7581_base[] = { 600000000, 540000000 }; |
93 | 131 | static const u32 npu7581_base[] = { 800000000, 750000000, 720000000, 600000000 }; |
94 | 132 | static const u32 crypto_base[] = { 540000000, 480000000 }; |
95 | 133 | static const u32 emmc7581_base[] = { 200000000, 150000000 }; |
| 134 | +/* EN751221 */ |
| 135 | +static const u32 gsw751221_base[] = { 500000000, 250000000, 400000000, 200000000 }; |
96 | 136 |
|
97 | 137 | static const struct en_clk_desc en7523_base_clks[] = { |
98 | 138 | { |
@@ -300,6 +340,13 @@ static const u16 en7581_rst_ofs[] = { |
300 | 340 | REG_RST_CTRL1, |
301 | 341 | }; |
302 | 342 |
|
| 343 | +static const u16 en751221_rst_ofs[] = { |
| 344 | + REG_RST_CTRL2, |
| 345 | + REG_RST_CTRL1, |
| 346 | + EN751221_REG_RST_DMT, |
| 347 | + EN751221_REG_RST_USB, |
| 348 | +}; |
| 349 | + |
303 | 350 | static const u16 en7523_rst_map[] = { |
304 | 351 | /* RST_CTRL2 */ |
305 | 352 | [EN7523_XPON_PHY_RST] = 0, |
@@ -405,8 +452,61 @@ static const u16 en7581_rst_map[] = { |
405 | 452 | [EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31, |
406 | 453 | }; |
407 | 454 |
|
| 455 | +static const u16 en751221_rst_map[] = { |
| 456 | + /* RST_CTRL2 */ |
| 457 | + [EN751221_XPON_PHY_RST] = 0, |
| 458 | + [EN751221_GFAST_RST] = 1, |
| 459 | + [EN751221_CPU_TIMER2_RST] = 2, |
| 460 | + [EN751221_UART3_RST] = 3, |
| 461 | + [EN751221_UART4_RST] = 4, |
| 462 | + [EN751221_UART5_RST] = 5, |
| 463 | + [EN751221_I2C2_RST] = 6, |
| 464 | + [EN751221_XSI_MAC_RST] = 7, |
| 465 | + [EN751221_XSI_PHY_RST] = 8, |
| 466 | + |
| 467 | + /* RST_CTRL1 */ |
| 468 | + [EN751221_PCM1_ZSI_ISI_RST] = RST_NR_PER_BANK + 0, |
| 469 | + [EN751221_FE_QDMA1_RST] = RST_NR_PER_BANK + 1, |
| 470 | + [EN751221_FE_QDMA2_RST] = RST_NR_PER_BANK + 2, |
| 471 | + [EN751221_FE_UNZIP_RST] = RST_NR_PER_BANK + 3, |
| 472 | + [EN751221_PCM2_RST] = RST_NR_PER_BANK + 4, |
| 473 | + [EN751221_PTM_MAC_RST] = RST_NR_PER_BANK + 5, |
| 474 | + [EN751221_CRYPTO_RST] = RST_NR_PER_BANK + 6, |
| 475 | + [EN751221_SAR_RST] = RST_NR_PER_BANK + 7, |
| 476 | + [EN751221_TIMER_RST] = RST_NR_PER_BANK + 8, |
| 477 | + [EN751221_INTC_RST] = RST_NR_PER_BANK + 9, |
| 478 | + [EN751221_BONDING_RST] = RST_NR_PER_BANK + 10, |
| 479 | + [EN751221_PCM1_RST] = RST_NR_PER_BANK + 11, |
| 480 | + [EN751221_UART_RST] = RST_NR_PER_BANK + 12, |
| 481 | + [EN751221_GPIO_RST] = RST_NR_PER_BANK + 13, |
| 482 | + [EN751221_GDMA_RST] = RST_NR_PER_BANK + 14, |
| 483 | + [EN751221_I2C_MASTER_RST] = RST_NR_PER_BANK + 16, |
| 484 | + [EN751221_PCM2_ZSI_ISI_RST] = RST_NR_PER_BANK + 17, |
| 485 | + [EN751221_SFC_RST] = RST_NR_PER_BANK + 18, |
| 486 | + [EN751221_UART2_RST] = RST_NR_PER_BANK + 19, |
| 487 | + [EN751221_GDMP_RST] = RST_NR_PER_BANK + 20, |
| 488 | + [EN751221_FE_RST] = RST_NR_PER_BANK + 21, |
| 489 | + [EN751221_USB_HOST_P0_RST] = RST_NR_PER_BANK + 22, |
| 490 | + [EN751221_GSW_RST] = RST_NR_PER_BANK + 23, |
| 491 | + [EN751221_SFC2_PCM_RST] = RST_NR_PER_BANK + 25, |
| 492 | + [EN751221_PCIE0_RST] = RST_NR_PER_BANK + 26, |
| 493 | + [EN751221_PCIE1_RST] = RST_NR_PER_BANK + 27, |
| 494 | + [EN751221_CPU_TIMER_RST] = RST_NR_PER_BANK + 28, |
| 495 | + [EN751221_PCIE_HB_RST] = RST_NR_PER_BANK + 29, |
| 496 | + [EN751221_SIMIF_RST] = RST_NR_PER_BANK + 30, |
| 497 | + [EN751221_XPON_MAC_RST] = RST_NR_PER_BANK + 31, |
| 498 | + |
| 499 | + /* RST_DMT */ |
| 500 | + [EN751221_DMT_RST] = 2 * RST_NR_PER_BANK + 0, |
| 501 | + |
| 502 | + /* RST_USB */ |
| 503 | + [EN751221_USB_PHY_P0_RST] = 3 * RST_NR_PER_BANK + 6, |
| 504 | + [EN751221_USB_PHY_P1_RST] = 3 * RST_NR_PER_BANK + 7, |
| 505 | +}; |
| 506 | + |
408 | 507 | static int en7581_reset_register(struct device *dev, void __iomem *base, |
409 | | - const u16 *rst_map, int nr_resets); |
| 508 | + const u16 *rst_map, int nr_resets, |
| 509 | + const u16 *rst_reg_ofs); |
410 | 510 |
|
411 | 511 | static u32 en7523_get_base_rate(const struct en_clk_desc *desc, u32 val) |
412 | 512 | { |
@@ -604,7 +704,8 @@ static int en7523_clk_hw_init(struct platform_device *pdev, |
604 | 704 | en7523_register_clocks(&pdev->dev, clk_data, base, np_base); |
605 | 705 |
|
606 | 706 | return en7581_reset_register(&pdev->dev, np_base, en7523_rst_map, |
607 | | - ARRAY_SIZE(en7523_rst_map)); |
| 707 | + ARRAY_SIZE(en7523_rst_map), |
| 708 | + en7581_rst_ofs); |
608 | 709 | } |
609 | 710 |
|
610 | 711 | static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, |
@@ -705,15 +806,16 @@ static const struct reset_control_ops en7581_reset_ops = { |
705 | 806 | }; |
706 | 807 |
|
707 | 808 | static int en7581_reset_register(struct device *dev, void __iomem *base, |
708 | | - const u16 *rst_map, int nr_resets) |
| 809 | + const u16 *rst_map, int nr_resets, |
| 810 | + const u16 *rst_reg_ofs) |
709 | 811 | { |
710 | 812 | struct en_rst_data *rst_data; |
711 | 813 |
|
712 | 814 | rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL); |
713 | 815 | if (!rst_data) |
714 | 816 | return -ENOMEM; |
715 | 817 |
|
716 | | - rst_data->bank_ofs = en7581_rst_ofs; |
| 818 | + rst_data->bank_ofs = rst_reg_ofs; |
717 | 819 | rst_data->idx_map = rst_map; |
718 | 820 | rst_data->base = base; |
719 | 821 |
|
@@ -752,7 +854,107 @@ static int en7581_clk_hw_init(struct platform_device *pdev, |
752 | 854 | writel(val | 3, base + REG_NP_SCU_PCIC); |
753 | 855 |
|
754 | 856 | return en7581_reset_register(&pdev->dev, base, en7581_rst_map, |
755 | | - ARRAY_SIZE(en7581_rst_map)); |
| 857 | + ARRAY_SIZE(en7581_rst_map), |
| 858 | + en7581_rst_ofs); |
| 859 | +} |
| 860 | + |
| 861 | +static enum en_hir get_hw_id(void __iomem *np_base) |
| 862 | +{ |
| 863 | + u32 val = FIELD_GET(REG_HIR_MASK, readl(np_base + REG_HIR)); |
| 864 | + |
| 865 | + if (val < HIR_MAX) |
| 866 | + return (enum en_hir)val; |
| 867 | + |
| 868 | + pr_warn("Unable to determine EcoNet SoC\n"); |
| 869 | + |
| 870 | + return HIR_UNKNOWN; |
| 871 | +} |
| 872 | + |
| 873 | +static void en751221_try_register_clk(struct device *dev, int key, |
| 874 | + struct clk_hw_onecell_data *clk_data, |
| 875 | + const char *name, u32 rate) |
| 876 | +{ |
| 877 | + struct clk_hw *hw; |
| 878 | + |
| 879 | + if (WARN_ON_ONCE(key >= EN751221_MAX_CLKS)) |
| 880 | + return; |
| 881 | + |
| 882 | + hw = clk_hw_register_fixed_rate(dev, name, NULL, 0, rate); |
| 883 | + if (IS_ERR(hw)) |
| 884 | + pr_err("Failed to register clk %s: %pe\n", name, hw); |
| 885 | + else |
| 886 | + clk_data->hws[key] = hw; |
| 887 | +} |
| 888 | + |
| 889 | +static void en751221_register_clocks(struct device *dev, |
| 890 | + struct clk_hw_onecell_data *clk_data, |
| 891 | + struct regmap *map, void __iomem *np_base) |
| 892 | +{ |
| 893 | + enum en_hir hid = get_hw_id(np_base); |
| 894 | + struct clk_hw *hw; |
| 895 | + u32 rate; |
| 896 | + u32 div; |
| 897 | + int err; |
| 898 | + |
| 899 | + /* PCI */ |
| 900 | + hw = en7523_register_pcie_clk(dev, np_base); |
| 901 | + clk_data->hws[EN751221_CLK_PCIE] = hw; |
| 902 | + |
| 903 | + /* SPI */ |
| 904 | + rate = EN751221_SPI_BASE; |
| 905 | + if (hid == HIR_EN7526C) |
| 906 | + rate = EN751221_SPI_BASE_EN7526C; |
| 907 | + |
| 908 | + err = regmap_read(map, EN751221_REG_SPI_DIV, &div); |
| 909 | + if (err) { |
| 910 | + pr_err("Failed reading fixed clk div %s: %d\n", |
| 911 | + "spi", err); |
| 912 | + } else { |
| 913 | + div = FIELD_GET(EN751221_REG_SPI_DIV_MASK, div) * 2; |
| 914 | + if (!div) |
| 915 | + div = EN751221_SPI_DIV_DEFAULT; |
| 916 | + |
| 917 | + en751221_try_register_clk(dev, EN751221_CLK_SPI, clk_data, |
| 918 | + "spi", rate / div); |
| 919 | + } |
| 920 | + |
| 921 | + /* BUS */ |
| 922 | + rate = FIELD_GET(EN751221_REG_BUS_MASK, |
| 923 | + readl(np_base + EN751221_REG_BUS)); |
| 924 | + rate *= 1000000; |
| 925 | + en751221_try_register_clk(dev, EN751221_CLK_BUS, clk_data, "bus", |
| 926 | + rate); |
| 927 | + |
| 928 | + /* CPU */ |
| 929 | + en751221_try_register_clk(dev, EN751221_CLK_CPU, clk_data, "cpu", |
| 930 | + rate * 4); |
| 931 | + |
| 932 | + /* GSW */ |
| 933 | + rate = FIELD_GET(EN751221_REG_SSR3_GSW_MASK, |
| 934 | + readl(np_base + EN751221_REG_SSR3)); |
| 935 | + en751221_try_register_clk(dev, EN751221_CLK_GSW, clk_data, "gsw", |
| 936 | + gsw751221_base[rate]); |
| 937 | +} |
| 938 | + |
| 939 | +static int en751221_clk_hw_init(struct platform_device *pdev, |
| 940 | + struct clk_hw_onecell_data *clk_data) |
| 941 | +{ |
| 942 | + struct regmap *map; |
| 943 | + void __iomem *base; |
| 944 | + |
| 945 | + map = syscon_regmap_lookup_by_compatible("econet,en751221-chip-scu"); |
| 946 | + if (IS_ERR(map)) |
| 947 | + return PTR_ERR(map); |
| 948 | + |
| 949 | + base = devm_platform_ioremap_resource(pdev, 0); |
| 950 | + if (IS_ERR(base)) |
| 951 | + return PTR_ERR(base); |
| 952 | + |
| 953 | + en751221_register_clocks(&pdev->dev, clk_data, map, base); |
| 954 | + |
| 955 | + return en7581_reset_register(&pdev->dev, base, en751221_rst_map, |
| 956 | + ARRAY_SIZE(en751221_rst_map), |
| 957 | + en751221_rst_ofs); |
756 | 958 | } |
757 | 959 |
|
758 | 960 | static int en7523_clk_probe(struct platform_device *pdev) |
@@ -799,9 +1001,20 @@ static const struct en_clk_soc_data en7581_data = { |
799 | 1001 | .hw_init = en7581_clk_hw_init, |
800 | 1002 | }; |
801 | 1003 |
|
| 1004 | +static const struct en_clk_soc_data en751221_data = { |
| 1005 | + .num_clocks = EN751221_MAX_CLKS, |
| 1006 | + .pcie_ops = { |
| 1007 | + .is_enabled = en7523_pci_is_enabled, |
| 1008 | + .prepare = en7523_pci_prepare, |
| 1009 | + .unprepare = en7523_pci_unprepare, |
| 1010 | + }, |
| 1011 | + .hw_init = en751221_clk_hw_init, |
| 1012 | +}; |
| 1013 | + |
802 | 1014 | static const struct of_device_id of_match_clk_en7523[] = { |
803 | 1015 | { .compatible = "airoha,en7523-scu", .data = &en7523_data }, |
804 | 1016 | { .compatible = "airoha,en7581-scu", .data = &en7581_data }, |
| 1017 | + { .compatible = "econet,en751221-scu", .data = &en751221_data }, |
805 | 1018 | { /* sentinel */ } |
806 | 1019 | }; |
807 | 1020 |
|
|
0 commit comments