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.

clk: airoha: Add econet EN751221 clock/reset support to en7523-scu

EcoNet EN751221 clock/reset driver is significantly similar to the
EN7523 / EN7581, however the EN751221 does not have a neat batch of clock
divider registers so there are fewer known clocks, and the frequency of
each clock is derived differently. This clock driver will probably work
correctly on EN751627, EN7528, and EN7580.

Signed-off-by: Caleb James DeLisle <cjd@cjdns.fr>
Reviewed-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>

authored by

Caleb James DeLisle and committed by
Stephen Boyd
d8b03452 35af99f7

+221 -8
+3 -3
drivers/clk/Kconfig
··· 218 218 If you say yes here you get support for the CS2000 clock multiplier. 219 219 220 220 config COMMON_CLK_EN7523 221 - bool "Clock driver for Airoha EN7523 SoC system clocks" 221 + bool "Clock driver for Airoha/EcoNet SoC system clocks" 222 222 depends on OF 223 - depends on ARCH_AIROHA || COMPILE_TEST 223 + depends on ARCH_AIROHA || ECONET || COMPILE_TEST 224 224 default ARCH_AIROHA 225 225 help 226 226 This driver provides the fixed clocks and gates present on Airoha 227 - ARM silicon. 227 + and EcoNet silicon. 228 228 229 229 config COMMON_CLK_EP93XX 230 230 tristate "Clock driver for Cirrus Logic ep93xx SoC"
+218 -5
drivers/clk/clk-en7523.c
··· 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> ··· 12 11 #include <dt-bindings/clock/en7523-clk.h> 13 12 #include <dt-bindings/reset/airoha,en7523-reset.h> 14 13 #include <dt-bindings/reset/airoha,en7581-reset.h> 14 + #include <dt-bindings/clock/econet,en751221-scu.h> 15 + #include <dt-bindings/reset/econet,en751221-scu.h> 15 16 16 17 #define RST_NR_PER_BANK 32 17 18 ··· 36 33 #define REG_RESET_CONTROL_PCIEHB BIT(29) 37 34 #define REG_RESET_CONTROL_PCIE1 BIT(27) 38 35 #define REG_RESET_CONTROL_PCIE2 BIT(26) 36 + #define REG_HIR 0x064 37 + #define REG_HIR_MASK GENMASK(31, 16) 39 38 /* EN7581 */ 40 39 #define REG_NP_SCU_PCIC 0x88 41 40 #define REG_NP_SCU_SSTR 0x9c 42 41 #define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13) 43 42 #define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11) 44 43 #define REG_CRYPTO_CLKSRC2 0x20c 44 + /* EN751221 */ 45 + #define EN751221_REG_SPI_DIV 0x0cc 46 + #define EN751221_REG_SPI_DIV_MASK GENMASK(31, 8) 47 + #define EN751221_SPI_BASE 500000000 48 + #define EN751221_SPI_BASE_EN7526C 400000000 49 + #define EN751221_SPI_DIV_DEFAULT 40 50 + #define EN751221_REG_BUS 0x284 51 + #define EN751221_REG_BUS_MASK GENMASK(21, 12) 52 + #define EN751221_REG_SSR3 0x094 53 + #define EN751221_REG_SSR3_GSW_MASK GENMASK(9, 8) 45 54 46 55 #define REG_RST_CTRL2 0x830 47 56 #define REG_RST_CTRL1 0x834 57 + #define EN751221_REG_RST_DMT 0x84 58 + #define EN751221_REG_RST_USB 0xec 59 + 60 + #define EN751221_MAX_CLKS 5 61 + 62 + enum en_hir { 63 + HIR_UNKNOWN = -1, 64 + HIR_TC3169 = 0, 65 + HIR_TC3182 = 1, 66 + HIR_RT65168 = 2, 67 + HIR_RT63165 = 3, 68 + HIR_RT63365 = 4, 69 + HIR_MT751020 = 5, 70 + HIR_MT7505 = 6, 71 + HIR_EN751221 = 7, 72 + HIR_EN7526C = 8, 73 + HIR_EN751627 = 9, 74 + HIR_EN7580 = 10, 75 + HIR_EN7528 = 11, 76 + HIR_EN7523 = 12, 77 + HIR_EN7581 = 13, 78 + HIR_MAX = 14, 79 + }; 48 80 49 81 struct en_clk_desc { 50 82 int id; ··· 131 93 static const u32 npu7581_base[] = { 800000000, 750000000, 720000000, 600000000 }; 132 94 static const u32 crypto_base[] = { 540000000, 480000000 }; 133 95 static const u32 emmc7581_base[] = { 200000000, 150000000 }; 96 + /* EN751221 */ 97 + static const u32 gsw751221_base[] = { 500000000, 250000000, 400000000, 200000000 }; 134 98 135 99 static const struct en_clk_desc en7523_base_clks[] = { 136 100 { ··· 340 300 REG_RST_CTRL1, 341 301 }; 342 302 303 + static const u16 en751221_rst_ofs[] = { 304 + REG_RST_CTRL2, 305 + REG_RST_CTRL1, 306 + EN751221_REG_RST_DMT, 307 + EN751221_REG_RST_USB, 308 + }; 309 + 343 310 static const u16 en7523_rst_map[] = { 344 311 /* RST_CTRL2 */ 345 312 [EN7523_XPON_PHY_RST] = 0, ··· 452 405 [EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31, 453 406 }; 454 407 408 + static const u16 en751221_rst_map[] = { 409 + /* RST_CTRL2 */ 410 + [EN751221_XPON_PHY_RST] = 0, 411 + [EN751221_GFAST_RST] = 1, 412 + [EN751221_CPU_TIMER2_RST] = 2, 413 + [EN751221_UART3_RST] = 3, 414 + [EN751221_UART4_RST] = 4, 415 + [EN751221_UART5_RST] = 5, 416 + [EN751221_I2C2_RST] = 6, 417 + [EN751221_XSI_MAC_RST] = 7, 418 + [EN751221_XSI_PHY_RST] = 8, 419 + 420 + /* RST_CTRL1 */ 421 + [EN751221_PCM1_ZSI_ISI_RST] = RST_NR_PER_BANK + 0, 422 + [EN751221_FE_QDMA1_RST] = RST_NR_PER_BANK + 1, 423 + [EN751221_FE_QDMA2_RST] = RST_NR_PER_BANK + 2, 424 + [EN751221_FE_UNZIP_RST] = RST_NR_PER_BANK + 3, 425 + [EN751221_PCM2_RST] = RST_NR_PER_BANK + 4, 426 + [EN751221_PTM_MAC_RST] = RST_NR_PER_BANK + 5, 427 + [EN751221_CRYPTO_RST] = RST_NR_PER_BANK + 6, 428 + [EN751221_SAR_RST] = RST_NR_PER_BANK + 7, 429 + [EN751221_TIMER_RST] = RST_NR_PER_BANK + 8, 430 + [EN751221_INTC_RST] = RST_NR_PER_BANK + 9, 431 + [EN751221_BONDING_RST] = RST_NR_PER_BANK + 10, 432 + [EN751221_PCM1_RST] = RST_NR_PER_BANK + 11, 433 + [EN751221_UART_RST] = RST_NR_PER_BANK + 12, 434 + [EN751221_GPIO_RST] = RST_NR_PER_BANK + 13, 435 + [EN751221_GDMA_RST] = RST_NR_PER_BANK + 14, 436 + [EN751221_I2C_MASTER_RST] = RST_NR_PER_BANK + 16, 437 + [EN751221_PCM2_ZSI_ISI_RST] = RST_NR_PER_BANK + 17, 438 + [EN751221_SFC_RST] = RST_NR_PER_BANK + 18, 439 + [EN751221_UART2_RST] = RST_NR_PER_BANK + 19, 440 + [EN751221_GDMP_RST] = RST_NR_PER_BANK + 20, 441 + [EN751221_FE_RST] = RST_NR_PER_BANK + 21, 442 + [EN751221_USB_HOST_P0_RST] = RST_NR_PER_BANK + 22, 443 + [EN751221_GSW_RST] = RST_NR_PER_BANK + 23, 444 + [EN751221_SFC2_PCM_RST] = RST_NR_PER_BANK + 25, 445 + [EN751221_PCIE0_RST] = RST_NR_PER_BANK + 26, 446 + [EN751221_PCIE1_RST] = RST_NR_PER_BANK + 27, 447 + [EN751221_CPU_TIMER_RST] = RST_NR_PER_BANK + 28, 448 + [EN751221_PCIE_HB_RST] = RST_NR_PER_BANK + 29, 449 + [EN751221_SIMIF_RST] = RST_NR_PER_BANK + 30, 450 + [EN751221_XPON_MAC_RST] = RST_NR_PER_BANK + 31, 451 + 452 + /* RST_DMT */ 453 + [EN751221_DMT_RST] = 2 * RST_NR_PER_BANK + 0, 454 + 455 + /* RST_USB */ 456 + [EN751221_USB_PHY_P0_RST] = 3 * RST_NR_PER_BANK + 6, 457 + [EN751221_USB_PHY_P1_RST] = 3 * RST_NR_PER_BANK + 7, 458 + }; 459 + 455 460 static int en7581_reset_register(struct device *dev, void __iomem *base, 456 - const u16 *rst_map, int nr_resets); 461 + const u16 *rst_map, int nr_resets, 462 + const u16 *rst_reg_ofs); 457 463 458 464 static u32 en7523_get_base_rate(const struct en_clk_desc *desc, u32 val) 459 465 { ··· 704 604 en7523_register_clocks(&pdev->dev, clk_data, base, np_base); 705 605 706 606 return en7581_reset_register(&pdev->dev, np_base, en7523_rst_map, 707 - ARRAY_SIZE(en7523_rst_map)); 607 + ARRAY_SIZE(en7523_rst_map), 608 + en7581_rst_ofs); 708 609 } 709 610 710 611 static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, ··· 806 705 }; 807 706 808 707 static int en7581_reset_register(struct device *dev, void __iomem *base, 809 - const u16 *rst_map, int nr_resets) 708 + const u16 *rst_map, int nr_resets, 709 + const u16 *rst_reg_ofs) 810 710 { 811 711 struct en_rst_data *rst_data; 812 712 ··· 815 713 if (!rst_data) 816 714 return -ENOMEM; 817 715 818 - rst_data->bank_ofs = en7581_rst_ofs; 716 + rst_data->bank_ofs = rst_reg_ofs; 819 717 rst_data->idx_map = rst_map; 820 718 rst_data->base = base; 821 719 ··· 854 752 writel(val | 3, base + REG_NP_SCU_PCIC); 855 753 856 754 return en7581_reset_register(&pdev->dev, base, en7581_rst_map, 857 - ARRAY_SIZE(en7581_rst_map)); 755 + ARRAY_SIZE(en7581_rst_map), 756 + en7581_rst_ofs); 757 + } 758 + 759 + static enum en_hir get_hw_id(void __iomem *np_base) 760 + { 761 + u32 val = FIELD_GET(REG_HIR_MASK, readl(np_base + REG_HIR)); 762 + 763 + if (val < HIR_MAX) 764 + return (enum en_hir)val; 765 + 766 + pr_warn("Unable to determine EcoNet SoC\n"); 767 + 768 + return HIR_UNKNOWN; 769 + } 770 + 771 + static void en751221_try_register_clk(struct device *dev, int key, 772 + struct clk_hw_onecell_data *clk_data, 773 + const char *name, u32 rate) 774 + { 775 + struct clk_hw *hw; 776 + 777 + if (WARN_ON_ONCE(key >= EN751221_MAX_CLKS)) 778 + return; 779 + 780 + hw = clk_hw_register_fixed_rate(dev, name, NULL, 0, rate); 781 + if (IS_ERR(hw)) 782 + pr_err("Failed to register clk %s: %pe\n", name, hw); 783 + else 784 + clk_data->hws[key] = hw; 785 + } 786 + 787 + static void en751221_register_clocks(struct device *dev, 788 + struct clk_hw_onecell_data *clk_data, 789 + struct regmap *map, void __iomem *np_base) 790 + { 791 + enum en_hir hid = get_hw_id(np_base); 792 + struct clk_hw *hw; 793 + u32 rate; 794 + u32 div; 795 + int err; 796 + 797 + /* PCI */ 798 + hw = en7523_register_pcie_clk(dev, np_base); 799 + clk_data->hws[EN751221_CLK_PCIE] = hw; 800 + 801 + /* SPI */ 802 + rate = EN751221_SPI_BASE; 803 + if (hid == HIR_EN7526C) 804 + rate = EN751221_SPI_BASE_EN7526C; 805 + 806 + err = regmap_read(map, EN751221_REG_SPI_DIV, &div); 807 + if (err) { 808 + pr_err("Failed reading fixed clk div %s: %d\n", 809 + "spi", err); 810 + } else { 811 + div = FIELD_GET(EN751221_REG_SPI_DIV_MASK, div) * 2; 812 + if (!div) 813 + div = EN751221_SPI_DIV_DEFAULT; 814 + 815 + en751221_try_register_clk(dev, EN751221_CLK_SPI, clk_data, 816 + "spi", rate / div); 817 + } 818 + 819 + /* BUS */ 820 + rate = FIELD_GET(EN751221_REG_BUS_MASK, 821 + readl(np_base + EN751221_REG_BUS)); 822 + rate *= 1000000; 823 + en751221_try_register_clk(dev, EN751221_CLK_BUS, clk_data, "bus", 824 + rate); 825 + 826 + /* CPU */ 827 + en751221_try_register_clk(dev, EN751221_CLK_CPU, clk_data, "cpu", 828 + rate * 4); 829 + 830 + /* GSW */ 831 + rate = FIELD_GET(EN751221_REG_SSR3_GSW_MASK, 832 + readl(np_base + EN751221_REG_SSR3)); 833 + en751221_try_register_clk(dev, EN751221_CLK_GSW, clk_data, "gsw", 834 + gsw751221_base[rate]); 835 + } 836 + 837 + static int en751221_clk_hw_init(struct platform_device *pdev, 838 + struct clk_hw_onecell_data *clk_data) 839 + { 840 + struct regmap *map; 841 + void __iomem *base; 842 + 843 + map = syscon_regmap_lookup_by_compatible("econet,en751221-chip-scu"); 844 + if (IS_ERR(map)) 845 + return PTR_ERR(map); 846 + 847 + base = devm_platform_ioremap_resource(pdev, 0); 848 + if (IS_ERR(base)) 849 + return PTR_ERR(base); 850 + 851 + en751221_register_clocks(&pdev->dev, clk_data, map, base); 852 + 853 + return en7581_reset_register(&pdev->dev, base, en751221_rst_map, 854 + ARRAY_SIZE(en751221_rst_map), 855 + en751221_rst_ofs); 858 856 } 859 857 860 858 static int en7523_clk_probe(struct platform_device *pdev) ··· 1001 799 .hw_init = en7581_clk_hw_init, 1002 800 }; 1003 801 802 + static const struct en_clk_soc_data en751221_data = { 803 + .num_clocks = EN751221_MAX_CLKS, 804 + .pcie_ops = { 805 + .is_enabled = en7523_pci_is_enabled, 806 + .prepare = en7523_pci_prepare, 807 + .unprepare = en7523_pci_unprepare, 808 + }, 809 + .hw_init = en751221_clk_hw_init, 810 + }; 811 + 1004 812 static const struct of_device_id of_match_clk_en7523[] = { 1005 813 { .compatible = "airoha,en7523-scu", .data = &en7523_data }, 1006 814 { .compatible = "airoha,en7581-scu", .data = &en7581_data }, 815 + { .compatible = "econet,en751221-scu", .data = &en751221_data }, 1007 816 { /* sentinel */ } 1008 817 }; 1009 818