diff options
58 files changed, 2617 insertions, 333 deletions
diff --git a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml index 84353fd09428..fe2c5c1baf43 100644 --- a/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml +++ b/Documentation/devicetree/bindings/clock/airoha,en7523-scu.yaml @@ -34,8 +34,10 @@ properties: - airoha,en7581-scu reg: - minItems: 2 - maxItems: 4 + items: + - description: scu base address + - description: misc scu base address + minItems: 1 "#clock-cells": description: @@ -60,9 +62,7 @@ allOf: then: properties: reg: - items: - - description: scu base address - - description: misc scu base address + minItems: 2 '#reset-cells': false @@ -73,11 +73,7 @@ allOf: then: properties: reg: - items: - - description: scu base address - - description: misc scu base address - - description: reset base address - - description: pb scu base address + maxItems: 1 additionalProperties: false @@ -96,12 +92,9 @@ examples: #address-cells = <2>; #size-cells = <2>; - scuclk: clock-controller@1fa20000 { + scuclk: clock-controller@1fb00000 { compatible = "airoha,en7581-scu"; - reg = <0x0 0x1fa20000 0x0 0x400>, - <0x0 0x1fb00000 0x0 0x90>, - <0x0 0x1fb00830 0x0 0x8>, - <0x0 0x1fbe3400 0x0 0xfc>; + reg = <0x0 0x1fb00000 0x0 0x970>; #clock-cells = <1>; #reset-cells = <1>; }; diff --git a/Documentation/devicetree/bindings/clock/gated-fixed-clock.yaml b/Documentation/devicetree/bindings/clock/gated-fixed-clock.yaml new file mode 100644 index 000000000000..d3e0faf3c64d --- /dev/null +++ b/Documentation/devicetree/bindings/clock/gated-fixed-clock.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/gated-fixed-clock.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Gated Fixed clock + +maintainers: + - Heiko Stuebner <heiko@sntech.de> + +properties: + compatible: + const: gated-fixed-clock + + "#clock-cells": + const: 0 + + clock-frequency: true + + clock-output-names: + maxItems: 1 + + enable-gpios: + description: + Contains a single GPIO specifier for the GPIO that enables and disables + the oscillator. + maxItems: 1 + + vdd-supply: + description: handle of the regulator that provides the supply voltage + +required: + - compatible + - "#clock-cells" + - clock-frequency + - vdd-supply + +additionalProperties: false + +examples: + - | + clock-1000000000 { + compatible = "gated-fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000000>; + vdd-supply = <®_vdd>; + }; +... diff --git a/Documentation/devicetree/bindings/clock/mediatek,apmixedsys.yaml b/Documentation/devicetree/bindings/clock/mediatek,apmixedsys.yaml index db5f48e4dd15..591a9e862c7d 100644 --- a/Documentation/devicetree/bindings/clock/mediatek,apmixedsys.yaml +++ b/Documentation/devicetree/bindings/clock/mediatek,apmixedsys.yaml @@ -12,7 +12,8 @@ maintainers: description: The Mediatek apmixedsys controller provides PLLs to the system. - The clock values can be found in <dt-bindings/clock/mt*-clk.h>. + The clock values can be found in <dt-bindings/clock/mt*-clk.h> + and <dt-bindings/clock/mediatek,mt*-apmixedsys.h>. properties: compatible: @@ -34,6 +35,7 @@ properties: - enum: - mediatek,mt2701-apmixedsys - mediatek,mt2712-apmixedsys + - mediatek,mt6735-apmixedsys - mediatek,mt6765-apmixedsys - mediatek,mt6779-apmixed - mediatek,mt6795-apmixedsys diff --git a/Documentation/devicetree/bindings/clock/mediatek,infracfg.yaml b/Documentation/devicetree/bindings/clock/mediatek,infracfg.yaml index 252c46d316ee..d1d30700d9b0 100644 --- a/Documentation/devicetree/bindings/clock/mediatek,infracfg.yaml +++ b/Documentation/devicetree/bindings/clock/mediatek,infracfg.yaml @@ -11,9 +11,10 @@ maintainers: description: The Mediatek infracfg controller provides various clocks and reset outputs - to the system. The clock values can be found in <dt-bindings/clock/mt*-clk.h>, - and reset values in <dt-bindings/reset/mt*-reset.h> and - <dt-bindings/reset/mt*-resets.h>. + to the system. The clock values can be found in <dt-bindings/clock/mt*-clk.h> + and <dt-bindings/clock/mediatek,mt*-infracfg.h>, and reset values in + <dt-bindings/reset/mt*-reset.h>, <dt-bindings/reset/mt*-resets.h> and + <dt-bindings/reset/mediatek,mt*-infracfg.h>. properties: compatible: @@ -22,6 +23,7 @@ properties: - enum: - mediatek,mt2701-infracfg - mediatek,mt2712-infracfg + - mediatek,mt6735-infracfg - mediatek,mt6765-infracfg - mediatek,mt6795-infracfg - mediatek,mt6779-infracfg_ao diff --git a/Documentation/devicetree/bindings/clock/mediatek,pericfg.yaml b/Documentation/devicetree/bindings/clock/mediatek,pericfg.yaml index 2f06baecfd23..b98cf45efe2f 100644 --- a/Documentation/devicetree/bindings/clock/mediatek,pericfg.yaml +++ b/Documentation/devicetree/bindings/clock/mediatek,pericfg.yaml @@ -20,6 +20,7 @@ properties: - enum: - mediatek,mt2701-pericfg - mediatek,mt2712-pericfg + - mediatek,mt6735-pericfg - mediatek,mt6765-pericfg - mediatek,mt6795-pericfg - mediatek,mt7622-pericfg diff --git a/Documentation/devicetree/bindings/clock/mediatek,syscon.yaml b/Documentation/devicetree/bindings/clock/mediatek,syscon.yaml index 10483e26878f..a86a64893c67 100644 --- a/Documentation/devicetree/bindings/clock/mediatek,syscon.yaml +++ b/Documentation/devicetree/bindings/clock/mediatek,syscon.yaml @@ -28,6 +28,10 @@ properties: - mediatek,mt2712-mfgcfg - mediatek,mt2712-vdecsys - mediatek,mt2712-vencsys + - mediatek,mt6735-imgsys + - mediatek,mt6735-mfgcfg + - mediatek,mt6735-vdecsys + - mediatek,mt6735-vencsys - mediatek,mt6765-camsys - mediatek,mt6765-imgsys - mediatek,mt6765-mipi0a diff --git a/Documentation/devicetree/bindings/clock/mediatek,topckgen.yaml b/Documentation/devicetree/bindings/clock/mediatek,topckgen.yaml index bdf3b55bd56f..c080fb0a1618 100644 --- a/Documentation/devicetree/bindings/clock/mediatek,topckgen.yaml +++ b/Documentation/devicetree/bindings/clock/mediatek,topckgen.yaml @@ -12,7 +12,8 @@ maintainers: description: The Mediatek topckgen controller provides various clocks to the system. - The clock values can be found in <dt-bindings/clock/mt*-clk.h>. + The clock values can be found in <dt-bindings/clock/mt*-clk.h> and + <dt-bindings/clock/mediatek,mt*-topckgen.h>. properties: compatible: @@ -31,6 +32,7 @@ properties: - enum: - mediatek,mt2701-topckgen - mediatek,mt2712-topckgen + - mediatek,mt6735-topckgen - mediatek,mt6765-topckgen - mediatek,mt6779-topckgen - mediatek,mt6795-topckgen diff --git a/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml index 9d5324dc1027..b44a76a958f4 100644 --- a/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml +++ b/Documentation/devicetree/bindings/clock/xlnx,clocking-wizard.yaml @@ -39,6 +39,11 @@ properties: - const: clk_in1 - const: s_axi_aclk + xlnx,static-config: + $ref: /schemas/types.yaml#/definitions/flag + description: + Indicate whether the core has been configured without support for dynamic + runtime reconfguration of the clocking primitive MMCM/PLL. xlnx,speed-grade: $ref: /schemas/types.yaml#/definitions/uint32 @@ -70,6 +75,7 @@ examples: compatible = "xlnx,clocking-wizard"; reg = <0xb0000000 0x10000>; #clock-cells = <1>; + xlnx,static-config; xlnx,speed-grade = <1>; xlnx,nr-outputs = <6>; clock-names = "clk_in1", "s_axi_aclk"; diff --git a/MAINTAINERS b/MAINTAINERS index c27f3190737f..262b23805ab3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14528,6 +14528,32 @@ S: Maintained F: Documentation/devicetree/bindings/mmc/mtk-sd.yaml F: drivers/mmc/host/mtk-sd.c +MEDIATEK MT6735 CLOCK & RESET DRIVERS +M: Yassine Oudjana <y.oudjana@protonmail.com> +L: linux-clk@vger.kernel.org +L: linux-mediatek@lists.infradead.org (moderated for non-subscribers) +S: Maintained +F: drivers/clk/mediatek/clk-mt6735-apmixedsys.c +F: drivers/clk/mediatek/clk-mt6735-imgsys.c +F: drivers/clk/mediatek/clk-mt6735-infracfg.c +F: drivers/clk/mediatek/clk-mt6735-mfgcfg.c +F: drivers/clk/mediatek/clk-mt6735-pericfg.c +F: drivers/clk/mediatek/clk-mt6735-topckgen.c +F: drivers/clk/mediatek/clk-mt6735-vdecsys.c +F: drivers/clk/mediatek/clk-mt6735-vencsys.c +F: include/dt-bindings/clock/mediatek,mt6735-apmixedsys.h +F: include/dt-bindings/clock/mediatek,mt6735-imgsys.h +F: include/dt-bindings/clock/mediatek,mt6735-infracfg.h +F: include/dt-bindings/clock/mediatek,mt6735-mfgcfg.h +F: include/dt-bindings/clock/mediatek,mt6735-pericfg.h +F: include/dt-bindings/clock/mediatek,mt6735-topckgen.h +F: include/dt-bindings/clock/mediatek,mt6735-vdecsys.h +F: include/dt-bindings/clock/mediatek,mt6735-vencsys.h +F: include/dt-bindings/reset/mediatek,mt6735-infracfg.h +F: include/dt-bindings/reset/mediatek,mt6735-mfgcfg.h +F: include/dt-bindings/reset/mediatek,mt6735-pericfg.h +F: include/dt-bindings/reset/mediatek,mt6735-vdecsys.h + MEDIATEK MT76 WIRELESS LAN DRIVER M: Felix Fietkau <nbd@nbd.name> M: Lorenzo Bianconi <lorenzo@kernel.org> diff --git a/drivers/clk/.kunitconfig b/drivers/clk/.kunitconfig index 54ece9207055..08e26137f3d9 100644 --- a/drivers/clk/.kunitconfig +++ b/drivers/clk/.kunitconfig @@ -1,5 +1,6 @@ CONFIG_KUNIT=y CONFIG_OF=y +CONFIG_OF_OVERLAY=y CONFIG_COMMON_CLK=y CONFIG_CLK_KUNIT_TEST=y CONFIG_CLK_FIXED_RATE_KUNIT_TEST=y diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index d61966cdd3ea..84f46b4045b7 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -517,7 +517,6 @@ config CLK_KUNIT_TEST tristate "Basic Clock Framework Kunit Tests" if !KUNIT_ALL_TESTS depends on KUNIT default KUNIT_ALL_TESTS - select OF_OVERLAY if OF select DTC help Kunit tests for the common clock framework. @@ -526,7 +525,6 @@ config CLK_FIXED_RATE_KUNIT_TEST tristate "Basic fixed rate clk type KUnit test" if !KUNIT_ALL_TESTS depends on KUNIT default KUNIT_ALL_TESTS - select OF_OVERLAY if OF select DTC help KUnit tests for the basic fixed rate clk type. diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index fb8878a5d7d9..35c70149259a 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -4,6 +4,20 @@ obj-$(CONFIG_HAVE_CLK) += clk-devres.o clk-bulk.o clkdev.o obj-$(CONFIG_COMMON_CLK) += clk.o obj-$(CONFIG_CLK_KUNIT_TEST) += clk-test.o clk-test-y := clk_test.o \ + kunit_clk_assigned_rates_u64_one.dtbo.o \ + kunit_clk_assigned_rates_u64_one_consumer.dtbo.o \ + kunit_clk_assigned_rates_u64_multiple.dtbo.o \ + kunit_clk_assigned_rates_u64_multiple_consumer.dtbo.o \ + kunit_clk_assigned_rates_multiple.dtbo.o \ + kunit_clk_assigned_rates_multiple_consumer.dtbo.o \ + kunit_clk_assigned_rates_null.dtbo.o \ + kunit_clk_assigned_rates_null_consumer.dtbo.o \ + kunit_clk_assigned_rates_one.dtbo.o \ + kunit_clk_assigned_rates_one_consumer.dtbo.o \ + kunit_clk_assigned_rates_without.dtbo.o \ + kunit_clk_assigned_rates_without_consumer.dtbo.o \ + kunit_clk_assigned_rates_zero.dtbo.o \ + kunit_clk_assigned_rates_zero_consumer.dtbo.o \ kunit_clk_parent_data_test.dtbo.o obj-$(CONFIG_COMMON_CLK) += clk-divider.o obj-$(CONFIG_COMMON_CLK) += clk-fixed-factor.o diff --git a/drivers/clk/clk-en7523.c b/drivers/clk/clk-en7523.c index 22fbea61c3dc..e52c5460e927 100644 --- a/drivers/clk/clk-en7523.c +++ b/drivers/clk/clk-en7523.c @@ -3,8 +3,10 @@ #include <linux/delay.h> #include <linux/clk-provider.h> #include <linux/io.h> +#include <linux/mfd/syscon.h> #include <linux/platform_device.h> #include <linux/property.h> +#include <linux/regmap.h> #include <linux/reset-controller.h> #include <dt-bindings/clock/en7523-clk.h> #include <dt-bindings/reset/airoha,en7581-reset.h> @@ -31,19 +33,14 @@ #define REG_RESET_CONTROL_PCIE1 BIT(27) #define REG_RESET_CONTROL_PCIE2 BIT(26) /* EN7581 */ -#define REG_PCIE0_MEM 0x00 -#define REG_PCIE0_MEM_MASK 0x04 -#define REG_PCIE1_MEM 0x08 -#define REG_PCIE1_MEM_MASK 0x0c -#define REG_PCIE2_MEM 0x10 -#define REG_PCIE2_MEM_MASK 0x14 #define REG_NP_SCU_PCIC 0x88 #define REG_NP_SCU_SSTR 0x9c #define REG_PCIE_XSI0_SEL_MASK GENMASK(14, 13) #define REG_PCIE_XSI1_SEL_MASK GENMASK(12, 11) +#define REG_CRYPTO_CLKSRC2 0x20c -#define REG_RST_CTRL2 0x00 -#define REG_RST_CTRL1 0x04 +#define REG_RST_CTRL2 0x830 +#define REG_RST_CTRL1 0x834 struct en_clk_desc { int id; @@ -79,12 +76,8 @@ struct en_rst_data { struct en_clk_soc_data { const struct clk_ops pcie_ops; - struct { - const u16 *bank_ofs; - const u16 *idx_map; - u16 idx_map_nr; - } reset; - int (*hw_init)(struct platform_device *pdev, void __iomem *np_base); + int (*hw_init)(struct platform_device *pdev, + struct clk_hw_onecell_data *clk_data); }; static const u32 gsw_base[] = { 400000000, 500000000 }; @@ -92,6 +85,10 @@ static const u32 emi_base[] = { 333000000, 400000000 }; static const u32 bus_base[] = { 500000000, 540000000 }; static const u32 slic_base[] = { 100000000, 3125000 }; static const u32 npu_base[] = { 333000000, 400000000, 500000000 }; +/* EN7581 */ +static const u32 emi7581_base[] = { 540000000, 480000000, 400000000, 300000000 }; +static const u32 npu7581_base[] = { 800000000, 750000000, 720000000, 600000000 }; +static const u32 crypto_base[] = { 540000000, 480000000 }; static const struct en_clk_desc en7523_base_clks[] = { { @@ -189,6 +186,102 @@ static const struct en_clk_desc en7523_base_clks[] = { } }; +static const struct en_clk_desc en7581_base_clks[] = { + { + .id = EN7523_CLK_GSW, + .name = "gsw", + + .base_reg = REG_GSW_CLK_DIV_SEL, + .base_bits = 1, + .base_shift = 8, + .base_values = gsw_base, + .n_base_values = ARRAY_SIZE(gsw_base), + + .div_bits = 3, + .div_shift = 0, + .div_step = 1, + .div_offset = 1, + }, { + .id = EN7523_CLK_EMI, + .name = "emi", + + .base_reg = REG_EMI_CLK_DIV_SEL, + .base_bits = 2, + .base_shift = 8, + .base_values = emi7581_base, + .n_base_values = ARRAY_SIZE(emi7581_base), + + .div_bits = 3, + .div_shift = 0, + .div_step = 1, + .div_offset = 1, + }, { + .id = EN7523_CLK_BUS, + .name = "bus", + + .base_reg = REG_BUS_CLK_DIV_SEL, + .base_bits = 1, + .base_shift = 8, + .base_values = bus_base, + .n_base_values = ARRAY_SIZE(bus_base), + + .div_bits = 3, + .div_shift = 0, + .div_step = 1, + .div_offset = 1, + }, { + .id = EN7523_CLK_SLIC, + .name = "slic", + + .base_reg = REG_SPI_CLK_FREQ_SEL, + .base_bits = 1, + .base_shift = 0, + .base_values = slic_base, + .n_base_values = ARRAY_SIZE(slic_base), + + .div_reg = REG_SPI_CLK_DIV_SEL, + .div_bits = 5, + .div_shift = 24, + .div_val0 = 20, + .div_step = 2, + }, { + .id = EN7523_CLK_SPI, + .name = "spi", + + .base_reg = REG_SPI_CLK_DIV_SEL, + + .base_value = 400000000, + + .div_bits = 5, + .div_shift = 8, + .div_val0 = 40, + .div_step = 2, + }, { + .id = EN7523_CLK_NPU, + .name = "npu", + + .base_reg = REG_NPU_CLK_DIV_SEL, + .base_bits = 2, + .base_shift = 8, + .base_values = npu7581_base, + .n_base_values = ARRAY_SIZE(npu7581_base), + + .div_bits = 3, + .div_shift = 0, + .div_step = 1, + .div_offset = 1, + }, { + .id = EN7523_CLK_CRYPTO, + .name = "crypto", + + .base_reg = REG_CRYPTO_CLKSRC2, + .base_bits = 1, + .base_shift = 0, + .base_values = crypto_base, + .n_base_values = ARRAY_SIZE(crypto_base), + } +}; + static const u16 en7581_rst_ofs[] = { REG_RST_CTRL2, REG_RST_CTRL1, @@ -252,15 +345,11 @@ static const u16 en7581_rst_map[] = { [EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31, }; -static unsigned int en7523_get_base_rate(void __iomem *base, unsigned int i) +static u32 en7523_get_base_rate(const struct en_clk_desc *desc, u32 val) { - const struct en_clk_desc *desc = &en7523_base_clks[i]; - u32 val; - if (!desc->base_bits) return desc->base_value; - val = readl(base + desc->base_reg); val >>= desc->base_shift; val &= (1 << desc->base_bits) - 1; @@ -270,16 +359,11 @@ static unsigned int en7523_get_base_rate(void __iomem *base, unsigned int i) return desc->base_values[val]; } -static u32 en7523_get_div(void __iomem *base, int i) +static u32 en7523_get_div(const struct en_clk_desc *desc, u32 val) { - const struct en_clk_desc *desc = &en7523_base_clks[i]; - u32 reg, val; - if (!desc->div_bits) return 1; - reg = desc->div_reg ? desc->div_reg : desc->base_reg; - val = readl(base + reg); val >>= desc->div_shift; val &= (1 << desc->div_bits) - 1; @@ -412,44 +496,83 @@ static void en7581_pci_disable(struct clk_hw *hw) usleep_range(1000, 2000); } -static int en7581_clk_hw_init(struct platform_device *pdev, - void __iomem *np_base) +static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, + void __iomem *base, void __iomem *np_base) { - void __iomem *pb_base; - u32 val; + struct clk_hw *hw; + u32 rate; + int i; + + for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) { + const struct en_clk_desc *desc = &en7523_base_clks[i]; + u32 reg = desc->div_reg ? desc->div_reg : desc->base_reg; + u32 val = readl(base + desc->base_reg); - pb_base = devm_platform_ioremap_resource(pdev, 3); - if (IS_ERR(pb_base)) - return PTR_ERR(pb_base); + rate = en7523_get_base_rate(desc, val); + val = readl(base + reg); + rate /= en7523_get_div(desc, val); - val = readl(np_base + REG_NP_SCU_SSTR); - val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); - writel(val, np_base + REG_NP_SCU_SSTR); - val = readl(np_base + REG_NP_SCU_PCIC); - writel(val | 3, np_base + REG_NP_SCU_PCIC); + hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate); + if (IS_ERR(hw)) { + pr_err("Failed to register clk %s: %ld\n", + desc->name, PTR_ERR(hw)); + continue; + } + + clk_data->hws[desc->id] = hw; + } + + hw = en7523_register_pcie_clk(dev, np_base); + clk_data->hws[EN7523_CLK_PCIE] = hw; + + clk_data->num = EN7523_NUM_CLOCKS; +} + +static int en7523_clk_hw_init(struct platform_device *pdev, + struct clk_hw_onecell_data *clk_data) +{ + void __iomem *base, *np_base; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); - writel(0x20000000, pb_base + REG_PCIE0_MEM); - writel(0xfc000000, pb_base + REG_PCIE0_MEM_MASK); - writel(0x24000000, pb_base + REG_PCIE1_MEM); - writel(0xfc000000, pb_base + REG_PCIE1_MEM_MASK); - writel(0x28000000, pb_base + REG_PCIE2_MEM); - writel(0xfc000000, pb_base + REG_PCIE2_MEM_MASK); + np_base = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(np_base)) + return PTR_ERR(np_base); + + en7523_register_clocks(&pdev->dev, clk_data, base, np_base); return 0; } -static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, - void __iomem *base, void __iomem *np_base) +static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, + struct regmap *map, void __iomem *base) { struct clk_hw *hw; u32 rate; int i; - for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) { - const struct en_clk_desc *desc = &en7523_base_clks[i]; + for (i = 0; i < ARRAY_SIZE(en7581_base_clks); i++) { + const struct en_clk_desc *desc = &en7581_base_clks[i]; + u32 val, reg = desc->div_reg ? desc->div_reg : desc->base_reg; + int err; + + err = regmap_read(map, desc->base_reg, &val); + if (err) { + pr_err("Failed reading fixed clk rate %s: %d\n", + desc->name, err); + continue; + } + rate = en7523_get_base_rate(desc, val); - rate = en7523_get_base_rate(base, i); - rate /= en7523_get_div(base, i); + err = regmap_read(map, reg, &val); + if (err) { + pr_err("Failed reading fixed clk div %s: %d\n", + desc->name, err); + continue; + } + rate /= en7523_get_div(desc, val); hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate); if (IS_ERR(hw)) { @@ -461,7 +584,7 @@ static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_dat clk_data->hws[desc->id] = hw; } - hw = en7523_register_pcie_clk(dev, np_base); + hw = en7523_register_pcie_clk(dev, base); clk_data->hws[EN7523_CLK_PCIE] = hw; clk_data->num = EN7523_NUM_CLOCKS; @@ -516,38 +639,27 @@ static int en7523_reset_xlate(struct reset_controller_dev *rcdev, return rst_data->idx_map[reset_spec->args[0]]; } -static const struct reset_control_ops en7523_reset_ops = { +static const struct reset_control_ops en7581_reset_ops = { .assert = en7523_reset_assert, .deassert = en7523_reset_deassert, .status = en7523_reset_status, }; -static int en7523_reset_register(struct platform_device *pdev, - const struct en_clk_soc_data *soc_data) +static int en7581_reset_register(struct device *dev, void __iomem *base) { - struct device *dev = &pdev->dev; struct en_rst_data *rst_data; - void __iomem *base; - - /* no reset lines available */ - if (!soc_data->reset.idx_map_nr) - return 0; - - base = devm_platform_ioremap_resource(pdev, 2); - if (IS_ERR(base)) - return PTR_ERR(base); rst_data = devm_kzalloc(dev, sizeof(*rst_data), GFP_KERNEL); if (!rst_data) return -ENOMEM; - rst_data->bank_ofs = soc_data->reset.bank_ofs; - rst_data->idx_map = soc_data->reset.idx_map; + rst_data->bank_ofs = en7581_rst_ofs; + rst_data->idx_map = en7581_rst_map; rst_data->base = base; - rst_data->rcdev.nr_resets = soc_data->reset.idx_map_nr; + rst_data->rcdev.nr_resets = ARRAY_SIZE(en7581_rst_map); rst_data->rcdev.of_xlate = en7523_reset_xlate; - rst_data->rcdev.ops = &en7523_reset_ops; + rst_data->rcdev.ops = &en7581_reset_ops; rst_data->rcdev.of_node = dev->of_node; rst_data->rcdev.of_reset_n_cells = 1; rst_data->rcdev.owner = THIS_MODULE; @@ -556,28 +668,38 @@ static int en7523_reset_register(struct platform_device *pdev, return devm_reset_controller_register(dev, &rst_data->rcdev); } -static int en7523_clk_probe(struct platform_device *pdev) +static int en7581_clk_hw_init(struct platform_device *pdev, + struct clk_hw_onecell_data *clk_data) { - struct device_node *node = pdev->dev.of_node; - const struct en_clk_soc_data *soc_data; - struct clk_hw_onecell_data *clk_data; - void __iomem *base, *np_base; - int r; + struct regmap *map; + void __iomem *base; + u32 val; + + map = syscon_regmap_lookup_by_compatible("airoha,en7581-chip-scu"); + if (IS_ERR(map)) + return PTR_ERR(map); base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(base)) return PTR_ERR(base); - np_base = devm_platform_ioremap_resource(pdev, 1); - if (IS_ERR(np_base)) - return PTR_ERR(np_base); + en7581_register_clocks(&pdev->dev, clk_data, map, base); - soc_data = device_get_match_data(&pdev->dev); - if (soc_data->hw_init) { - r = soc_data->hw_init(pdev, np_base); - if (r) - return r; - } + val = readl(base + REG_NP_SCU_SSTR); + val &= ~(REG_PCIE_XSI0_SEL_MASK | REG_PCIE_XSI1_SEL_MASK); + writel(val, base + REG_NP_SCU_SSTR); + val = readl(base + REG_NP_SCU_PCIC); + writel(val | 3, base + REG_NP_SCU_PCIC); + + return en7581_reset_register(&pdev->dev, base); +} + +static int en7523_clk_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + const struct en_clk_soc_data *soc_data; + struct clk_hw_onecell_data *clk_data; + int r; clk_data = devm_kzalloc(&pdev->dev, struct_size(clk_data, hws, EN7523_NUM_CLOCKS), @@ -585,21 +707,12 @@ static int en7523_clk_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - en7523_register_clocks(&pdev->dev, clk_data, base, np_base); - - r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + soc_data = device_get_match_data(&pdev->dev); + r = soc_data->hw_init(pdev, clk_data); if (r) - return dev_err_probe(&pdev->dev, r, "Could not register clock provider: %s\n", - pdev->name); - - r = en7523_reset_register(pdev, soc_data); - if (r) { - of_clk_del_provider(node); - return dev_err_probe(&pdev->dev, r, "Could not register reset controller: %s\n", - pdev->name); - } + return r; - return 0; + return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); } static const struct en_clk_soc_data en7523_data = { @@ -608,6 +721,7 @@ static const struct en_clk_soc_data en7523_data = { .prepare = en7523_pci_prepare, .unprepare = en7523_pci_unprepare, }, + .hw_init = en7523_clk_hw_init, }; static const struct en_clk_soc_data en7581_data = { @@ -616,11 +730,6 @@ static const struct en_clk_soc_data en7581_data = { .enable = en7581_pci_enable, .disable = en7581_pci_disable, }, - .reset = { - .bank_ofs = en7581_rst_ofs, - .idx_map = en7581_rst_map, - .idx_map_nr = ARRAY_SIZE(en7581_rst_map), - }, .hw_init = en7581_clk_hw_init, }; diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c index 5b114043771d..9099c57e2715 100644 --- a/drivers/clk/clk-gpio.c +++ b/drivers/clk/clk-gpio.c @@ -17,13 +17,15 @@ #include <linux/device.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/regulator/consumer.h> /** * DOC: basic gpio gated clock which can be enabled and disabled * with gpio output * Traits of this clock: - * prepare - clk_(un)prepare only ensures parent is (un)prepared - * enable - clk_enable and clk_disable are functional & control gpio + * prepare - clk_(un)prepare are functional and control a gpio that can sleep + * enable - clk_enable and clk_disable are functional & control + * non-sleeping gpio * rate - inherits rate from parent. No clk_set_rate support * parent - fixed parent. No clk_set_parent support */ @@ -199,7 +201,6 @@ static int gpio_clk_driver_probe(struct platform_device *pdev) struct gpio_desc *gpiod; struct clk_hw *hw; bool is_mux; - int ret; is_mux = of_device_is_compatible(node, "gpio-mux-clock"); @@ -211,17 +212,9 @@ static int gpio_clk_driver_probe(struct platform_device *pdev) gpio_name = is_mux ? "select" : "enable"; gpiod = devm_gpiod_get(dev, gpio_name, GPIOD_OUT_LOW); - if (IS_ERR(gpiod)) { - ret = PTR_ERR(gpiod); - if (ret == -EPROBE_DEFER) - pr_debug("%pOFn: %s: GPIOs not yet available, retry later\n", - node, __func__); - else - pr_err("%pOFn: %s: Can't get '%s' named GPIO property\n", - node, __func__, - gpio_name); - return ret; - } + if (IS_ERR(gpiod)) + return dev_err_probe(dev, PTR_ERR(gpiod), + "Can't get '%s' named GPIO property\n", gpio_name); if (is_mux) hw = clk_hw_register_gpio_mux(dev, gpiod); @@ -247,3 +240,187 @@ static struct platform_driver gpio_clk_driver = { }, }; builtin_platform_driver(gpio_clk_driver); + +/** + * DOC: gated fixed clock, controlled with a gpio output and a regulator + * Traits of this clock: + * prepare - clk_prepare and clk_unprepare are function & control regulator + * optionally a gpio that can sleep + * enable - clk_enable and clk_disable are functional & control gpio + * rate - rate is fixed and set on clock registration + * parent - fixed clock is a root clock and has no parent + */ + +/** + * struct clk_gated_fixed - Gateable fixed rate clock + * @clk_gpio: instance of clk_gpio for gate-gpio + * @supply: supply regulator + * @rate: fixed rate + */ +struct clk_gated_fixed { + struct clk_gpio clk_gpio; + struct regulator *supply; + unsigned long rate; +}; + +#define to_clk_gated_fixed(_clk_gpio) container_of(_clk_gpio, struct clk_gated_fixed, clk_gpio) + +static unsigned long clk_gated_fixed_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return to_clk_gated_fixed(to_clk_gpio(hw))->rate; +} + +static int clk_gated_fixed_prepare(struct clk_hw *hw) +{ + struct clk_gated_fixed *clk = to_clk_gated_fixed(to_clk_gpio(hw)); + + if (!clk->supply) + return 0; + + return regulator_enable(clk->supply); +} + +static void clk_gated_fixed_unprepare(struct clk_hw *hw) +{ + struct clk_gated_fixed *clk = to_clk_gated_fixed(to_clk_gpio(hw)); + + if (!clk->supply) + return; + + regulator_disable(clk->supply); +} + +static int clk_gated_fixed_is_prepared(struct clk_hw *hw) +{ + struct clk_gated_fixed *clk = to_clk_gated_fixed(to_clk_gpio(hw)); + + if (!clk->supply) + return true; + + return regulator_is_enabled(clk->supply); +} + +/* + * Fixed gated clock with non-sleeping gpio. + * + * Prepare operation turns on the supply regulator + * and the enable operation switches the enable-gpio. + */ +static const struct clk_ops clk_gated_fixed_ops = { + .prepare = clk_gated_fixed_prepare, + .unprepare = clk_gated_fixed_unprepare, + .is_prepared = clk_gated_fixed_is_prepared, + .enable = clk_gpio_gate_enable, + .disable = clk_gpio_gate_disable, + .is_enabled = clk_gpio_gate_is_enabled, + .recalc_rate = clk_gated_fixed_recalc_rate, +}; + +static int clk_sleeping_gated_fixed_prepare(struct clk_hw *hw) +{ + int ret; + + ret = clk_gated_fixed_prepare(hw); + if (ret) + return ret; + + ret = clk_sleeping_gpio_gate_prepare(hw); + if (ret) + clk_gated_fixed_unprepare(hw); + + return ret; +} + +static void clk_sleeping_gated_fixed_unprepare(struct clk_hw *hw) +{ + clk_gated_fixed_unprepare(hw); + clk_sleeping_gpio_gate_unprepare(hw); +} + +/* + * Fixed gated clock with non-sleeping gpio. + * + * Enabling the supply regulator and switching the enable-gpio happens + * both in the prepare step. + * is_prepared only needs to check the gpio state, as toggling the + * gpio is the last step when preparing. + */ +static const struct clk_ops clk_sleeping_gated_fixed_ops = { + .prepare = clk_sleeping_gated_fixed_prepare, + .unprepare = clk_sleeping_gated_fixed_unprepare, + .is_prepared = clk_sleeping_gpio_gate_is_prepared, + .recalc_rate = clk_gated_fixed_recalc_rate, +}; + +static int clk_gated_fixed_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct clk_gated_fixed *clk; + const struct clk_ops *ops; + const char *clk_name; + u32 rate; + int ret; + + clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL); + if (!clk) + return -ENOMEM; + + ret = device_property_read_u32(dev, "clock-frequency", &rate); + if (ret) + return dev_err_probe(dev, ret, "Failed to get clock-frequency\n"); + clk->rate = rate; + + ret = device_property_read_string(dev, "clock-output-names", &clk_name); + if (ret) + clk_name = fwnode_get_name(dev->fwnode); + + clk->supply = devm_regulator_get_optional(dev, "vdd"); + if (IS_ERR(clk->supply)) { + if (PTR_ERR(clk->supply) != -ENODEV) + return dev_err_probe(dev, PTR_ERR(clk->supply), + "Failed to get regulator\n"); + clk->supply = NULL; + } + + clk->clk_gpio.gpiod = devm_gpiod_get_optional(dev, "enable", + GPIOD_OUT_LOW); + if (IS_ERR(clk->clk_gpio.gpiod)) + return dev_err_probe(dev, PTR_ERR(clk->clk_gpio.gpiod), + "Failed to get gpio\n"); + + if (gpiod_cansleep(clk->clk_gpio.gpiod)) + ops = &clk_sleeping_gated_fixed_ops; + else + ops = &clk_gated_fixed_ops; + + clk->clk_gpio.hw.init = CLK_HW_INIT_NO_PARENT(clk_name, ops, 0); + + /* register the clock */ + ret = devm_clk_hw_register(dev, &clk->clk_gpio.hw); + if (ret) + return dev_err_probe(dev, ret, + "Failed to register clock\n"); + + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, + &clk->clk_gpio.hw); + if (ret) + return dev_err_probe(dev, ret, + "Failed to register clock provider\n"); + + return 0; +} + +static const struct of_device_id gated_fixed_clk_match_table[] = { + { .compatible = "gated-fixed-clock" }, + { /* sentinel */ } +}; + +static struct platform_driver gated_fixed_clk_driver = { + .probe = clk_gated_fixed_probe, + .driver = { + .name = "gated-fixed-clk", + .of_match_table = gated_fixed_clk_match_table, + }, +}; +builtin_platform_driver(gated_fixed_clk_driver); diff --git a/drivers/clk/clk_kunit_helpers.c b/drivers/clk/clk_kunit_helpers.c index 52fd25594c96..68a28e70bb61 100644 --- a/drivers/clk/clk_kunit_helpers.c +++ b/drivers/clk/clk_kunit_helpers.c @@ -203,5 +203,35 @@ int of_clk_hw_register_kunit(struct kunit *test, struct device_node *node, struc } EXPORT_SYMBOL_GPL(of_clk_hw_register_kunit); +KUNIT_DEFINE_ACTION_WRAPPER(of_clk_del_provider_wrapper, + of_clk_del_provider, struct device_node *); + +/** + * of_clk_add_hw_provider_kunit() - Test managed of_clk_add_hw_provider() + * @test: The test context + * @np: Device node pointer associated with clock provider + * @get: Callback for decoding clk_hw + * @data: Context pointer for @get callback. + * + * Just like of_clk_add_hw_provider(), except the clk_hw provider is managed by + * the test case and is automatically unregistered after the test case + * concludes. + * + * Return: 0 on success or a negative errno value on failure. + */ +int of_clk_add_hw_provider_kunit(struct kunit *test, struct device_node *np, + struct clk_hw *(*get)(struct of_phandle_args *clkspec, void *data), + void *data) +{ + int ret; + + ret = of_clk_add_hw_provider(np, get, data); + if (ret) + return ret; + + return kunit_add_action_or_reset(test, of_clk_del_provider_wrapper, np); +} +EXPORT_SYMBOL_GPL(of_clk_add_hw_provider_kunit); + MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("KUnit helpers for clk providers and consumers"); diff --git a/drivers/clk/clk_test.c b/drivers/clk/clk_test.c index 41fc8eba3418..cb53a8df55fc 100644 --- a/drivers/clk/clk_test.c +++ b/drivers/clk/clk_test.c @@ -4,6 +4,7 @@ */ #include <linux/clk.h> #include <linux/clk-provider.h> +#include <linux/clk/clk-conf.h> #include <linux/of.h> #include <linux/platform_device.h> @@ -15,6 +16,7 @@ #include <kunit/platform_device.h> #include <kunit/test.h> +#include "kunit_clk_assigned_rates.h" #include "clk_parent_data_test.h" static const struct clk_ops empty_clk_ops = { }; @@ -3108,7 +3110,326 @@ static struct kunit_suite clk_register_clk_parent_data_device_suite = { .test_cases = clk_register_clk_parent_data_device_test_cases, }; +struct clk_assigned_rates_context { + struct clk_dummy_context clk0; + struct clk_dummy_context clk1; +}; + +/* + * struct clk_assigned_rates_test_param - Test parameters for clk_assigned_rates test + * @desc: Test description + * @overlay_begin: Pointer to start of DT overlay to apply for test + * @overlay_end: Pointer to end of DT overlay to apply for test + * @rate0: Initial rate of first clk + * @rate1: Initial rate of second clk + * @consumer_test: true if a consumer is being tested + */ +struct clk_assigned_rates_test_param { + const char *desc; + u8 *overlay_begin; + u8 *overlay_end; + unsigned long rate0; + unsigned long rate1; + bool consumer_test; +}; + +#define TEST_PARAM_OVERLAY(overlay_name) \ + .overlay_begin = of_overlay_begin(overlay_name), \ + .overlay_end = of_overlay_end(overlay_name) + +static void +clk_assigned_rates_register_clk(struct kunit *test, + struct clk_dummy_context *ctx, + struct device_node *np, const char *name, + unsigned long rate) +{ + struct clk_init_data init = { }; + + init.name = name; + init.ops = &clk_dummy_rate_ops; + ctx->hw.init = &init; + ctx->rate = rate; + + KUNIT_ASSERT_EQ(test, 0, of_clk_hw_register_kunit(test, np, &ctx->hw)); + KUNIT_ASSERT_EQ(test, ctx->rate, rate); +} + +/* + * Does most of the work of the test: + * + * 1. Apply the overlay to test + * 2. Register the clk or clks to test + * 3. Register the clk provider + * 4. Apply clk defaults to the consumer device if this is a consumer test + * + * The tests will set different test_param values to test different scenarios + * and validate that in their test functions. + */ +static int clk_assigned_rates_test_init(struct kunit *test) +{ + struct device_node *np, *consumer; + struct clk_hw_onecell_data *data; + struct clk_assigned_rates_context *ctx; + u32 clk_cells; + const struct clk_assigned_rates_test_param *test_param; + + test_param = test->param_value; + + KUNIT_ASSERT_EQ(test, 0, __of_overlay_apply_kunit(test, + test_param->overlay_begin, + test_param->overlay_end)); + + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, + ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL)); + test->priv = ctx; + + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, + np = of_find_compatible_node(NULL, NULL, "test,clk-assigned-rates")); + of_node_put_kunit(test, np); + + KUNIT_ASSERT_EQ(test, 0, of_property_read_u32(np, "#clock-cells", &clk_cells)); + /* Only support #clock-cells = <0> or <1> */ + KUNIT_ASSERT_LT(test, clk_cells, 2); + + clk_assigned_rates_register_clk(test, &ctx->clk0, np, + "test_assigned_rate0", test_param->rate0); + if (clk_cells == 0) { + KUNIT_ASSERT_EQ(test, 0, + of_clk_add_hw_provider_kunit(test, np, of_clk_hw_simple_get, + &ctx->clk0.hw)); + } else if (clk_cells == 1) { + clk_assigned_rates_register_clk(test, &ctx->clk1, np, + "test_assigned_rate1", test_param->rate1); + + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, + data = kunit_kzalloc(test, struct_size(data, hws, 2), GFP_KERNEL)); + data->num = 2; + data->hws[0] = &ctx->clk0.hw; + data->hws[1] = &ctx->clk1.hw; + + KUNIT_ASSERT_EQ(test, 0, + of_clk_add_hw_provider_kunit(test, np, of_clk_hw_onecell_get, data)); + } + + /* Consumers are optional */ + if (test_param->consumer_test) { + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, + consumer = of_find_compatible_node(NULL, NULL, "test,clk-consumer")); + of_node_put_kunit(test, consumer); + + KUNIT_ASSERT_EQ(test, 0, of_clk_set_defaults(consumer, false)); + } + + return 0; +} + +static void clk_assigned_rates_assigns_one(struct kunit *test) +{ + struct clk_assigned_rates_context *ctx = test->priv; + + KUNIT_EXPECT_EQ(test, ctx->clk0.rate, ASSIGNED_RATES_0_RATE); +} + +static void clk_assigned_rates_assigns_multiple(struct kunit *test) +{ + struct clk_assigned_rates_context *ctx = test->priv; + + KUNIT_EXPECT_EQ(test, ctx->clk0.rate, ASSIGNED_RATES_0_RATE); + KUNIT_EXPECT_EQ(test, ctx->clk1.rate, ASSIGNED_RATES_1_RATE); +} + +static void clk_assigned_rates_skips(struct kunit *test) +{ + struct clk_assigned_rates_context *ctx = test->priv; + const struct clk_assigned_rates_test_param *test_param = test->param_value; + + KUNIT_EXPECT_NE(test, ctx->clk0.rate, ASSIGNED_RATES_0_RATE); + KUNIT_EXPECT_EQ(test, ctx->clk0.rate, test_param->rate0); +} + +OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_one); +OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_one_consumer); +OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_u64_one); +OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_u64_one_consumer); + +/* Test cases that assign one rate */ +static const struct clk_assigned_rates_test_param clk_assigned_rates_assigns_one_test_params[] = { + { + /* + * Test that a single cell assigned-clock-rates property + * assigns the rate when the property is in the provider. + */ + .desc = "provider assigns", + TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_one), + }, + { + /* + * Test that a single cell assigned-clock-rates property + * assigns the rate when the property is in the consumer. + */ + .desc = "consumer assigns", + TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_one_consumer), + .consumer_test = true, + }, + { + /* + * Test that a single cell assigned-clock-rates-u64 property + * assigns the rate when the property is in the provider. + */ + .desc = "provider assigns u64", + TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_u64_one), + }, + { + /* + * Test that a single cell assigned-clock-rates-u64 property + * assigns the rate when the property is in the consumer. + */ + .desc = "consumer assigns u64", + TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_u64_one_consumer), + .consumer_test = true, + }, +}; +KUNIT_ARRAY_PARAM_DESC(clk_assigned_rates_assigns_one, + clk_assigned_rates_assigns_one_test_params, desc) + +OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_multiple); +OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_multiple_consumer); +OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_u64_multiple); +OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_u64_multiple_consumer); + +/* Test cases that assign multiple rates */ +static const struct clk_assigned_rates_test_param clk_assigned_rates_assigns_multiple_test_params[] = { + { + /* + * Test that a multiple cell assigned-clock-rates property + * assigns the rates when the property is in the provider. + */ + .desc = "provider assigns", + TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_multiple), + }, + { + /* + * Test that a multiple cell assigned-clock-rates property + * assigns the rates when the property is in the consumer. + */ + .desc = "consumer assigns", + TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_multiple_consumer), + .consumer_test = true, + }, + { + /* + * Test that a single cell assigned-clock-rates-u64 property + * assigns the rate when the property is in the provider. + */ + .desc = "provider assigns u64", + TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_u64_multiple), + }, + { + /* + * Test that a multiple cell assigned-clock-rates-u64 property + * assigns the rates when the property is in the consumer. + */ + .desc = "consumer assigns u64", + TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_u64_multiple_consumer), + .consumer_test = true, + }, +}; +KUNIT_ARRAY_PARAM_DESC(clk_assigned_rates_assigns_multiple, + clk_assigned_rates_assigns_multiple_test_params, + desc) + +OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_without); +OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_without_consumer); +OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_zero); +OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_zero_consumer); +OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_null); +OF_OVERLAY_DECLARE(kunit_clk_assigned_rates_null_consumer); + +/* Test cases that skip changing the rate due to malformed DT */ +static const struct clk_assigned_rates_test_param clk_assigned_rates_skips_test_params[] = { + { + /* + * Test that an assigned-clock-rates property without an assigned-clocks + * property fails when the property is in the provider. + */ + .desc = "provider missing assigned-clocks", + TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_without), + .rate0 = 3000, + }, + { + /* + * Test that an assigned-clock-rates property without an assigned-clocks + * property fails when the property is in the consumer. + */ + .desc = "consumer missing assigned-clocks", + TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_without_consumer), + .rate0 = 3000, + .consumer_test = true, + }, + { + /* + * Test that an assigned-clock-rates property of zero doesn't + * set a rate when the property is in the provider. + */ + .desc = "provider assigned-clock-rates of zero", + TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_zero), + .rate0 = 3000, + }, + { + /* + * Test that an assigned-clock-rates property of zero doesn't + * set a rate when the property is in the consumer. + */ + .desc = "consumer assigned-clock-rates of zero", + TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_zero_consumer), + .rate0 = 3000, + .consumer_test = true, + }, + { + /* + * Test that an assigned-clocks property with a null phandle + * doesn't set a rate when the property is in the provider. + */ + .desc = "provider assigned-clocks null phandle", + TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_null), + .rate0 = 3000, + }, + { + /* + * Test that an assigned-clocks property with a null phandle + * doesn't set a rate when the property is in the consumer. + */ + .desc = "provider assigned-clocks null phandle", + TEST_PARAM_OVERLAY(kunit_clk_assigned_rates_null_consumer), + .rate0 = 3000, + .consumer_test = true, + }, +}; +KUNIT_ARRAY_PARAM_DESC(clk_assigned_rates_skips, + clk_assigned_rates_skips_test_params, + desc) + +static struct kunit_case clk_assigned_rates_test_cases[] = { + KUNIT_CASE_PARAM(clk_assigned_rates_assigns_one, + clk_assigned_rates_assigns_one_gen_params), + KUNIT_CASE_PARAM(clk_assigned_rates_assigns_multiple, + clk_assigned_rates_assigns_multiple_gen_params), + KUNIT_CASE_PARAM(clk_assigned_rates_skips, + clk_assigned_rates_skips_gen_params), + {} +}; + +/* + * Test suite for assigned-clock-rates{-u64} DT property. + */ +static struct kunit_suite clk_assigned_rates_suite = { + .name = "clk_assigned_rates", + .test_cases = clk_assigned_rates_test_cases, + .init = clk_assigned_rates_test_init, +}; + kunit_test_suites( + &clk_assigned_rates_suite, &clk_leaf_mux_set_rate_parent_test_suite, &clk_test_suite, &clk_multiple_parents_mux_test_suite, diff --git a/drivers/clk/kunit_clk_assigned_rates.h b/drivers/clk/kunit_clk_assigned_rates.h new file mode 100644 index 000000000000..df2d84dcaa93 --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_rates.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _KUNIT_CLK_ASSIGNED_RATES_H +#define _KUNIT_CLK_ASSIGNED_RATES_H + +#define ASSIGNED_RATES_0_RATE 1600000 +#define ASSIGNED_RATES_1_RATE 9700000 + +#endif diff --git a/drivers/clk/kunit_clk_assigned_rates_multiple.dtso b/drivers/clk/kunit_clk_assigned_rates_multiple.dtso new file mode 100644 index 000000000000..e600736e70f5 --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_rates_multiple.dtso @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <1>; + assigned-clocks = <&clk 0>, + <&clk 1>; + assigned-clock-rates = <ASSIGNED_RATES_0_RATE>, + <ASSIGNED_RATES_1_RATE>; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_rates_multiple_consumer.dtso b/drivers/clk/kunit_clk_assigned_rates_multiple_consumer.dtso new file mode 100644 index 000000000000..260aba458daf --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_rates_multiple_consumer.dtso @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <1>; + }; + + kunit-clock-consumer { + compatible = "test,clk-consumer"; + assigned-clocks = <&clk 0>, + <&clk 1>; + assigned-clock-rates = <ASSIGNED_RATES_0_RATE>, + <ASSIGNED_RATES_1_RATE>; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_rates_null.dtso b/drivers/clk/kunit_clk_assigned_rates_null.dtso new file mode 100644 index 000000000000..0b27b38a9130 --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_rates_null.dtso @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + assigned-clocks = <0>; + assigned-clock-rates = <ASSIGNED_RATES_0_RATE>; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_rates_null_consumer.dtso b/drivers/clk/kunit_clk_assigned_rates_null_consumer.dtso new file mode 100644 index 000000000000..99fb332ae83d --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_rates_null_consumer.dtso @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + }; + + kunit-clock-consumer { + compatible = "test,clk-consumer"; + assigned-clocks = <0>; + assigned-clock-rates = <ASSIGNED_RATES_0_RATE>; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_rates_one.dtso b/drivers/clk/kunit_clk_assigned_rates_one.dtso new file mode 100644 index 000000000000..dd95ec9b1cf9 --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_rates_one.dtso @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + assigned-clocks = <&clk>; + assigned-clock-rates = <ASSIGNED_RATES_0_RATE>; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_rates_one_consumer.dtso b/drivers/clk/kunit_clk_assigned_rates_one_consumer.dtso new file mode 100644 index 000000000000..a41dca806318 --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_rates_one_consumer.dtso @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + }; + + kunit-clock-consumer { + compatible = "test,clk-consumer"; + assigned-clocks = <&clk>; + assigned-clock-rates = <ASSIGNED_RATES_0_RATE>; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_rates_u64_multiple.dtso b/drivers/clk/kunit_clk_assigned_rates_u64_multiple.dtso new file mode 100644 index 000000000000..389b4e2eb7f7 --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_rates_u64_multiple.dtso @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <1>; + assigned-clocks = <&clk 0>, + <&clk 1>; + assigned-clock-rates-u64 = /bits/ 64 <ASSIGNED_RATES_0_RATE>, + /bits/ 64 <ASSIGNED_RATES_1_RATE>; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_rates_u64_multiple_consumer.dtso b/drivers/clk/kunit_clk_assigned_rates_u64_multiple_consumer.dtso new file mode 100644 index 000000000000..3e117fd59b7d --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_rates_u64_multiple_consumer.dtso @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <1>; + }; + + kunit-clock-consumer { + compatible = "test,clk-consumer"; + assigned-clocks = <&clk 0>, + <&clk 1>; + assigned-clock-rates-u64 = /bits/ 64 <ASSIGNED_RATES_0_RATE>, + /bits/ 64 <ASSIGNED_RATES_1_RATE>; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_rates_u64_one.dtso b/drivers/clk/kunit_clk_assigned_rates_u64_one.dtso new file mode 100644 index 000000000000..87041264e8f5 --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_rates_u64_one.dtso @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + assigned-clocks = <&clk>; + assigned-clock-rates-u64 = /bits/ 64 <ASSIGNED_RATES_0_RATE>; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_rates_u64_one_consumer.dtso b/drivers/clk/kunit_clk_assigned_rates_u64_one_consumer.dtso new file mode 100644 index 000000000000..3259c003aec0 --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_rates_u64_one_consumer.dtso @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + }; + + kunit-clock-consumer { + compatible = "test,clk-consumer"; + assigned-clocks = <&clk>; + assigned-clock-rates-u64 = /bits/ 64 <ASSIGNED_RATES_0_RATE>; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_rates_without.dtso b/drivers/clk/kunit_clk_assigned_rates_without.dtso new file mode 100644 index 000000000000..22d333495cf2 --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_rates_without.dtso @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + assigned-clock-rates = <ASSIGNED_RATES_0_RATE>; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_rates_without_consumer.dtso b/drivers/clk/kunit_clk_assigned_rates_without_consumer.dtso new file mode 100644 index 000000000000..75ac09140f83 --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_rates_without_consumer.dtso @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +#include "kunit_clk_assigned_rates.h" + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + }; + + kunit-clock-consumer { + compatible = "test,clk-consumer"; + assigned-clock-rates = <ASSIGNED_RATES_0_RATE>; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_rates_zero.dtso b/drivers/clk/kunit_clk_assigned_rates_zero.dtso new file mode 100644 index 000000000000..08e042c2eafe --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_rates_zero.dtso @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + assigned-clocks = <&clk>; + assigned-clock-rates = <0>; + }; +}; diff --git a/drivers/clk/kunit_clk_assigned_rates_zero_consumer.dtso b/drivers/clk/kunit_clk_assigned_rates_zero_consumer.dtso new file mode 100644 index 000000000000..1d964672e855 --- /dev/null +++ b/drivers/clk/kunit_clk_assigned_rates_zero_consumer.dtso @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +&{/} { + clk: kunit-clock { + compatible = "test,clk-assigned-rates"; + #clock-cells = <0>; + }; + + kunit-clock-consumer { + compatible = "test,clk-consumer"; + assigned-clocks = <&clk>; + assigned-clock-rates = <0>; + }; +}; diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 70a005e7e1b1..5f8e6d68fa14 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -124,6 +124,43 @@ config COMMON_CLK_MT2712_VENCSYS help This driver supports MediaTek MT2712 vencsys clocks. +config COMMON_CLK_MT6735 + tristate "Main clock drivers for MediaTek MT6735" + depends on ARCH_MEDIATEK || COMPILE_TEST + select COMMON_CLK_MEDIATEK + help + This enables drivers for clocks and resets provided + by apmixedsys, topckgen, infracfg and pericfg on the + MediaTek MT6735 SoC. + +config COMMON_CLK_MT6735_IMGSYS + tristate "Clock driver for MediaTek MT6735 imgsys" + depends on COMMON_CLK_MT6735 + help + This enables a driver for clocks provided by imgsys + on the MediaTek MT6735 SoC. + +config COMMON_CLK_MT6735_MFGCFG + tristate "Clock driver for MediaTek MT6735 mfgcfg" + depends on COMMON_CLK_MT6735 + help + This enables a driver for clocks and resets provided + by mfgcfg on the MediaTek MT6735 SoC. + +config COMMON_CLK_MT6735_VDECSYS + tristate "Clock driver for MediaTek MT6735 vdecsys" + depends on COMMON_CLK_MT6735 + help + This enables a driver for clocks and resets provided + by vdecsys on the MediaTek MT6735 SoC. + +config COMMON_CLK_MT6735_VENCSYS + tristate "Clock driver for MediaTek MT6735 vencsys" + depends on COMMON_CLK_MT6735 + help + This enables a driver for clocks provided by vencsys + on the MediaTek MT6735 SoC. + config COMMON_CLK_MT6765 bool "Clock driver for MediaTek MT6765" depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST @@ -887,13 +924,6 @@ config COMMON_CLK_MT8195_APUSYS help This driver supports MediaTek MT8195 AI Processor Unit System clocks. -config COMMON_CLK_MT8195_AUDSYS - tristate "Clock driver for MediaTek MT8195 audsys" - depends on COMMON_CLK_MT8195 - default COMMON_CLK_MT8195 - help - This driver supports MediaTek MT8195 audsys clocks. - config COMMON_CLK_MT8195_IMP_IIC_WRAP tristate "Clock driver for MediaTek MT8195 imp_iic_wrap" depends on COMMON_CLK_MT8195 @@ -908,14 +938,6 @@ config COMMON_CLK_MT8195_MFGCFG help This driver supports MediaTek MT8195 mfgcfg clocks. -config COMMON_CLK_MT8195_MSDC - tristate "Clock driver for MediaTek MT8195 msdc" - depends on COMMON_CLK_MT8195 - default COMMON_CLK_MT8195 - help - This driver supports MediaTek MT8195 MMC and SD Controller's - msdc and msdc_top clocks. - config COMMON_CLK_MT8195_SCP_ADSP tristate "Clock driver for MediaTek MT8195 scp_adsp" depends on COMMON_CLK_MT8195 diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index eeccfa039896..6efec95406bd 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -2,6 +2,11 @@ obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o clk-mux.o obj-$(CONFIG_COMMON_CLK_MEDIATEK_FHCTL) += clk-fhctl.o clk-pllfh.o +obj-$(CONFIG_COMMON_CLK_MT6735) += clk-mt6735-apmixedsys.o clk-mt6735-infracfg.o clk-mt6735-pericfg.o clk-mt6735-topckgen.o +obj-$(CONFIG_COMMON_CLK_MT6735_IMGSYS) += clk-mt6735-imgsys.o +obj-$(CONFIG_COMMON_CLK_MT6735_MFGCFG) += clk-mt6735-mfgcfg.o +obj-$(CONFIG_COMMON_CLK_MT6735_VDECSYS) += clk-mt6735-vdecsys.o +obj-$(CONFIG_COMMON_CLK_MT6735_VENCSYS) += clk-mt6735-vencsys.o obj-$(CONFIG_COMMON_CLK_MT6765) += clk-mt6765.o obj-$(CONFIG_COMMON_CLK_MT6765_AUDIOSYS) += clk-mt6765-audio.o obj-$(CONFIG_COMMON_CLK_MT6765_CAMSYS) += clk-mt6765-cam.o diff --git a/drivers/clk/mediatek/clk-mt6735-apmixedsys.c b/drivers/clk/mediatek/clk-mt6735-apmixedsys.c new file mode 100644 index 000000000000..e0949911e8f7 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6735-apmixedsys.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Yassine Oudjana <y.oudjana@protonmail.com> + */ + +#include <linux/clk-provider.h> +#include <linux/platform_device.h> + +#include "clk-mtk.h" +#include "clk-pll.h" + +#include <dt-bindings/clock/mediatek,mt6735-apmixedsys.h> + +#define AP_PLL_CON_5 0x014 +#define ARMPLL_CON0 0x200 +#define ARMPLL_CON1 0x204 +#define ARMPLL_PWR_CON0 0x20c +#define MAINPLL_CON0 0x210 +#define MAINPLL_CON1 0x214 +#define MAINPLL_PWR_CON0 0x21c +#define UNIVPLL_CON0 0x220 +#define UNIVPLL_CON1 0x224 +#define UNIVPLL_PWR_CON0 0x22c +#define MMPLL_CON0 0x230 +#define MMPLL_CON1 0x234 +#define MMPLL_PWR_CON0 0x23c +#define MSDCPLL_CON0 0x240 +#define MSDCPLL_CON1 0x244 +#define MSDCPLL_PWR_CON0 0x24c +#define VENCPLL_CON0 0x250 +#define VENCPLL_CON1 0x254 +#define VENCPLL_PWR_CON0 0x25c +#define TVDPLL_CON0 0x260 +#define TVDPLL_CON1 0x264 +#define TVDPLL_PWR_CON0 0x26c +#define APLL1_CON0 0x270 +#define APLL1_CON1 0x274 +#define APLL1_CON2 0x278 +#define APLL1_PWR_CON0 0x280 +#define APLL2_CON0 0x284 +#define APLL2_CON1 0x288 +#define APLL2_CON2 0x28c +#define APLL2_PWR_CON0 0x294 + +#define CON0_RST_BAR BIT(24) + +#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _rst_bar_mask, \ + _pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg, \ + _tuner_en_bit, _pcw_reg, _pcwbits, _flags) { \ + .id = _id, \ + .name = _name, \ + .parent_name = "clk26m", \ + .reg = _reg, \ + .pwr_reg = _pwr_reg, \ + .en_mask = _en_mask, \ + .rst_bar_mask = _rst_bar_mask, \ + .pd_reg = _pd_reg, \ + .pd_shift = _pd_shift, \ + .tuner_reg = _tuner_reg, \ + .tuner_en_reg = _tuner_en_reg, \ + .tuner_en_bit = _tuner_en_bit, \ + .pcw_reg = _pcw_reg, \ + .pcw_chg_reg = _pcw_reg, \ + .pcwbits = _pcwbits, \ + .flags = _flags, \ + } + +static const struct mtk_pll_data apmixedsys_plls[] = { + PLL(CLK_APMIXED_ARMPLL, "armpll", ARMPLL_CON0, ARMPLL_PWR_CON0, 0x00000001, 0, ARMPLL_CON1, 24, 0, 0, 0, ARMPLL_CON1, 21, PLL_AO), + PLL(CLK_APMIXED_MAINPLL, "mainpll", MAINPLL_CON0, MAINPLL_PWR_CON0, 0xf0000101, CON0_RST_BAR, MAINPLL_CON1, 24, 0, 0, 0, MAINPLL_CON1, 21, HAVE_RST_BAR), + PLL(CLK_APMIXED_UNIVPLL, "univpll", UNIVPLL_CON0, UNIVPLL_PWR_CON0, 0xfc000001, CON0_RST_BAR, UNIVPLL_CON1, 24, 0, 0, 0, UNIVPLL_CON1, 21, HAVE_RST_BAR), + PLL(CLK_APMIXED_MMPLL, "mmpll", MMPLL_CON0, MMPLL_PWR_CON0, 0x00000001, 0, MMPLL_CON1, 24, 0, 0, 0, MMPLL_CON1, 21, 0), + PLL(CLK_APMIXED_MSDCPLL, "msdcpll", MSDCPLL_CON0, MSDCPLL_PWR_CON0, 0x00000001, 0, MSDCPLL_CON1, 24, 0, 0, 0, MSDCPLL_CON1, 21, 0), + PLL(CLK_APMIXED_VENCPLL, "vencpll", VENCPLL_CON0, VENCPLL_PWR_CON0, 0x00000001, CON0_RST_BAR, VENCPLL_CON1, 24, 0, 0, 0, VENCPLL_CON1, 21, HAVE_RST_BAR), + PLL(CLK_APMIXED_TVDPLL, "tvdpll", TVDPLL_CON0, TVDPLL_PWR_CON0, 0x00000001, 0, TVDPLL_CON1, 24, 0, 0, 0, TVDPLL_CON1, 21, 0), + PLL(CLK_APMIXED_APLL1, "apll1", APLL1_CON0, APLL1_PWR_CON0, 0x00000001, 0, APLL1_CON0, 4, APLL1_CON2, AP_PLL_CON_5, 0, APLL1_CON1, 31, 0), + PLL(CLK_APMIXED_APLL2, "apll2", APLL2_CON0, APLL2_PWR_CON0, 0x00000001, 0, APLL2_CON0, 4, APLL2_CON2, AP_PLL_CON_5, 1, APLL2_CON1, 31, 0) +}; + +static int clk_mt6735_apmixed_probe(struct platform_device *pdev) +{ + void __iomem *base; + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + struct clk_hw_onecell_data *clk_data; + int ret; + + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + clk_data = mtk_devm_alloc_clk_data(&pdev->dev, ARRAY_SIZE(apmixedsys_plls)); + if (!clk_data) + return -ENOMEM; + platform_set_drvdata(pdev, clk_data); + + ret = mtk_clk_register_plls(pdev->dev.of_node, apmixedsys_plls, + ARRAY_SIZE(apmixedsys_plls), clk_data); + if (ret) { + dev_err(&pdev->dev, "Failed to register PLLs: %d\n", ret); + return ret; + } + + ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get, + clk_data); + if (ret) + dev_err(&pdev->dev, + "Failed to register clock provider: %d\n", ret); + + return ret; +} + +static void clk_mt6735_apmixed_remove(struct platform_device *pdev) +{ + struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev); + + mtk_clk_unregister_plls(apmixedsys_plls, ARRAY_SIZE(apmixedsys_plls), clk_data); +} + +static const struct of_device_id of_match_mt6735_apmixedsys[] = { + { .compatible = "mediatek,mt6735-apmixedsys" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_mt6735_apmixedsys); + +static struct platform_driver clk_mt6735_apmixedsys = { + .probe = clk_mt6735_apmixed_probe, + .remove = clk_mt6735_apmixed_remove, + .driver = { + .name = "clk-mt6735-apmixedsys", + .of_match_table = of_match_mt6735_apmixedsys, + }, +}; +module_platform_driver(clk_mt6735_apmixedsys); + +MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>"); +MODULE_DESCRIPTION("MediaTek MT6735 apmixedsys clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt6735-imgsys.c b/drivers/clk/mediatek/clk-mt6735-imgsys.c new file mode 100644 index 000000000000..c564f8f72432 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6735-imgsys.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Yassine Oudjana <y.oudjana@protonmail.com> + */ + +#include <linux/clk-provider.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include <dt-bindings/clock/mediatek,mt6735-imgsys.h> + +#define IMG_CG_CON 0x00 +#define IMG_CG_SET 0x04 +#define IMG_CG_CLR 0x08 + +static struct mtk_gate_regs imgsys_cg_regs = { + .set_ofs = IMG_CG_SET, + .clr_ofs = IMG_CG_CLR, + .sta_ofs = IMG_CG_CON, +}; + +static const struct mtk_gate imgsys_gates[] = { + GATE_MTK(CLK_IMG_SMI_LARB2, "smi_larb2", "mm_sel", &imgsys_cg_regs, 0, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_IMG_CAM_SMI, "cam_smi", "mm_sel", &imgsys_cg_regs, 5, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_IMG_CAM_CAM, "cam_cam", "mm_sel", &imgsys_cg_regs, 6, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_IMG_SEN_TG, "sen_tg", "mm_sel", &imgsys_cg_regs, 7, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_IMG_SEN_CAM, "sen_cam", "mm_sel", &imgsys_cg_regs, 8, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_IMG_CAM_SV, "cam_sv", "mm_sel", &imgsys_cg_regs, 9, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_IMG_SUFOD, "sufod", "mm_sel", &imgsys_cg_regs, 10, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_IMG_FD, "fd", "mm_sel", &imgsys_cg_regs, 11, &mtk_clk_gate_ops_setclr), +}; + +static const struct mtk_clk_desc imgsys_clks = { + .clks = imgsys_gates, + .num_clks = ARRAY_SIZE(imgsys_gates), +}; + +static const struct of_device_id of_match_mt6735_imgsys[] = { + { .compatible = "mediatek,mt6735-imgsys", .data = &imgsys_clks }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt6735_imgsys = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt6735-imgsys", + .of_match_table = of_match_mt6735_imgsys, + }, +}; +module_platform_driver(clk_mt6735_imgsys); + +MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>"); +MODULE_DESCRIPTION("MediaTek MT6735 imgsys clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt6735-infracfg.c b/drivers/clk/mediatek/clk-mt6735-infracfg.c new file mode 100644 index 000000000000..c1171f903cfa --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6735-infracfg.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Yassine Oudjana <y.oudjana@protonmail.com> + */ + +#include <linux/clk-provider.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include <dt-bindings/clock/mediatek,mt6735-infracfg.h> +#include <dt-bindings/reset/mediatek,mt6735-infracfg.h> + +#define INFRA_RST0 0x30 +#define INFRA_GLOBALCON_PDN0 0x40 +#define INFRA_PDN1 0x44 +#define INFRA_PDN_STA 0x48 + +#define RST_NR_PER_BANK 32 + +static struct mtk_gate_regs infra_cg_regs = { + .set_ofs = INFRA_GLOBALCON_PDN0, + .clr_ofs = INFRA_PDN1, + .sta_ofs = INFRA_PDN_STA, +}; + +static const struct mtk_gate infracfg_gates[] = { + GATE_MTK(CLK_INFRA_DBG, "dbg", "axi_sel", &infra_cg_regs, 0, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_INFRA_GCE, "gce", "axi_sel", &infra_cg_regs, 1, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_INFRA_TRBG, "trbg", "axi_sel", &infra_cg_regs, 2, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_INFRA_CPUM, "cpum", "axi_sel", &infra_cg_regs, 3, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_INFRA_DEVAPC, "devapc", "axi_sel", &infra_cg_regs, 4, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_INFRA_AUDIO, "audio", "aud_intbus_sel", &infra_cg_regs, 5, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_INFRA_GCPU, "gcpu", "axi_sel", &infra_cg_regs, 6, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_INFRA_L2C_SRAM, "l2csram", "axi_sel", &infra_cg_regs, 7, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_INFRA_M4U, "m4u", "axi_sel", &infra_cg_regs, 8, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_INFRA_CLDMA, "cldma", "axi_sel", &infra_cg_regs, 12, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_INFRA_CONNMCU_BUS, "connmcu_bus", "axi_sel", &infra_cg_regs, 15, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_INFRA_KP, "kp", "axi_sel", &infra_cg_regs, 16, &mtk_clk_gate_ops_setclr), + GATE_MTK_FLAGS(CLK_INFRA_APXGPT, "apxgpt", "axi_sel", &infra_cg_regs, 18, &mtk_clk_gate_ops_setclr, CLK_IS_CRITICAL), + GATE_MTK(CLK_INFRA_SEJ, "sej", "axi_sel", &infra_cg_regs, 19, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_INFRA_CCIF0_AP, "ccif0ap", "axi_sel", &infra_cg_regs, 20, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_INFRA_CCIF1_AP, "ccif1ap", "axi_sel", &infra_cg_regs, 21, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_INFRA_PMIC_SPI, "pmicspi", "pmicspi_sel", &infra_cg_regs, 22, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_INFRA_PMIC_WRAP, "pmicwrap", "axi_sel", &infra_cg_regs, 23, &mtk_clk_gate_ops_setclr) +}; + +static u16 infracfg_rst_bank_ofs[] = { INFRA_RST0 }; + +static u16 infracfg_rst_idx_map[] = { + [MT6735_INFRA_RST0_EMI_REG] = 0 * RST_NR_PER_BANK + 0, + [MT6735_INFRA_RST0_DRAMC0_AO] = 0 * RST_NR_PER_BANK + 1, + [MT6735_INFRA_RST0_AP_CIRQ_EINT] = 0 * RST_NR_PER_BANK + 3, + [MT6735_INFRA_RST0_APXGPT] = 0 * RST_NR_PER_BANK + 4, + [MT6735_INFRA_RST0_SCPSYS] = 0 * RST_NR_PER_BANK + 5, + [MT6735_INFRA_RST0_KP] = 0 * RST_NR_PER_BANK + 6, + [MT6735_INFRA_RST0_PMIC_WRAP] = 0 * RST_NR_PER_BANK + 7, + [MT6735_INFRA_RST0_CLDMA_AO_TOP] = 0 * RST_NR_PER_BANK + 8, + [MT6735_INFRA_RST0_USBSIF_TOP] = 0 * RST_NR_PER_BANK + 9, + [MT6735_INFRA_RST0_EMI] = 0 * RST_NR_PER_BANK + 16, + [MT6735_INFRA_RST0_CCIF] = 0 * RST_NR_PER_BANK + 17, + [MT6735_INFRA_RST0_DRAMC0] = 0 * RST_NR_PER_BANK + 18, + [MT6735_INFRA_RST0_EMI_AO_REG] = 0 * RST_NR_PER_BANK + 19, + [MT6735_INFRA_RST0_CCIF_AO] = 0 * RST_NR_PER_BANK + 20, + [MT6735_INFRA_RST0_TRNG] = 0 * RST_NR_PER_BANK + 21, + [MT6735_INFRA_RST0_SYS_CIRQ] = 0 * RST_NR_PER_BANK + 22, + [MT6735_INFRA_RST0_GCE] = 0 * RST_NR_PER_BANK + 23, + [MT6735_INFRA_RST0_M4U] = 0 * RST_NR_PER_BANK + 24, + [MT6735_INFRA_RST0_CCIF1] = 0 * RST_NR_PER_BANK + 25, + [MT6735_INFRA_RST0_CLDMA_TOP_PD] = 0 * RST_NR_PER_BANK + 26 +}; + +static const struct mtk_clk_rst_desc infracfg_resets = { + .version = MTK_RST_SIMPLE, + .rst_bank_ofs = infracfg_rst_bank_ofs, + .rst_bank_nr = ARRAY_SIZE(infracfg_rst_bank_ofs), + .rst_idx_map = infracfg_rst_idx_map, + .rst_idx_map_nr = ARRAY_SIZE(infracfg_rst_idx_map) +}; + +static const struct mtk_clk_desc infracfg_clks = { + .clks = infracfg_gates, + .num_clks = ARRAY_SIZE(infracfg_gates), + + .rst_desc = &infracfg_resets +}; + +static const struct of_device_id of_match_mt6735_infracfg[] = { + { .compatible = "mediatek,mt6735-infracfg", .data = &infracfg_clks }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_mt6735_infracfg); + +static struct platform_driver clk_mt6735_infracfg = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt6735-infracfg", + .of_match_table = of_match_mt6735_infracfg, + }, +}; +module_platform_driver(clk_mt6735_infracfg); + +MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>"); +MODULE_DESCRIPTION("MediaTek MT6735 infracfg clock and reset driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt6735-mfgcfg.c b/drivers/clk/mediatek/clk-mt6735-mfgcfg.c new file mode 100644 index 000000000000..1f5aedddf209 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6735-mfgcfg.c @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Yassine Oudjana <y.oudjana@protonmail.com> + */ + +#include <linux/clk-provider.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include <dt-bindings/clock/mediatek,mt6735-mfgcfg.h> + +#define MFG_CG_CON 0x00 +#define MFG_CG_SET 0x04 +#define MFG_CG_CLR 0x08 +#define MFG_RESET 0x0c + +static struct mtk_gate_regs mfgcfg_cg_regs = { + .set_ofs = MFG_CG_SET, + .clr_ofs = MFG_CG_CLR, + .sta_ofs = MFG_CG_CON, +}; + +static const struct mtk_gate mfgcfg_gates[] = { + GATE_MTK(CLK_MFG_BG3D, "bg3d", "mfg_sel", &mfgcfg_cg_regs, 0, &mtk_clk_gate_ops_setclr), +}; + +static u16 mfgcfg_rst_ofs[] = { MFG_RESET }; + +static const struct mtk_clk_rst_desc mfgcfg_resets = { + .version = MTK_RST_SIMPLE, + .rst_bank_ofs = mfgcfg_rst_ofs, + .rst_bank_nr = ARRAY_SIZE(mfgcfg_rst_ofs) +}; + +static const struct mtk_clk_desc mfgcfg_clks = { + .clks = mfgcfg_gates, + .num_clks = ARRAY_SIZE(mfgcfg_gates), + + .rst_desc = &mfgcfg_resets +}; + +static const struct of_device_id of_match_mt6735_mfgcfg[] = { + { .compatible = "mediatek,mt6735-mfgcfg", .data = &mfgcfg_clks }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt6735_mfgcfg = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt6735-mfgcfg", + .of_match_table = of_match_mt6735_mfgcfg, + }, +}; +module_platform_driver(clk_mt6735_mfgcfg); + +MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>"); +MODULE_DESCRIPTION("Mediatek MT6735 mfgcfg clock and reset driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt6735-pericfg.c b/drivers/clk/mediatek/clk-mt6735-pericfg.c new file mode 100644 index 000000000000..cbdf6d25c1b2 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6735-pericfg.c @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Yassine Oudjana <y.oudjana@protonmail.com> + */ + +#include <linux/clk-provider.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include <dt-bindings/clock/mediatek,mt6735-pericfg.h> +#include <dt-bindings/reset/mediatek,mt6735-pericfg.h> + +#define PERI_GLOBALCON_RST0 0x00 +#define PERI_GLOBALCON_RST1 0x04 +#define PERI_GLOBALCON_PDN0_SET 0x08 +#define PERI_GLOBALCON_PDN0_CLR 0x10 +#define PERI_GLOBALCON_PDN0_STA 0x18 + +#define RST_NR_PER_BANK 32 + +static struct mtk_gate_regs peri_cg_regs = { + .set_ofs = PERI_GLOBALCON_PDN0_SET, + .clr_ofs = PERI_GLOBALCON_PDN0_CLR, + .sta_ofs = PERI_GLOBALCON_PDN0_STA, +}; + +static const struct mtk_gate pericfg_gates[] = { + GATE_MTK(CLK_PERI_DISP_PWM, "disp_pwm", "disppwm_sel", &peri_cg_regs, 0, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_THERM, "therm", "axi_sel", &peri_cg_regs, 1, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_PWM1, "pwm1", "axi_sel", &peri_cg_regs, 2, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_PWM2, "pwm2", "axi_sel", &peri_cg_regs, 3, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_PWM3, "pwm3", "axi_sel", &peri_cg_regs, 4, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_PWM4, "pwm4", "axi_sel", &peri_cg_regs, 5, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_PWM5, "pwm5", "axi_sel", &peri_cg_regs, 6, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_PWM6, "pwm6", "axi_sel", &peri_cg_regs, 7, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_PWM7, "pwm7", "axi_sel", &peri_cg_regs, 8, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_PWM, "pwm", "axi_sel", &peri_cg_regs, 9, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_USB0, "usb0", "usb20_sel", &peri_cg_regs, 10, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_IRDA, "irda", "irda_sel", &peri_cg_regs, 11, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_APDMA, "apdma", "axi_sel", &peri_cg_regs, 12, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_MSDC30_0, "msdc30_0", "msdc30_0_sel", &peri_cg_regs, 13, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_MSDC30_1, "msdc30_1", "msdc30_1_sel", &peri_cg_regs, 14, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_MSDC30_2, "msdc30_2", "msdc30_2_sel", &peri_cg_regs, 15, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_MSDC30_3, "msdc30_3", "msdc30_3_sel", &peri_cg_regs, 16, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_UART0, "uart0", "uart_sel", &peri_cg_regs, 17, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_UART1, "uart1", "uart_sel", &peri_cg_regs, 18, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_UART2, "uart2", "uart_sel", &peri_cg_regs, 19, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_UART3, "uart3", "uart_sel", &peri_cg_regs, 20, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_UART4, "uart4", "uart_sel", &peri_cg_regs, 21, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_BTIF, "btif", "axi_sel", &peri_cg_regs, 22, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_I2C0, "i2c0", "axi_sel", &peri_cg_regs, 23, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_I2C1, "i2c1", "axi_sel", &peri_cg_regs, 24, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_I2C2, "i2c2", "axi_sel", &peri_cg_regs, 25, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_I2C3, "i2c3", "axi_sel", &peri_cg_regs, 26, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_AUXADC, "auxadc", "axi_sel", &peri_cg_regs, 27, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_SPI0, "spi0", "spi_sel", &peri_cg_regs, 28, &mtk_clk_gate_ops_setclr), + GATE_MTK(CLK_PERI_IRTX, "irtx", "irtx_sel", &peri_cg_regs, 29, &mtk_clk_gate_ops_setclr) +}; + +static u16 pericfg_rst_bank_ofs[] = { PERI_GLOBALCON_RST0, PERI_GLOBALCON_RST1 }; + +static u16 pericfg_rst_idx_map[] = { + [MT6735_PERI_RST0_UART0] = 0 * RST_NR_PER_BANK + 0, + [MT6735_PERI_RST0_UART1] = 0 * RST_NR_PER_BANK + 1, + [MT6735_PERI_RST0_UART2] = 0 * RST_NR_PER_BANK + 2, + [MT6735_PERI_RST0_UART3] = 0 * RST_NR_PER_BANK + 3, + [MT6735_PERI_RST0_UART4] = 0 * RST_NR_PER_BANK + 4, + [MT6735_PERI_RST0_BTIF] = 0 * RST_NR_PER_BANK + 6, + [MT6735_PERI_RST0_DISP_PWM_PERI] = 0 * RST_NR_PER_BANK + 7, + [MT6735_PERI_RST0_PWM] = 0 * RST_NR_PER_BANK + 8, + [MT6735_PERI_RST0_AUXADC] = 0 * RST_NR_PER_BANK + 10, + [MT6735_PERI_RST0_DMA] = 0 * RST_NR_PER_BANK + 11, + [MT6735_PERI_RST0_IRDA] = 0 * RST_NR_PER_BANK + 12, + [MT6735_PERI_RST0_IRTX] = 0 * RST_NR_PER_BANK + 13, + [MT6735_PERI_RST0_THERM] = 0 * RST_NR_PER_BANK + 16, + [MT6735_PERI_RST0_MSDC2] = 0 * RST_NR_PER_BANK + 17, + [MT6735_PERI_RST0_MSDC3] = 0 * RST_NR_PER_BANK + 18, + [MT6735_PERI_RST0_MSDC0] = 0 * RST_NR_PER_BANK + 19, + [MT6735_PERI_RST0_MSDC1] = 0 * RST_NR_PER_BANK + 20, + [MT6735_PERI_RST0_I2C0] = 0 * RST_NR_PER_BANK + 22, + [MT6735_PERI_RST0_I2C1] = 0 * RST_NR_PER_BANK + 23, + [MT6735_PERI_RST0_I2C2] = 0 * RST_NR_PER_BANK + 24, + [MT6735_PERI_RST0_I2C3] = 0 * RST_NR_PER_BANK + 25, + [MT6735_PERI_RST0_USB] = 0 * RST_NR_PER_BANK + 28, + + [MT6735_PERI_RST1_SPI0] = 1 * RST_NR_PER_BANK + 1, +}; + +static const struct mtk_clk_rst_desc pericfg_resets = { + .version = MTK_RST_SIMPLE, + .rst_bank_ofs = pericfg_rst_bank_ofs, + .rst_bank_nr = ARRAY_SIZE(pericfg_rst_bank_ofs), + .rst_idx_map = pericfg_rst_idx_map, + .rst_idx_map_nr = ARRAY_SIZE(pericfg_rst_idx_map) +}; + +static const struct mtk_clk_desc pericfg_clks = { + .clks = pericfg_gates, + .num_clks = ARRAY_SIZE(pericfg_gates), + + .rst_desc = &pericfg_resets +}; + +static const struct of_device_id of_match_mt6735_pericfg[] = { + { .compatible = "mediatek,mt6735-pericfg", .data = &pericfg_clks }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_mt6735_pericfg); + +static struct platform_driver clk_mt6735_pericfg = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt6735-pericfg", + .of_match_table = of_match_mt6735_pericfg, + }, +}; +module_platform_driver(clk_mt6735_pericfg); + +MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>"); +MODULE_DESCRIPTION("MediaTek MT6735 pericfg clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt6735-topckgen.c b/drivers/clk/mediatek/clk-mt6735-topckgen.c new file mode 100644 index 000000000000..2589ebfe2271 --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6735-topckgen.c @@ -0,0 +1,394 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Yassine Oudjana <y.oudjana@protonmail.com> + */ + +#include <linux/clk-provider.h> +#include <linux/platform_device.h> + +#include "clk-mtk.h" +#include "clk-mux.h" + +#include <dt-bindings/clock/mediatek,mt6735-topckgen.h> + +#define CLK_CFG_0 0x40 +#define CLK_CFG_0_SET 0x44 +#define CLK_CFG_0_CLR 0x48 +#define CLK_CFG_1 0x50 +#define CLK_CFG_1_SET 0x54 +#define CLK_CFG_1_CLR 0x58 +#define CLK_CFG_2 0x60 +#define CLK_CFG_2_SET 0x64 +#define CLK_CFG_2_CLR 0x68 +#define CLK_CFG_3 0x70 +#define CLK_CFG_3_SET 0x74 +#define CLK_CFG_3_CLR 0x78 +#define CLK_CFG_4 0x80 +#define CLK_CFG_4_SET 0x84 +#define CLK_CFG_4_CLR 0x88 +#define CLK_CFG_5 0x90 +#define CLK_CFG_5_SET 0x94 +#define CLK_CFG_5_CLR 0x98 +#define CLK_CFG_6 0xa0 +#define CLK_CFG_6_SET 0xa4 +#define CLK_CFG_6_CLR 0xa8 +#define CLK_CFG_7 0xb0 +#define CLK_CFG_7_SET 0xb4 +#define CLK_CFG_7_CLR 0xb8 + +static DEFINE_SPINLOCK(mt6735_topckgen_lock); + +/* Some clocks with unknown details are modeled as fixed clocks */ +static const struct mtk_fixed_clk topckgen_fixed_clks[] = { + /* + * This clock is available as a parent option for multiple + * muxes and seems like an alternative name for clk26m at first, + * but it appears alongside it in several muxes which should + * mean it is a separate clock. + */ + FIXED_CLK(CLK_TOP_AD_SYS_26M_CK, "ad_sys_26m_ck", "clk26m", 26 * MHZ), + /* + * This clock is the parent of DMPLL divisors. It might be MEMPLL + * or its parent, as DMPLL appears to be an alternative name for + * MEMPLL. + */ + FIXED_CLK(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", NULL, 0), + /* + * DMPLL clock (dmpll_ck), controlled by DDRPHY. + */ + FIXED_CLK(CLK_TOP_DMPLL, "dmpll", "clkph_mck_o", 0), + /* + * MIPI DPI clock. Parent option for dpi0_sel. Unknown parent. + */ + FIXED_CLK(CLK_TOP_DPI_CK, "dpi_ck", NULL, 0), + /* + * This clock is a child of WHPLL which is controlled by + * the modem. + */ + FIXED_CLK(CLK_TOP_WHPLL_AUDIO_CK, "whpll_audio_ck", NULL, 0) +}; + +static const struct mtk_fixed_factor topckgen_factors[] = { + FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll", 1, 2), + FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll", 1, 3), + FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll", 1, 5), + FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "mainpll", 1, 2), + FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "mainpll", 1, 4), + FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "mainpll", 1, 8), + FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "mainpll", 1, 16), + FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "mainpll", 1, 2), + FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "mainpll", 1, 4), + FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "mainpll", 1, 2), + FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "mainpll", 1, 4), + FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "mainpll", 1, 2), + FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "mainpll", 1, 4), + FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univpll", 1, 2), + FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll", 1, 3), + FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll", 1, 5), + FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll", 1, 26), + FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll", 1, 2), + FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll", 1, 4), + FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll", 1, 8), + FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll", 1, 2), + FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll", 1, 4), + FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll", 1, 8), + FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univpll", 1, 2), + FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univpll", 1, 4), + FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2), + FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4), + FACTOR(CLK_TOP_MSDCPLL_D8, "msdcpll_d8", "msdcpll", 1, 8), + FACTOR(CLK_TOP_MSDCPLL_D16, "msdcpll_d16", "msdcpll", 1, 16), + FACTOR(CLK_TOP_VENCPLL_D3, "vencpll_d3", "vencpll", 1, 3), + FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll", 1, 2), + FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4), + FACTOR(CLK_TOP_DMPLL_D2, "dmpll_d2", "clkph_mck_o", 1, 2), + FACTOR(CLK_TOP_DMPLL_D4, "dmpll_d4", "clkph_mck_o", 1, 4), + FACTOR(CLK_TOP_DMPLL_D8, "dmpll_d8", "clkph_mck_o", 1, 8), + FACTOR(CLK_TOP_AD_SYS_26M_D2, "ad_sys_26m_d2", "clk26m", 1, 2) +}; + +static const char * const axi_sel_parents[] = { + "clk26m", + "syspll1_d2", + "syspll_d5", + "syspll1_d4", + "univpll_d5", + "univpll2_d2", + "dmpll", + "dmpll_d2" +}; + +static const char * const mem_sel_parents[] = { + "clk26m", + "dmpll" +}; + +static const char * const ddrphycfg_parents[] = { + "clk26m", + "syspll1_d8" +}; + +static const char * const mm_sel_parents[] = { + "clk26m", + "vencpll", + "syspll1_d2", + "syspll_d5", + "syspll1_d4", + "univpll_d5", + "univpll2_d2", + "dmpll" +}; + +static const char * const pwm_sel_parents[] = { + "clk26m", + "univpll2_d4", + "univpll3_d2", + "univpll1_d4" +}; + +static const char * const vdec_sel_parents[] = { + "clk26m", + "syspll1_d2", + "syspll_d5", + "syspll1_d4", + "univpll_d5", + "syspll_d2", + "syspll2_d2", + "msdcpll_d2" +}; + +static const char * const mfg_sel_parents[] = { + "clk26m", + "mmpll", + "clk26m", + "clk26m", + "clk26m", + "clk26m", + "clk26m", + "clk26m", + "clk26m", + "syspll_d3", + "syspll1_d2", + "syspll_d5", + "univpll_d3", + "univpll1_d2" +}; + +static const char * const camtg_sel_parents[] = { + "clk26m", + "univpll_d26", + "univpll2_d2", + "syspll3_d2", + "syspll3_d4", + "msdcpll_d4" +}; + +static const char * const uart_sel_parents[] = { + "clk26m", + "univpll2_d8" +}; + +static const char * const spi_sel_parents[] = { + "clk26m", + "syspll3_d2", + "msdcpll_d8", + "syspll2_d4", + "syspll4_d2", + "univpll2_d4", + "univpll1_d8" +}; + +static const char * const usb20_sel_parents[] = { + "clk26m", + "univpll1_d8", + "univpll3_d4" +}; + +static const char * const msdc50_0_sel_parents[] = { + "clk26m", + "syspll1_d2", + "syspll2_d2", + "syspll4_d2", + "univpll_d5", + "univpll1_d4" +}; + +static const char * const msdc30_0_sel_parents[] = { + "clk26m", + "msdcpll", + "msdcpll_d2", + "msdcpll_d4", + "syspll2_d2", + "syspll1_d4", + "univpll1_d4", + "univpll_d3", + "univpll_d26", + "syspll2_d4", + "univpll_d2" +}; + +static const char * const msdc30_1_2_sel_parents[] = { + "clk26m", + "univpll2_d2", + "msdcpll_d4", + "syspll2_d2", + "syspll1_d4", + "univpll1_d4", + "univpll_d26", + "syspll2_d4" +}; + +static const char * const msdc30_3_sel_parents[] = { + "clk26m", + "univpll2_d2", + "msdcpll_d4", + "syspll2_d2", + "syspll1_d4", + "univpll1_d4", + "univpll_d26", + "msdcpll_d16", + "syspll2_d4" +}; + +static const char * const audio_sel_parents[] = { + "clk26m", + "syspll3_d4", + "syspll4_d4", + "syspll1_d16" +}; + +static const char * const aud_intbus_sel_parents[] = { + "clk26m", + "syspll1_d4", + "syspll4_d2", + "dmpll_d4" +}; + +static const char * const pmicspi_sel_parents[] = { + "clk26m", + "syspll1_d8", + "syspll3_d4", + "syspll1_d16", + "univpll3_d4", + "univpll_d26", + "dmpll_d4", + "dmpll_d8" +}; + +static const char * const scp_sel_parents[] = { + "clk26m", + "syspll1_d8", + "dmpll_d2", + "dmpll_d4" +}; + +static const char * const atb_sel_parents[] = { + "clk26m", + "syspll1_d2", + "syspll_d5", + "dmpll" +}; + +static const char * const dpi0_sel_parents[] = { + "clk26m", + "tvdpll", + "tvdpll_d2", + "tvdpll_d4", + "dpi_ck" +}; + +static const char * const scam_sel_parents[] = { + "clk26m", + "syspll3_d2", + "univpll2_d4", + "vencpll_d3" +}; + +static const char * const mfg13m_sel_parents[] = { + "clk26m", + "ad_sys_26m_d2" +}; + +static const char * const aud_1_2_sel_parents[] = { + "clk26m", + "apll1" +}; + +static const char * const irda_sel_parents[] = { + "clk26m", + "univpll2_d4" +}; + +static const char * const irtx_sel_parents[] = { + "clk26m", + "ad_sys_26m_ck" +}; + +static const char * const disppwm_sel_parents[] = { + "clk26m", + "univpll2_d4", + "syspll4_d2_d8", + "ad_sys_26m_ck" +}; + +static const struct mtk_mux topckgen_muxes[] = { + MUX_CLR_SET_UPD(CLK_TOP_AXI_SEL, "axi_sel", axi_sel_parents, CLK_CFG_0, CLK_CFG_0_SET, CLK_CFG_0_CLR, 0, 3, 0, 0), + MUX_CLR_SET_UPD(CLK_TOP_MEM_SEL, "mem_sel", mem_sel_parents, CLK_CFG_0, CLK_CFG_0_SET, CLK_CFG_0_CLR, 8, 1, 0, 0), + MUX_CLR_SET_UPD(CLK_TOP_DDRPHY_SEL, "ddrphycfg_sel", ddrphycfg_parents, CLK_CFG_0, CLK_CFG_0_SET, CLK_CFG_0_CLR, 16, 1, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MM_SEL, "mm_sel", mm_sel_parents, CLK_CFG_0, CLK_CFG_0_SET, CLK_CFG_0_CLR, 24, 3, 31, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", pwm_sel_parents, CLK_CFG_1, CLK_CFG_1_SET, CLK_CFG_1_CLR, 0, 2, 7, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_sel_parents, CLK_CFG_1, CLK_CFG_1_SET, CLK_CFG_1_CLR, 8, 3, 15, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MFG_SEL, "mfg_sel", mfg_sel_parents, CLK_CFG_1, CLK_CFG_1_SET, CLK_CFG_1_CLR, 16, 4, 23, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_sel_parents, CLK_CFG_1, CLK_CFG_1_SET, CLK_CFG_1_CLR, 24, 3, 31, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", uart_sel_parents, CLK_CFG_2, CLK_CFG_2_SET, CLK_CFG_2_CLR, 0, 1, 7, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", spi_sel_parents, CLK_CFG_2, CLK_CFG_2_SET, CLK_CFG_2_CLR, 8, 3, 15, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_USB20_SEL, "usb20_sel", usb20_sel_parents, CLK_CFG_2, CLK_CFG_2_SET, CLK_CFG_2_CLR, 16, 2, 23, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel", msdc50_0_sel_parents, CLK_CFG_2, CLK_CFG_2_SET, CLK_CFG_2_CLR, 24, 3, 31, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_0_sel_parents, CLK_CFG_3, CLK_CFG_3_SET, CLK_CFG_3_CLR, 0, 4, 7, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_1_2_sel_parents, CLK_CFG_3, CLK_CFG_3_SET, CLK_CFG_3_CLR, 8, 3, 15, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_1_2_sel_parents, CLK_CFG_3, CLK_CFG_3_SET, CLK_CFG_3_CLR, 16, 3, 23, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_3_sel_parents, CLK_CFG_3, CLK_CFG_3_SET, CLK_CFG_3_CLR, 24, 4, 31, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDIO_SEL, "audio_sel", audio_sel_parents, CLK_CFG_4, CLK_CFG_4_SET, CLK_CFG_4_CLR, 0, 2, 7, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUDINTBUS_SEL, "aud_intbus_sel", aud_intbus_sel_parents, CLK_CFG_4, CLK_CFG_4_SET, CLK_CFG_4_CLR, 8, 2, 15, 0, 0), + MUX_CLR_SET_UPD(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_sel_parents, CLK_CFG_4, CLK_CFG_4_SET, CLK_CFG_4_CLR, 16, 3, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_SCP_SEL, "scp_sel", scp_sel_parents, CLK_CFG_4, CLK_CFG_4_SET, CLK_CFG_4_CLR, 24, 2, 31, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_ATB_SEL, "atb_sel", atb_sel_parents, CLK_CFG_5, CLK_CFG_5_SET, CLK_CFG_5_CLR, 0, 2, 7, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_sel_parents, CLK_CFG_5, CLK_CFG_5_SET, CLK_CFG_5_CLR, 8, 3, 15, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_SCAM_SEL, "scam_sel", scam_sel_parents, CLK_CFG_5, CLK_CFG_5_SET, CLK_CFG_5_CLR, 16, 2, 23, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_MFG13M_SEL, "mfg13m_sel", mfg13m_sel_parents, CLK_CFG_5, CLK_CFG_5_SET, CLK_CFG_5_CLR, 24, 1, 31, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD1_SEL, "aud_1_sel", aud_1_2_sel_parents, CLK_CFG_6, CLK_CFG_6_SET, CLK_CFG_6_CLR, 0, 1, 7, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD2_SEL, "aud_2_sel", aud_1_2_sel_parents, CLK_CFG_6, CLK_CFG_6_SET, CLK_CFG_6_CLR, 8, 1, 15, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_IRDA_SEL, "irda_sel", irda_sel_parents, CLK_CFG_6, CLK_CFG_6_SET, CLK_CFG_6_CLR, 16, 1, 23, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_IRTX_SEL, "irtx_sel", irtx_sel_parents, CLK_CFG_6, CLK_CFG_6_SET, CLK_CFG_6_CLR, 24, 1, 31, 0, 0), + MUX_GATE_CLR_SET_UPD(CLK_TOP_DISPPWM_SEL, "disppwm_sel", disppwm_sel_parents, CLK_CFG_7, CLK_CFG_7_SET, CLK_CFG_7_CLR, 0, 2, 7, 0, 0), +}; + +static const struct mtk_clk_desc topckgen_desc = { + .fixed_clks = topckgen_fixed_clks, + .num_fixed_clks = ARRAY_SIZE(topckgen_fixed_clks), + .factor_clks = topckgen_factors, + .num_factor_clks = ARRAY_SIZE(topckgen_factors), + .mux_clks = topckgen_muxes, + .num_mux_clks = ARRAY_SIZE(topckgen_muxes), + .clk_lock = &mt6735_topckgen_lock, +}; + +static const struct of_device_id of_match_mt6735_topckgen[] = { + { .compatible = "mediatek,mt6735-topckgen", .data = &topckgen_desc}, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_match_mt6735_topckgen); + +static struct platform_driver clk_mt6735_topckgen = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt6735-topckgen", + .of_match_table = of_match_mt6735_topckgen, + }, +}; +module_platform_driver(clk_mt6735_topckgen); + +MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>"); +MODULE_DESCRIPTION("MediaTek MT6735 topckgen clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt6735-vdecsys.c b/drivers/clk/mediatek/clk-mt6735-vdecsys.c new file mode 100644 index 000000000000..8817085fc1db --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6735-vdecsys.c @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Yassine Oudjana <y.oudjana@protonmail.com> + */ + +#include <linux/clk-provider.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include <dt-bindings/clock/mediatek,mt6735-vdecsys.h> +#include <dt-bindings/reset/mediatek,mt6735-vdecsys.h> + +#define VDEC_CKEN_SET 0x00 +#define VDEC_CKEN_CLR 0x04 +#define SMI_LARB1_CKEN_SET 0x08 +#define SMI_LARB1_CKEN_CLR 0x0c +#define VDEC_RESETB_CON 0x10 +#define SMI_LARB1_RESETB_CON 0x14 + +#define RST_NR_PER_BANK 32 + +static struct mtk_gate_regs vdec_cg_regs = { + .set_ofs = VDEC_CKEN_SET, + .clr_ofs = VDEC_CKEN_CLR, + .sta_ofs = VDEC_CKEN_SET, +}; + +static struct mtk_gate_regs smi_larb1_cg_regs = { + .set_ofs = SMI_LARB1_CKEN_SET, + .clr_ofs = SMI_LARB1_CKEN_CLR, + .sta_ofs = SMI_LARB1_CKEN_SET, +}; + +static const struct mtk_gate vdecsys_gates[] = { + GATE_MTK(CLK_VDEC_VDEC, "vdec", "vdec_sel", &vdec_cg_regs, 0, &mtk_clk_gate_ops_setclr_inv), + GATE_MTK(CLK_VDEC_SMI_LARB1, "smi_larb1", "vdec_sel", &smi_larb1_cg_regs, 0, &mtk_clk_gate_ops_setclr_inv), +}; + +static u16 vdecsys_rst_bank_ofs[] = { VDEC_RESETB_CON, SMI_LARB1_RESETB_CON }; + +static u16 vdecsys_rst_idx_map[] = { + [MT6735_VDEC_RST0_VDEC] = 0 * RST_NR_PER_BANK + 0, + [MT6735_VDEC_RST1_SMI_LARB1] = 1 * RST_NR_PER_BANK + 0, +}; + +static const struct mtk_clk_rst_desc vdecsys_resets = { + .version = MTK_RST_SIMPLE, + .rst_bank_ofs = vdecsys_rst_bank_ofs, + .rst_bank_nr = ARRAY_SIZE(vdecsys_rst_bank_ofs), + .rst_idx_map = vdecsys_rst_idx_map, + .rst_idx_map_nr = ARRAY_SIZE(vdecsys_rst_idx_map) +}; + +static const struct mtk_clk_desc vdecsys_clks = { + .clks = vdecsys_gates, + .num_clks = ARRAY_SIZE(vdecsys_gates), + .rst_desc = &vdecsys_resets +}; + +static const struct of_device_id of_match_mt6735_vdecsys[] = { + { .compatible = "mediatek,mt6735-vdecsys", .data = &vdecsys_clks }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt6735_vdecsys = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt6735-vdecsys", + .of_match_table = of_match_mt6735_vdecsys, + }, +}; +module_platform_driver(clk_mt6735_vdecsys); + +MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>"); +MODULE_DESCRIPTION("MediaTek MT6735 vdecsys clock and reset driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt6735-vencsys.c b/drivers/clk/mediatek/clk-mt6735-vencsys.c new file mode 100644 index 000000000000..8dec7f98492a --- /dev/null +++ b/drivers/clk/mediatek/clk-mt6735-vencsys.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Yassine Oudjana <y.oudjana@protonmail.com> + */ + +#include <linux/clk-provider.h> +#include <linux/platform_device.h> + +#include "clk-gate.h" +#include "clk-mtk.h" + +#include <dt-bindings/clock/mediatek,mt6735-vencsys.h> + +#define VENC_CG_CON 0x00 +#define VENC_CG_SET 0x04 +#define VENC_CG_CLR 0x08 + +static struct mtk_gate_regs venc_cg_regs = { + .set_ofs = VENC_CG_SET, + .clr_ofs = VENC_CG_CLR, + .sta_ofs = VENC_CG_CON, +}; + +static const struct mtk_gate vencsys_gates[] = { + GATE_MTK(CLK_VENC_SMI_LARB3, "smi_larb3", "mm_sel", &venc_cg_regs, 0, &mtk_clk_gate_ops_setclr_inv), + GATE_MTK(CLK_VENC_VENC, "venc", "mm_sel", &venc_cg_regs, 4, &mtk_clk_gate_ops_setclr_inv), + GATE_MTK(CLK_VENC_JPGENC, "jpgenc", "mm_sel", &venc_cg_regs, 8, &mtk_clk_gate_ops_setclr_inv), + GATE_MTK(CLK_VENC_JPGDEC, "jpgdec", "mm_sel", &venc_cg_regs, 12, &mtk_clk_gate_ops_setclr_inv), +}; + +static const struct mtk_clk_desc vencsys_clks = { + .clks = vencsys_gates, + .num_clks = ARRAY_SIZE(vencsys_gates), +}; + +static const struct of_device_id of_match_mt6735_vencsys[] = { + { .compatible = "mediatek,mt6735-vencsys", .data = &vencsys_clks }, + { /* sentinel */ } +}; + +static struct platform_driver clk_mt6735_vencsys = { + .probe = mtk_clk_simple_probe, + .remove = mtk_clk_simple_remove, + .driver = { + .name = "clk-mt6735-vencsys", + .of_match_table = of_match_mt6735_vencsys, + }, +}; +module_platform_driver(clk_mt6735_vencsys); + +MODULE_AUTHOR("Yassine Oudjana <y.oudjana@protonmail.com>"); +MODULE_DESCRIPTION("Mediatek MT6735 vencsys clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/mediatek/clk-mt8188-topckgen.c b/drivers/clk/mediatek/clk-mt8188-topckgen.c index c4baf4076ed6..6b07abe9a8f5 100644 --- a/drivers/clk/mediatek/clk-mt8188-topckgen.c +++ b/drivers/clk/mediatek/clk-mt8188-topckgen.c @@ -342,11 +342,14 @@ static const char * const dsp7_parents[] = { "univpll_d3" }; +/* + * MFG can be also parented to "univpll_d6" and "univpll_d7": + * these have been removed from the parents list to let us + * achieve GPU DVFS without any special clock handlers. + */ static const char * const mfg_core_tmp_parents[] = { "clk26m", - "mainpll_d5_d2", - "univpll_d6", - "univpll_d7" + "mainpll_d5_d2" }; static const char * const camtg_parents[] = { diff --git a/drivers/clk/ralink/clk-mtmips.c b/drivers/clk/ralink/clk-mtmips.c index 50a443bf79ec..97b8ca0f9181 100644 --- a/drivers/clk/ralink/clk-mtmips.c +++ b/drivers/clk/ralink/clk-mtmips.c @@ -207,6 +207,7 @@ static struct mtmips_clk mt7620_pherip_clks[] = { { CLK_PERIPH("10000b00.spi", "bus") }, { CLK_PERIPH("10000b40.spi", "bus") }, { CLK_PERIPH("10000c00.uartlite", "periph") }, + { CLK_PERIPH("10130000.mmc", "sdhc") }, { CLK_PERIPH("10180000.wmac", "xtal") } }; @@ -220,6 +221,7 @@ static struct mtmips_clk mt76x8_pherip_clks[] = { { CLK_PERIPH("10000c00.uart0", "periph") }, { CLK_PERIPH("10000d00.uart1", "periph") }, { CLK_PERIPH("10000e00.uart2", "periph") }, + { CLK_PERIPH("10130000.mmc", "sdhc") }, { CLK_PERIPH("10300000.wmac", "xtal") } }; @@ -263,16 +265,22 @@ err_clk_unreg: .rate = _rate \ } -static struct mtmips_clk_fixed rt305x_fixed_clocks[] = { - CLK_FIXED("xtal", NULL, 40000000) +static struct mtmips_clk_fixed rt3883_fixed_clocks[] = { + CLK_FIXED("xtal", NULL, 40000000), + CLK_FIXED("periph", "xtal", 40000000) }; static struct mtmips_clk_fixed rt3352_fixed_clocks[] = { CLK_FIXED("periph", "xtal", 40000000) }; +static struct mtmips_clk_fixed mt7620_fixed_clocks[] = { + CLK_FIXED("bbppll", "xtal", 480000000) +}; + static struct mtmips_clk_fixed mt76x8_fixed_clocks[] = { - CLK_FIXED("pcmi2s", "xtal", 480000000), + CLK_FIXED("bbppll", "xtal", 480000000), + CLK_FIXED("pcmi2s", "bbppll", 480000000), CLK_FIXED("periph", "xtal", 40000000) }; @@ -327,6 +335,15 @@ static struct mtmips_clk_factor rt305x_factor_clocks[] = { CLK_FACTOR("bus", "cpu", 1, 3) }; +static struct mtmips_clk_factor mt7620_factor_clocks[] = { + CLK_FACTOR("sdhc", "bbppll", 1, 10) +}; + +static struct mtmips_clk_factor mt76x8_factor_clocks[] = { + CLK_FACTOR("bus", "cpu", 1, 3), + CLK_FACTOR("sdhc", "bbppll", 1, 10) +}; + static int mtmips_register_factor_clocks(struct clk_hw_onecell_data *clk_data, struct mtmips_clk_priv *priv) { @@ -366,6 +383,12 @@ static inline struct mtmips_clk *to_mtmips_clk(struct clk_hw *hw) return container_of(hw, struct mtmips_clk, hw); } +static unsigned long rt2880_xtal_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return 40000000; +} + static unsigned long rt5350_xtal_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -677,10 +700,12 @@ static unsigned long mt76x8_cpu_recalc_rate(struct clk_hw *hw, } static struct mtmips_clk rt2880_clks_base[] = { + { CLK_BASE("xtal", NULL, rt2880_xtal_recalc_rate) }, { CLK_BASE("cpu", "xtal", rt2880_cpu_recalc_rate) } }; static struct mtmips_clk rt305x_clks_base[] = { + { CLK_BASE("xtal", NULL, rt2880_xtal_recalc_rate) }, { CLK_BASE("cpu", "xtal", rt305x_cpu_recalc_rate) } }; @@ -690,6 +715,7 @@ static struct mtmips_clk rt3352_clks_base[] = { }; static struct mtmips_clk rt3883_clks_base[] = { + { CLK_BASE("xtal", NULL, rt2880_xtal_recalc_rate) }, { CLK_BASE("cpu", "xtal", rt3883_cpu_recalc_rate) }, { CLK_BASE("bus", "cpu", rt3883_bus_recalc_rate) } }; @@ -746,8 +772,8 @@ err_clk_unreg: static const struct mtmips_clk_data rt2880_clk_data = { .clk_base = rt2880_clks_base, .num_clk_base = ARRAY_SIZE(rt2880_clks_base), - .clk_fixed = rt305x_fixed_clocks, - .num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks), + .clk_fixed = NULL, + .num_clk_fixed = 0, .clk_factor = rt2880_factor_clocks, .num_clk_factor = ARRAY_SIZE(rt2880_factor_clocks), .clk_periph = rt2880_pherip_clks, @@ -757,8 +783,8 @@ static const struct mtmips_clk_data rt2880_clk_data = { static const struct mtmips_clk_data rt305x_clk_data = { .clk_base = rt305x_clks_base, .num_clk_base = ARRAY_SIZE(rt305x_clks_base), - .clk_fixed = rt305x_fixed_clocks, - .num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks), + .clk_fixed = NULL, + .num_clk_fixed = 0, .clk_factor = rt305x_factor_clocks, .num_clk_factor = ARRAY_SIZE(rt305x_factor_clocks), .clk_periph = rt305x_pherip_clks, @@ -779,8 +805,8 @@ static const struct mtmips_clk_data rt3352_clk_data = { static const struct mtmips_clk_data rt3883_clk_data = { .clk_base = rt3883_clks_base, .num_clk_base = ARRAY_SIZE(rt3883_clks_base), - .clk_fixed = rt305x_fixed_clocks, - .num_clk_fixed = ARRAY_SIZE(rt305x_fixed_clocks), + .clk_fixed = rt3883_fixed_clocks, + .num_clk_fixed = ARRAY_SIZE(rt3883_fixed_clocks), .clk_factor = NULL, .num_clk_factor = 0, .clk_periph = rt5350_pherip_clks, @@ -801,10 +827,10 @@ static const struct mtmips_clk_data rt5350_clk_data = { static const struct mtmips_clk_data mt7620_clk_data = { .clk_base = mt7620_clks_base, .num_clk_base = ARRAY_SIZE(mt7620_clks_base), - .clk_fixed = NULL, - .num_clk_fixed = 0, - .clk_factor = NULL, - .num_clk_factor = 0, + .clk_fixed = mt7620_fixed_clocks, + .num_clk_fixed = ARRAY_SIZE(mt7620_fixed_clocks), + .clk_factor = mt7620_factor_clocks, + .num_clk_factor = ARRAY_SIZE(mt7620_factor_clocks), .clk_periph = mt7620_pherip_clks, .num_clk_periph = ARRAY_SIZE(mt7620_pherip_clks), }; @@ -814,8 +840,8 @@ static const struct mtmips_clk_data mt76x8_clk_data = { .num_clk_base = ARRAY_SIZE(mt76x8_clks_base), .clk_fixed = mt76x8_fixed_clocks, .num_clk_fixed = ARRAY_SIZE(mt76x8_fixed_clocks), - .clk_factor = rt305x_factor_clocks, - .num_clk_factor = ARRAY_SIZE(rt305x_factor_clocks), + .clk_factor = mt76x8_factor_clocks, + .num_clk_factor = ARRAY_SIZE(mt76x8_factor_clocks), .clk_periph = mt76x8_pherip_clks, .num_clk_periph = ARRAY_SIZE(mt76x8_pherip_clks), }; diff --git a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c index 7a0269bdfbb3..b2233d3ff9a9 100644 --- a/drivers/clk/xilinx/clk-xlnx-clock-wizard.c +++ b/drivers/clk/xilinx/clk-xlnx-clock-wizard.c @@ -17,6 +17,7 @@ #include <linux/of.h> #include <linux/math64.h> #include <linux/module.h> +#include <linux/overflow.h> #include <linux/err.h> #include <linux/iopoll.h> @@ -121,26 +122,24 @@ enum clk_wzrd_int_clks { /** * struct clk_wzrd - Clock wizard private data structure * - * @clk_data: Clock data * @nb: Notifier block * @base: Memory base * @clk_in1: Handle to input clock 'clk_in1' * @axi_clk: Handle to input clock 's_axi_aclk' * @clks_internal: Internal clocks - * @clkout: Output clocks * @speed_grade: Speed grade of the device * @suspended: Flag indicating power state of the device + * @clk_data: Output clock data */ struct clk_wzrd { - struct clk_onecell_data clk_data; struct notifier_block nb; void __iomem *base; struct clk *clk_in1; struct clk *axi_clk; - struct clk *clks_internal[wzrd_clk_int_max]; - struct clk *clkout[WZRD_NUM_OUTPUTS]; + struct clk_hw *clks_internal[wzrd_clk_int_max]; unsigned int speed_grade; bool suspended; + struct clk_hw_onecell_data clk_data; }; /** @@ -765,7 +764,7 @@ static const struct clk_ops clk_wzrd_clk_divider_ops_f = { .recalc_rate = clk_wzrd_recalc_ratef, }; -static struct clk *clk_wzrd_register_divf(struct device *dev, +static struct clk_hw *clk_wzrd_register_divf(struct device *dev, const char *name, const char *parent_name, unsigned long flags, @@ -805,10 +804,10 @@ static struct clk *clk_wzrd_register_divf(struct device *dev, if (ret) return ERR_PTR(ret); - return hw->clk; + return hw; } -static struct clk *clk_wzrd_ver_register_divider(struct device *dev, +static struct clk_hw *clk_wzrd_ver_register_divider(struct device *dev, const char *name, const char *parent_name, unsigned long flags, @@ -852,10 +851,10 @@ static struct clk *clk_wzrd_ver_register_divider(struct device *dev, if (ret) return ERR_PTR(ret); - return hw->clk; + return hw; } -static struct clk *clk_wzrd_register_divider(struct device *dev, +static struct clk_hw *clk_wzrd_register_divider(struct device *dev, const char *name, const char *parent_name, unsigned long flags, @@ -898,7 +897,7 @@ static struct clk *clk_wzrd_register_divider(struct device *dev, if (ret) return ERR_PTR(ret); - return hw->clk; + return hw; } static int clk_wzrd_clk_notifier(struct notifier_block *nb, unsigned long event, @@ -963,81 +962,30 @@ static const struct versal_clk_data versal_data = { .is_versal = true, }; -static int clk_wzrd_probe(struct platform_device *pdev) +static int clk_wzrd_register_output_clocks(struct device *dev, int nr_outputs) { const char *clkout_name, *clk_name, *clk_mul_name; + struct clk_wzrd *clk_wzrd = dev_get_drvdata(dev); u32 regl, regh, edge, regld, reghd, edged, div; - struct device_node *np = pdev->dev.of_node; const struct versal_clk_data *data; - struct clk_wzrd *clk_wzrd; unsigned long flags = 0; + bool is_versal = false; void __iomem *ctrl_reg; u32 reg, reg_f, mult; - bool is_versal = false; - unsigned long rate; - int nr_outputs; - int i, ret; - - clk_wzrd = devm_kzalloc(&pdev->dev, sizeof(*clk_wzrd), GFP_KERNEL); - if (!clk_wzrd) - return -ENOMEM; - platform_set_drvdata(pdev, clk_wzrd); - - clk_wzrd->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(clk_wzrd->base)) - return PTR_ERR(clk_wzrd->base); - - ret = of_property_read_u32(np, "xlnx,speed-grade", &clk_wzrd->speed_grade); - if (!ret) { - if (clk_wzrd->speed_grade < 1 || clk_wzrd->speed_grade > 3) { - dev_warn(&pdev->dev, "invalid speed grade '%d'\n", - clk_wzrd->speed_grade); - clk_wzrd->speed_grade = 0; - } - } - - clk_wzrd->clk_in1 = devm_clk_get(&pdev->dev, "clk_in1"); - if (IS_ERR(clk_wzrd->clk_in1)) - return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->clk_in1), - "clk_in1 not found\n"); - - clk_wzrd->axi_clk = devm_clk_get(&pdev->dev, "s_axi_aclk"); - if (IS_ERR(clk_wzrd->axi_clk)) - return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->axi_clk), - "s_axi_aclk not found\n"); - ret = clk_prepare_enable(clk_wzrd->axi_clk); - if (ret) { - dev_err(&pdev->dev, "enabling s_axi_aclk failed\n"); - return ret; - } - rate = clk_get_rate(clk_wzrd->axi_clk); - if (rate > WZRD_ACLK_MAX_FREQ) { - dev_err(&pdev->dev, "s_axi_aclk frequency (%lu) too high\n", - rate); - ret = -EINVAL; - goto err_disable_clk; - } + int i; - data = device_get_match_data(&pdev->dev); + data = device_get_match_data(dev); if (data) is_versal = data->is_versal; - ret = of_property_read_u32(np, "xlnx,nr-outputs", &nr_outputs); - if (ret || nr_outputs > WZRD_NUM_OUTPUTS) { - ret = -EINVAL; - goto err_disable_clk; - } - - clkout_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_out0", dev_name(&pdev->dev)); - if (!clkout_name) { - ret = -ENOMEM; - goto err_disable_clk; - } + clkout_name = devm_kasprintf(dev, GFP_KERNEL, "%s_out0", dev_name(dev)); + if (!clkout_name) + return -ENOMEM; if (is_versal) { if (nr_outputs == 1) { - clk_wzrd->clkout[0] = clk_wzrd_ver_register_divider - (&pdev->dev, clkout_name, + clk_wzrd->clk_data.hws[0] = clk_wzrd_ver_register_divider + (dev, clkout_name, __clk_get_name(clk_wzrd->clk_in1), 0, clk_wzrd->base, WZRD_CLK_CFG_REG(is_versal, 3), WZRD_CLKOUT_DIVIDE_SHIFT, @@ -1045,7 +993,7 @@ static int clk_wzrd_probe(struct platform_device *pdev) CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, DIV_ALL, &clkwzrd_lock); - goto out; + return 0; } /* register multiplier */ edge = !!(readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0)) & @@ -1069,8 +1017,8 @@ static int clk_wzrd_probe(struct platform_device *pdev) div = 64; } else { if (nr_outputs == 1) { - clk_wzrd->clkout[0] = clk_wzrd_register_divider - (&pdev->dev, clkout_name, + clk_wzrd->clk_data.hws[0] = clk_wzrd_register_divider + (dev, clkout_name, __clk_get_name(clk_wzrd->clk_in1), 0, clk_wzrd->base, WZRD_CLK_CFG_REG(is_versal, 3), WZRD_CLKOUT_DIVIDE_SHIFT, @@ -1078,7 +1026,7 @@ static int clk_wzrd_probe(struct platform_device *pdev) CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, DIV_ALL, &clkwzrd_lock); - goto out; + return 0; } reg = readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0)); reg_f = reg & WZRD_CLKFBOUT_FRAC_MASK; @@ -1089,26 +1037,21 @@ static int clk_wzrd_probe(struct platform_device *pdev) mult = (reg * 1000) + reg_f; div = 1000; } - clk_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_mul", dev_name(&pdev->dev)); - if (!clk_name) { - ret = -ENOMEM; - goto err_disable_clk; - } - clk_wzrd->clks_internal[wzrd_clk_mul] = clk_register_fixed_factor - (&pdev->dev, clk_name, + clk_name = devm_kasprintf(dev, GFP_KERNEL, "%s_mul", dev_name(dev)); + if (!clk_name) + return -ENOMEM; + clk_wzrd->clks_internal[wzrd_clk_mul] = devm_clk_hw_register_fixed_factor + (dev, clk_name, __clk_get_name(clk_wzrd->clk_in1), 0, mult, div); if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul])) { - dev_err(&pdev->dev, "unable to register fixed-factor clock\n"); - ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul]); - goto err_disable_clk; + dev_err(dev, "unable to register fixed-factor clock\n"); + return PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul]); } - clk_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%s_mul_div", dev_name(&pdev->dev)); - if (!clk_name) { - ret = -ENOMEM; - goto err_rm_int_clk; - } + clk_name = devm_kasprintf(dev, GFP_KERNEL, "%s_mul_div", dev_name(dev)); + if (!clk_name) + return -ENOMEM; if (is_versal) { edged = !!(readl(clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 20)) & @@ -1121,36 +1064,31 @@ static int clk_wzrd_probe(struct platform_device *pdev) if (!div) div = 1; - clk_mul_name = __clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]); + clk_mul_name = clk_hw_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]); clk_wzrd->clks_internal[wzrd_clk_mul_div] = - clk_register_fixed_factor(&pdev->dev, clk_name, - clk_mul_name, 0, 1, div); + devm_clk_hw_register_fixed_factor(dev, clk_name, clk_mul_name, 0, 1, div); } else { ctrl_reg = clk_wzrd->base + WZRD_CLK_CFG_REG(is_versal, 0); - clk_wzrd->clks_internal[wzrd_clk_mul_div] = clk_register_divider - (&pdev->dev, clk_name, - __clk_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]), + clk_wzrd->clks_internal[wzrd_clk_mul_div] = devm_clk_hw_register_divider + (dev, clk_name, + clk_hw_get_name(clk_wzrd->clks_internal[wzrd_clk_mul]), flags, ctrl_reg, 0, 8, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, &clkwzrd_lock); } if (IS_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div])) { - dev_err(&pdev->dev, "unable to register divider clock\n"); - ret = PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div]); - goto err_rm_int_clk; + dev_err(dev, "unable to register divider clock\n"); + return PTR_ERR(clk_wzrd->clks_internal[wzrd_clk_mul_div]); } /* register div per output */ for (i = nr_outputs - 1; i >= 0 ; i--) { - clkout_name = devm_kasprintf(&pdev->dev, GFP_KERNEL, - "%s_out%d", dev_name(&pdev->dev), i); - if (!clkout_name) { - ret = -ENOMEM; - goto err_rm_int_clk; - } + clkout_name = devm_kasprintf(dev, GFP_KERNEL, "%s_out%d", dev_name(dev), i); + if (!clkout_name) + return -ENOMEM; if (is_versal) { - clk_wzrd->clkout[i] = clk_wzrd_ver_register_divider - (&pdev->dev, + clk_wzrd->clk_data.hws[i] = clk_wzrd_ver_register_divider + (dev, clkout_name, clk_name, 0, clk_wzrd->base, (WZRD_CLK_CFG_REG(is_versal, 3) + i * 8), @@ -1161,84 +1099,108 @@ static int clk_wzrd_probe(struct platform_device *pdev) DIV_O, &clkwzrd_lock); } else { if (!i) - clk_wzrd->clkout[i] = clk_wzrd_register_divf - (&pdev->dev, clkout_name, clk_name, flags, clk_wzrd->base, + clk_wzrd->clk_data.hws[i] = clk_wzrd_register_divf + (dev, clkout_name, clk_name, flags, clk_wzrd->base, (WZRD_CLK_CFG_REG(is_versal, 2) + i * 12), WZRD_CLKOUT_DIVIDE_SHIFT, WZRD_CLKOUT_DIVIDE_WIDTH, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, DIV_O, &clkwzrd_lock); else - clk_wzrd->clkout[i] = clk_wzrd_register_divider - (&pdev->dev, clkout_name, clk_name, 0, clk_wzrd->base, + clk_wzrd->clk_data.hws[i] = clk_wzrd_register_divider + (dev, clkout_name, clk_name, 0, clk_wzrd->base, (WZRD_CLK_CFG_REG(is_versal, 2) + i * 12), WZRD_CLKOUT_DIVIDE_SHIFT, WZRD_CLKOUT_DIVIDE_WIDTH, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, DIV_O, &clkwzrd_lock); } - if (IS_ERR(clk_wzrd->clkout[i])) { - int j; - - for (j = i + 1; j < nr_outputs; j++) - clk_unregister(clk_wzrd->clkout[j]); - dev_err(&pdev->dev, - "unable to register divider clock\n"); - ret = PTR_ERR(clk_wzrd->clkout[i]); - goto err_rm_int_clks; + if (IS_ERR(clk_wzrd->clk_data.hws[i])) { + dev_err(dev, "unable to register divider clock\n"); + return PTR_ERR(clk_wzrd->clk_data.hws[i]); } } -out: - clk_wzrd->clk_data.clks = clk_wzrd->clkout; - clk_wzrd->clk_data.clk_num = ARRAY_SIZE(clk_wzrd->clkout); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_wzrd->clk_data); + return 0; +} - if (clk_wzrd->speed_grade) { - clk_wzrd->nb.notifier_call = clk_wzrd_clk_notifier; +static int clk_wzrd_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct clk_wzrd *clk_wzrd; + unsigned long rate; + int nr_outputs; + int ret; - ret = clk_notifier_register(clk_wzrd->clk_in1, - &clk_wzrd->nb); - if (ret) - dev_warn(&pdev->dev, - "unable to register clock notifier\n"); + ret = of_property_read_u32(np, "xlnx,nr-outputs", &nr_outputs); + if (ret || nr_outputs > WZRD_NUM_OUTPUTS) + return -EINVAL; - ret = clk_notifier_register(clk_wzrd->axi_clk, &clk_wzrd->nb); - if (ret) - dev_warn(&pdev->dev, - "unable to register clock notifier\n"); - } + clk_wzrd = devm_kzalloc(&pdev->dev, struct_size(clk_wzrd, clk_data.hws, nr_outputs), + GFP_KERNEL); + if (!clk_wzrd) + return -ENOMEM; + platform_set_drvdata(pdev, clk_wzrd); - return 0; + clk_wzrd->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(clk_wzrd->base)) + return PTR_ERR(clk_wzrd->base); -err_rm_int_clks: - clk_unregister(clk_wzrd->clks_internal[1]); -err_rm_int_clk: - clk_unregister(clk_wzrd->clks_internal[0]); -err_disable_clk: - clk_disable_unprepare(clk_wzrd->axi_clk); + clk_wzrd->axi_clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk"); + if (IS_ERR(clk_wzrd->axi_clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->axi_clk), + "s_axi_aclk not found\n"); + rate = clk_get_rate(clk_wzrd->axi_clk); + if (rate > WZRD_ACLK_MAX_FREQ) { + dev_err(&pdev->dev, "s_axi_aclk frequency (%lu) too high\n", rate); + return -EINVAL; + } - return ret; -} + if (!of_property_present(np, "xlnx,static-config")) { + ret = of_property_read_u32(np, "xlnx,speed-grade", &clk_wzrd->speed_grade); + if (!ret) { + if (clk_wzrd->speed_grade < 1 || clk_wzrd->speed_grade > 3) { + dev_warn(&pdev->dev, "invalid speed grade '%d'\n", + clk_wzrd->speed_grade); + clk_wzrd->speed_grade = 0; + } + } -static void clk_wzrd_remove(struct platform_device *pdev) -{ - int i; - struct clk_wzrd *clk_wzrd = platform_get_drvdata(pdev); + clk_wzrd->clk_in1 = devm_clk_get(&pdev->dev, "clk_in1"); + if (IS_ERR(clk_wzrd->clk_in1)) + return dev_err_probe(&pdev->dev, PTR_ERR(clk_wzrd->clk_in1), + "clk_in1 not found\n"); + + ret = clk_wzrd_register_output_clocks(&pdev->dev, nr_outputs); + if (ret) + return ret; + + clk_wzrd->clk_data.num = nr_outputs; + ret = devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get, + &clk_wzrd->clk_data); + if (ret) { + dev_err(&pdev->dev, "unable to register clock provider\n"); + return ret; + } - of_clk_del_provider(pdev->dev.of_node); + if (clk_wzrd->speed_grade) { + clk_wzrd->nb.notifier_call = clk_wzrd_clk_notifier; - for (i = 0; i < WZRD_NUM_OUTPUTS; i++) - clk_unregister(clk_wzrd->clkout[i]); - for (i = 0; i < wzrd_clk_int_max; i++) - clk_unregister(clk_wzrd->clks_internal[i]); + ret = devm_clk_notifier_register(&pdev->dev, clk_wzrd->clk_in1, + &clk_wzrd->nb); + if (ret) + dev_warn(&pdev->dev, + "unable to register clock notifier\n"); - if (clk_wzrd->speed_grade) { - clk_notifier_unregister(clk_wzrd->axi_clk, &clk_wzrd->nb); - clk_notifier_unregister(clk_wzrd->clk_in1, &clk_wzrd->nb); + ret = devm_clk_notifier_register(&pdev->dev, clk_wzrd->axi_clk, + &clk_wzrd->nb); + if (ret) + dev_warn(&pdev->dev, + "unable to register clock notifier\n"); + } } - clk_disable_unprepare(clk_wzrd->axi_clk); + return 0; } static const struct of_device_id clk_wzrd_ids[] = { @@ -1257,7 +1219,6 @@ static struct platform_driver clk_wzrd_driver = { .pm = &clk_wzrd_dev_pm_ops, }, .probe = clk_wzrd_probe, - .remove = clk_wzrd_remove, }; module_platform_driver(clk_wzrd_driver); diff --git a/include/dt-bindings/clock/mediatek,mt6735-apmixedsys.h b/include/dt-bindings/clock/mediatek,mt6735-apmixedsys.h new file mode 100644 index 000000000000..b4705204409c --- /dev/null +++ b/include/dt-bindings/clock/mediatek,mt6735-apmixedsys.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef _DT_BINDINGS_CLK_MT6735_APMIXEDSYS_H +#define _DT_BINDINGS_CLK_MT6735_APMIXEDSYS_H + +#define CLK_APMIXED_ARMPLL 0 +#define CLK_APMIXED_MAINPLL 1 +#define CLK_APMIXED_UNIVPLL 2 +#define CLK_APMIXED_MMPLL 3 +#define CLK_APMIXED_MSDCPLL 4 +#define CLK_APMIXED_VENCPLL 5 +#define CLK_APMIXED_TVDPLL 6 +#define CLK_APMIXED_APLL1 7 +#define CLK_APMIXED_APLL2 8 + +#endif diff --git a/include/dt-bindings/clock/mediatek,mt6735-imgsys.h b/include/dt-bindings/clock/mediatek,mt6735-imgsys.h new file mode 100644 index 000000000000..f250c26c5eb4 --- /dev/null +++ b/include/dt-bindings/clock/mediatek,mt6735-imgsys.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef _DT_BINDINGS_CLK_MT6735_IMGSYS_H +#define _DT_BINDINGS_CLK_MT6735_IMGSYS_H + +#define CLK_IMG_SMI_LARB2 0 +#define CLK_IMG_CAM_SMI 1 +#define CLK_IMG_CAM_CAM 2 +#define CLK_IMG_SEN_TG 3 +#define CLK_IMG_SEN_CAM 4 +#define CLK_IMG_CAM_SV 5 +#define CLK_IMG_SUFOD 6 +#define CLK_IMG_FD 7 + +#endif /* _DT_BINDINGS_CLK_MT6735_IMGSYS_H */ diff --git a/include/dt-bindings/clock/mediatek,mt6735-infracfg.h b/include/dt-bindings/clock/mediatek,mt6735-infracfg.h new file mode 100644 index 000000000000..d8dd51e15637 --- /dev/null +++ b/include/dt-bindings/clock/mediatek,mt6735-infracfg.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef _DT_BINDINGS_CLK_MT6735_INFRACFG_H +#define _DT_BINDINGS_CLK_MT6735_INFRACFG_H + +#define CLK_INFRA_DBG 0 +#define CLK_INFRA_GCE 1 +#define CLK_INFRA_TRBG 2 +#define CLK_INFRA_CPUM 3 +#define CLK_INFRA_DEVAPC 4 +#define CLK_INFRA_AUDIO 5 +#define CLK_INFRA_GCPU 6 +#define CLK_INFRA_L2C_SRAM 7 +#define CLK_INFRA_M4U 8 +#define CLK_INFRA_CLDMA 9 +#define CLK_INFRA_CONNMCU_BUS 10 +#define CLK_INFRA_KP 11 +#define CLK_INFRA_APXGPT 12 +#define CLK_INFRA_SEJ 13 +#define CLK_INFRA_CCIF0_AP 14 +#define CLK_INFRA_CCIF1_AP 15 +#define CLK_INFRA_PMIC_SPI 16 +#define CLK_INFRA_PMIC_WRAP 17 + +#endif diff --git a/include/dt-bindings/clock/mediatek,mt6735-mfgcfg.h b/include/dt-bindings/clock/mediatek,mt6735-mfgcfg.h new file mode 100644 index 000000000000..d2d99a48348a --- /dev/null +++ b/include/dt-bindings/clock/mediatek,mt6735-mfgcfg.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef _DT_BINDINGS_CLK_MT6735_MFGCFG_H +#define _DT_BINDINGS_CLK_MT6735_MFGCFG_H + +#define CLK_MFG_BG3D 0 + +#endif /* _DT_BINDINGS_CLK_MT6735_MFGCFG_H */ diff --git a/include/dt-bindings/clock/mediatek,mt6735-pericfg.h b/include/dt-bindings/clock/mediatek,mt6735-pericfg.h new file mode 100644 index 000000000000..16bc21bbd95b --- /dev/null +++ b/include/dt-bindings/clock/mediatek,mt6735-pericfg.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef _DT_BINDINGS_CLK_MT6735_PERICFG_H +#define _DT_BINDINGS_CLK_MT6735_PERICFG_H + +#define CLK_PERI_DISP_PWM 0 +#define CLK_PERI_THERM 1 +#define CLK_PERI_PWM1 2 +#define CLK_PERI_PWM2 3 +#define CLK_PERI_PWM3 4 +#define CLK_PERI_PWM4 5 +#define CLK_PERI_PWM5 6 +#define CLK_PERI_PWM6 7 +#define CLK_PERI_PWM7 8 +#define CLK_PERI_PWM 9 +#define CLK_PERI_USB0 10 +#define CLK_PERI_IRDA 11 +#define CLK_PERI_APDMA 12 +#define CLK_PERI_MSDC30_0 13 +#define CLK_PERI_MSDC30_1 14 +#define CLK_PERI_MSDC30_2 15 +#define CLK_PERI_MSDC30_3 16 +#define CLK_PERI_UART0 17 +#define CLK_PERI_UART1 18 +#define CLK_PERI_UART2 19 +#define CLK_PERI_UART3 20 +#define CLK_PERI_UART4 21 +#define CLK_PERI_BTIF 22 +#define CLK_PERI_I2C0 23 +#define CLK_PERI_I2C1 24 +#define CLK_PERI_I2C2 25 +#define CLK_PERI_I2C3 26 +#define CLK_PERI_AUXADC 27 +#define CLK_PERI_SPI0 28 +#define CLK_PERI_IRTX 29 + +#endif diff --git a/include/dt-bindings/clock/mediatek,mt6735-topckgen.h b/include/dt-bindings/clock/mediatek,mt6735-topckgen.h new file mode 100644 index 000000000000..d4b1e113cc0a --- /dev/null +++ b/include/dt-bindings/clock/mediatek,mt6735-topckgen.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef _DT_BINDINGS_CLK_MT6735_TOPCKGEN_H +#define _DT_BINDINGS_CLK_MT6735_TOPCKGEN_H + +#define CLK_TOP_AD_SYS_26M_CK 0 +#define CLK_TOP_CLKPH_MCK_O 1 +#define CLK_TOP_DMPLL 2 +#define CLK_TOP_DPI_CK 3 +#define CLK_TOP_WHPLL_AUDIO_CK 4 + +#define CLK_TOP_SYSPLL_D2 5 +#define CLK_TOP_SYSPLL_D3 6 +#define CLK_TOP_SYSPLL_D5 7 +#define CLK_TOP_SYSPLL1_D2 8 +#define CLK_TOP_SYSPLL1_D4 9 +#define CLK_TOP_SYSPLL1_D8 10 +#define CLK_TOP_SYSPLL1_D16 11 +#define CLK_TOP_SYSPLL2_D2 12 +#define CLK_TOP_SYSPLL2_D4 13 +#define CLK_TOP_SYSPLL3_D2 14 +#define CLK_TOP_SYSPLL3_D4 15 +#define CLK_TOP_SYSPLL4_D2 16 +#define CLK_TOP_SYSPLL4_D4 17 +#define CLK_TOP_UNIVPLL_D2 18 +#define CLK_TOP_UNIVPLL_D3 19 +#define CLK_TOP_UNIVPLL_D5 20 +#define CLK_TOP_UNIVPLL_D26 21 +#define CLK_TOP_UNIVPLL1_D2 22 +#define CLK_TOP_UNIVPLL1_D4 23 +#define CLK_TOP_UNIVPLL1_D8 24 +#define CLK_TOP_UNIVPLL2_D2 25 +#define CLK_TOP_UNIVPLL2_D4 26 +#define CLK_TOP_UNIVPLL2_D8 27 +#define CLK_TOP_UNIVPLL3_D2 28 +#define CLK_TOP_UNIVPLL3_D4 29 +#define CLK_TOP_MSDCPLL_D2 30 +#define CLK_TOP_MSDCPLL_D4 31 +#define CLK_TOP_MSDCPLL_D8 32 +#define CLK_TOP_MSDCPLL_D16 33 +#define CLK_TOP_VENCPLL_D3 34 +#define CLK_TOP_TVDPLL_D2 35 +#define CLK_TOP_TVDPLL_D4 36 +#define CLK_TOP_DMPLL_D2 37 +#define CLK_TOP_DMPLL_D4 38 +#define CLK_TOP_DMPLL_D8 39 +#define CLK_TOP_AD_SYS_26M_D2 40 + +#define CLK_TOP_AXI_SEL 41 +#define CLK_TOP_MEM_SEL 42 +#define CLK_TOP_DDRPHY_SEL 43 +#define CLK_TOP_MM_SEL 44 +#define CLK_TOP_PWM_SEL 45 +#define CLK_TOP_VDEC_SEL 46 +#define CLK_TOP_MFG_SEL 47 +#define CLK_TOP_CAMTG_SEL 48 +#define CLK_TOP_UART_SEL 49 +#define CLK_TOP_SPI_SEL 50 +#define CLK_TOP_USB20_SEL 51 +#define CLK_TOP_MSDC50_0_SEL 52 +#define CLK_TOP_MSDC30_0_SEL 53 +#define CLK_TOP_MSDC30_1_SEL 54 +#define CLK_TOP_MSDC30_2_SEL 55 +#define CLK_TOP_MSDC30_3_SEL 56 +#define CLK_TOP_AUDIO_SEL 57 +#define CLK_TOP_AUDINTBUS_SEL 58 +#define CLK_TOP_PMICSPI_SEL 59 +#define CLK_TOP_SCP_SEL 60 +#define CLK_TOP_ATB_SEL 61 +#define CLK_TOP_DPI0_SEL 62 +#define CLK_TOP_SCAM_SEL 63 +#define CLK_TOP_MFG13M_SEL 64 +#define CLK_TOP_AUD1_SEL 65 +#define CLK_TOP_AUD2_SEL 66 +#define CLK_TOP_IRDA_SEL 67 +#define CLK_TOP_IRTX_SEL 68 +#define CLK_TOP_DISPPWM_SEL 69 + +#endif diff --git a/include/dt-bindings/clock/mediatek,mt6735-vdecsys.h b/include/dt-bindings/clock/mediatek,mt6735-vdecsys.h new file mode 100644 index 000000000000..f94cec10c89f --- /dev/null +++ b/include/dt-bindings/clock/mediatek,mt6735-vdecsys.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef _DT_BINDINGS_CLK_MT6735_VDECSYS_H +#define _DT_BINDINGS_CLK_MT6735_VDECSYS_H + +#define CLK_VDEC_VDEC 0 +#define CLK_VDEC_SMI_LARB1 1 + +#endif /* _DT_BINDINGS_CLK_MT6735_VDECSYS_H */ diff --git a/include/dt-bindings/clock/mediatek,mt6735-vencsys.h b/include/dt-bindings/clock/mediatek,mt6735-vencsys.h new file mode 100644 index 000000000000..e5a9cb4f269f --- /dev/null +++ b/include/dt-bindings/clock/mediatek,mt6735-vencsys.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef _DT_BINDINGS_CLK_MT6735_VENCSYS_H +#define _DT_BINDINGS_CLK_MT6735_VENCSYS_H + +#define CLK_VENC_SMI_LARB3 0 +#define CLK_VENC_VENC 1 +#define CLK_VENC_JPGENC 2 +#define CLK_VENC_JPGDEC 3 + +#endif /* _DT_BINDINGS_CLK_MT6735_VENCSYS_H */ diff --git a/include/dt-bindings/reset/mediatek,mt6735-infracfg.h b/include/dt-bindings/reset/mediatek,mt6735-infracfg.h new file mode 100644 index 000000000000..9df969090377 --- /dev/null +++ b/include/dt-bindings/reset/mediatek,mt6735-infracfg.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef _DT_BINDINGS_RESET_MT6735_INFRACFG_H +#define _DT_BINDINGS_RESET_MT6735_INFRACFG_H + +#define MT6735_INFRA_RST0_EMI_REG 0 +#define MT6735_INFRA_RST0_DRAMC0_AO 1 +#define MT6735_INFRA_RST0_AP_CIRQ_EINT 2 +#define MT6735_INFRA_RST0_APXGPT 3 +#define MT6735_INFRA_RST0_SCPSYS 4 +#define MT6735_INFRA_RST0_KP 5 +#define MT6735_INFRA_RST0_PMIC_WRAP 6 +#define MT6735_INFRA_RST0_CLDMA_AO_TOP 7 +#define MT6735_INFRA_RST0_USBSIF_TOP 8 +#define MT6735_INFRA_RST0_EMI 9 +#define MT6735_INFRA_RST0_CCIF 10 +#define MT6735_INFRA_RST0_DRAMC0 11 +#define MT6735_INFRA_RST0_EMI_AO_REG 12 +#define MT6735_INFRA_RST0_CCIF_AO 13 +#define MT6735_INFRA_RST0_TRNG 14 +#define MT6735_INFRA_RST0_SYS_CIRQ 15 +#define MT6735_INFRA_RST0_GCE 16 +#define MT6735_INFRA_RST0_M4U 17 +#define MT6735_INFRA_RST0_CCIF1 18 +#define MT6735_INFRA_RST0_CLDMA_TOP_PD 19 + +#endif diff --git a/include/dt-bindings/reset/mediatek,mt6735-mfgcfg.h b/include/dt-bindings/reset/mediatek,mt6735-mfgcfg.h new file mode 100644 index 000000000000..c489242b226e --- /dev/null +++ b/include/dt-bindings/reset/mediatek,mt6735-mfgcfg.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef _DT_BINDINGS_RESET_MT6735_MFGCFG_H +#define _DT_BINDINGS_RESET_MT6735_MFGCFG_H + +#define MT6735_MFG_RST0_AXI 0 +#define MT6735_MFG_RST0_G3D 1 + +#endif /* _DT_BINDINGS_RESET_MT6735_MFGCFG_H */ diff --git a/include/dt-bindings/reset/mediatek,mt6735-pericfg.h b/include/dt-bindings/reset/mediatek,mt6735-pericfg.h new file mode 100644 index 000000000000..a62bb192835a --- /dev/null +++ b/include/dt-bindings/reset/mediatek,mt6735-pericfg.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef _DT_BINDINGS_RESET_MT6735_PERICFG_H +#define _DT_BINDINGS_RESET_MT6735_PERICFG_H + +#define MT6735_PERI_RST0_UART0 0 +#define MT6735_PERI_RST0_UART1 1 +#define MT6735_PERI_RST0_UART2 2 +#define MT6735_PERI_RST0_UART3 3 +#define MT6735_PERI_RST0_UART4 4 +#define MT6735_PERI_RST0_BTIF 5 +#define MT6735_PERI_RST0_DISP_PWM_PERI 6 +#define MT6735_PERI_RST0_PWM 7 +#define MT6735_PERI_RST0_AUXADC 8 +#define MT6735_PERI_RST0_DMA 9 +#define MT6735_PERI_RST0_IRDA 10 +#define MT6735_PERI_RST0_IRTX 11 +#define MT6735_PERI_RST0_THERM 12 +#define MT6735_PERI_RST0_MSDC2 13 +#define MT6735_PERI_RST0_MSDC3 14 +#define MT6735_PERI_RST0_MSDC0 15 +#define MT6735_PERI_RST0_MSDC1 16 +#define MT6735_PERI_RST0_I2C0 17 +#define MT6735_PERI_RST0_I2C1 18 +#define MT6735_PERI_RST0_I2C2 19 +#define MT6735_PERI_RST0_I2C3 20 +#define MT6735_PERI_RST0_USB 21 + +#define MT6735_PERI_RST1_SPI0 22 + +#endif diff --git a/include/dt-bindings/reset/mediatek,mt6735-vdecsys.h b/include/dt-bindings/reset/mediatek,mt6735-vdecsys.h new file mode 100644 index 000000000000..b6ae5d249192 --- /dev/null +++ b/include/dt-bindings/reset/mediatek,mt6735-vdecsys.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef _DT_BINDINGS_RESET_MT6735_VDECSYS_H +#define _DT_BINDINGS_RESET_MT6735_VDECSYS_H + +#define MT6735_VDEC_RST0_VDEC 0 +#define MT6735_VDEC_RST1_SMI_LARB1 1 + +#endif /* _DT_BINDINGS_RESET_MT6735_VDECSYS_H */ diff --git a/include/kunit/clk.h b/include/kunit/clk.h index 73bc99cefe7b..0afae7688157 100644 --- a/include/kunit/clk.h +++ b/include/kunit/clk.h @@ -25,4 +25,8 @@ int clk_hw_register_kunit(struct kunit *test, struct device *dev, struct clk_hw int of_clk_hw_register_kunit(struct kunit *test, struct device_node *node, struct clk_hw *hw); +int of_clk_add_hw_provider_kunit(struct kunit *test, struct device_node *np, + struct clk_hw *(*get)(struct of_phandle_args *clkspec, void *data), + void *data); + #endif diff --git a/include/kunit/of.h b/include/kunit/of.h index 48d4e70c9666..75a760a4e2a5 100644 --- a/include/kunit/of.h +++ b/include/kunit/of.h @@ -62,6 +62,13 @@ static inline int __of_overlay_apply_kunit(struct kunit *test, &unused); } +#define of_overlay_begin(overlay_name) __dtbo_##overlay_name##_begin +#define of_overlay_end(overlay_name) __dtbo_##overlay_name##_end + +#define OF_OVERLAY_DECLARE(overlay_name) \ + extern uint8_t of_overlay_begin(overlay_name)[]; \ + extern uint8_t of_overlay_end(overlay_name)[] \ + /** * of_overlay_apply_kunit() - Test managed of_overlay_fdt_apply() for built-in overlays * @test: test context @@ -104,12 +111,11 @@ static inline int __of_overlay_apply_kunit(struct kunit *test, */ #define of_overlay_apply_kunit(test, overlay_name) \ ({ \ - extern uint8_t __dtbo_##overlay_name##_begin[]; \ - extern uint8_t __dtbo_##overlay_name##_end[]; \ + OF_OVERLAY_DECLARE(overlay_name); \ \ __of_overlay_apply_kunit((test), \ - __dtbo_##overlay_name##_begin, \ - __dtbo_##overlay_name##_end); \ + of_overlay_begin(overlay_name), \ + of_overlay_end(overlay_name)); \ }) #endif |