From: Robert Marko Date: Mon, 19 Feb 2024 20:34:37 +0000 (+0100) Subject: airoha: make files 5.15 only X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=d646e4573ca9cf7326d73430fbd29b90cc61c1c1;p=openwrt%2Fstaging%2Fpepe2k.git airoha: make files 5.15 only Contents of the files folder were upstreamed in 6.1 so make it 5.15 only. Signed-off-by: Robert Marko --- diff --git a/target/linux/airoha/files-5.15/arch/arm/mach-airoha/Makefile b/target/linux/airoha/files-5.15/arch/arm/mach-airoha/Makefile new file mode 100644 index 0000000000..a5857d0d02 --- /dev/null +++ b/target/linux/airoha/files-5.15/arch/arm/mach-airoha/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-y += airoha.o diff --git a/target/linux/airoha/files-5.15/arch/arm/mach-airoha/airoha.c b/target/linux/airoha/files-5.15/arch/arm/mach-airoha/airoha.c new file mode 100644 index 0000000000..ea23b5abb4 --- /dev/null +++ b/target/linux/airoha/files-5.15/arch/arm/mach-airoha/airoha.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Device Tree support for Airoha SoCs + * + * Copyright (c) 2022 Felix Fietkau + */ +#include + +static const char * const airoha_board_dt_compat[] = { + "airoha,en7523", + NULL, +}; + +DT_MACHINE_START(MEDIATEK_DT, "Airoha Cortex-A53 (Device Tree)") + .dt_compat = airoha_board_dt_compat, +MACHINE_END diff --git a/target/linux/airoha/files-5.15/drivers/clk/clk-en7523.c b/target/linux/airoha/files-5.15/drivers/clk/clk-en7523.c new file mode 100644 index 0000000000..29f0126cbd --- /dev/null +++ b/target/linux/airoha/files-5.15/drivers/clk/clk-en7523.c @@ -0,0 +1,351 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include +#include + +#define REG_PCI_CONTROL 0x88 +#define REG_PCI_CONTROL_PERSTOUT BIT(29) +#define REG_PCI_CONTROL_PERSTOUT1 BIT(26) +#define REG_PCI_CONTROL_REFCLK_EN1 BIT(22) +#define REG_GSW_CLK_DIV_SEL 0x1b4 +#define REG_EMI_CLK_DIV_SEL 0x1b8 +#define REG_BUS_CLK_DIV_SEL 0x1bc +#define REG_SPI_CLK_DIV_SEL 0x1c4 +#define REG_SPI_CLK_FREQ_SEL 0x1c8 +#define REG_NPU_CLK_DIV_SEL 0x1fc +#define REG_CRYPTO_CLKSRC 0x200 +#define REG_RESET_CONTROL 0x834 +#define REG_RESET_CONTROL_PCIEHB BIT(29) +#define REG_RESET_CONTROL_PCIE1 BIT(27) +#define REG_RESET_CONTROL_PCIE2 BIT(26) + +struct en_clk_desc { + int id; + const char *name; + u32 base_reg; + u8 base_bits; + u8 base_shift; + union { + const unsigned int *base_values; + unsigned int base_value; + }; + size_t n_base_values; + + u16 div_reg; + u8 div_bits; + u8 div_shift; + u16 div_val0; + u8 div_step; +}; + +struct en_clk_gate { + void __iomem *base; + struct clk_hw hw; +}; + +static const u32 gsw_base[] = { 400000000, 500000000 }; +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 }; + +static const struct en_clk_desc en7523_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, + }, { + .id = EN7523_CLK_EMI, + .name = "emi", + + .base_reg = REG_EMI_CLK_DIV_SEL, + .base_bits = 1, + .base_shift = 8, + .base_values = emi_base, + .n_base_values = ARRAY_SIZE(emi_base), + + .div_bits = 3, + .div_shift = 0, + .div_step = 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, + }, { + .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 = npu_base, + .n_base_values = ARRAY_SIZE(npu_base), + + .div_bits = 3, + .div_shift = 0, + .div_step = 1, + }, { + .id = EN7523_CLK_CRYPTO, + .name = "crypto", + + .base_reg = REG_CRYPTO_CLKSRC, + .base_bits = 1, + .base_shift = 8, + .base_values = emi_base, + .n_base_values = ARRAY_SIZE(emi_base), + } +}; + +static const struct of_device_id of_match_clk_en7523[] = { + { .compatible = "airoha,en7523-scu", }, + { /* sentinel */ } +}; + +static unsigned int en7523_get_base_rate(void __iomem *base, unsigned int i) +{ + 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; + + if (val >= desc->n_base_values) + return 0; + + return desc->base_values[val]; +} + +static u32 en7523_get_div(void __iomem *base, int i) +{ + 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; + + if (!val && desc->div_val0) + return desc->div_val0; + + return (val + 1) * desc->div_step; +} + +static int en7523_pci_is_enabled(struct clk_hw *hw) +{ + struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); + + return !!(readl(cg->base + REG_PCI_CONTROL) & REG_PCI_CONTROL_REFCLK_EN1); +} + +static int en7523_pci_prepare(struct clk_hw *hw) +{ + struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); + void __iomem *np_base = cg->base; + u32 val, mask; + + /* Need to pull device low before reset */ + val = readl(np_base + REG_PCI_CONTROL); + val &= ~(REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT); + writel(val, np_base + REG_PCI_CONTROL); + usleep_range(1000, 2000); + + /* Enable PCIe port 1 */ + val |= REG_PCI_CONTROL_REFCLK_EN1; + writel(val, np_base + REG_PCI_CONTROL); + usleep_range(1000, 2000); + + /* Reset to default */ + val = readl(np_base + REG_RESET_CONTROL); + mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 | + REG_RESET_CONTROL_PCIEHB; + writel(val & ~mask, np_base + REG_RESET_CONTROL); + usleep_range(1000, 2000); + writel(val | mask, np_base + REG_RESET_CONTROL); + msleep(100); + writel(val & ~mask, np_base + REG_RESET_CONTROL); + usleep_range(5000, 10000); + + /* Release device */ + mask = REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT; + val = readl(np_base + REG_PCI_CONTROL); + writel(val & ~mask, np_base + REG_PCI_CONTROL); + usleep_range(1000, 2000); + writel(val | mask, np_base + REG_PCI_CONTROL); + msleep(250); + + return 0; +} + +static void en7523_pci_unprepare(struct clk_hw *hw) +{ + struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); + void __iomem *np_base = cg->base; + u32 val; + + val = readl(np_base + REG_PCI_CONTROL); + val &= ~REG_PCI_CONTROL_REFCLK_EN1; + writel(val, np_base + REG_PCI_CONTROL); +} + +static struct clk_hw *en7523_register_pcie_clk(struct device *dev, + void __iomem *np_base) +{ + static const struct clk_ops pcie_gate_ops = { + .is_enabled = en7523_pci_is_enabled, + .prepare = en7523_pci_prepare, + .unprepare = en7523_pci_unprepare, + }; + struct clk_init_data init = { + .name = "pcie", + .ops = &pcie_gate_ops, + }; + struct en_clk_gate *cg; + + cg = devm_kzalloc(dev, sizeof(*cg), GFP_KERNEL); + if (!cg) + return NULL; + + cg->base = np_base; + cg->hw.init = &init; + en7523_pci_unprepare(&cg->hw); + + if (clk_hw_register(dev, &cg->hw)) + return NULL; + + return &cg->hw; +} + +static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, + void __iomem *base, void __iomem *np_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]; + + rate = en7523_get_base_rate(base, i); + rate /= en7523_get_div(base, i); + + 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_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct clk_hw_onecell_data *clk_data; + void __iomem *base, *np_base; + int r; + + 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); + + clk_data = devm_kzalloc(&pdev->dev, + struct_size(clk_data, hws, EN7523_NUM_CLOCKS), + GFP_KERNEL); + 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); + if (r) + dev_err(&pdev->dev, + "could not register clock provider: %s: %d\n", + pdev->name, r); + + return r; +} + +static struct platform_driver clk_en7523_drv = { + .probe = en7523_clk_probe, + .driver = { + .name = "clk-en7523", + .of_match_table = of_match_clk_en7523, + .suppress_bind_attrs = true, + }, +}; + +static int __init clk_en7523_init(void) +{ + return platform_driver_register(&clk_en7523_drv); +} + +arch_initcall(clk_en7523_init); diff --git a/target/linux/airoha/files-5.15/drivers/gpio/gpio-en7523.c b/target/linux/airoha/files-5.15/drivers/gpio/gpio-en7523.c new file mode 100644 index 0000000000..f836a8db4c --- /dev/null +++ b/target/linux/airoha/files-5.15/drivers/gpio/gpio-en7523.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include +#include +#include + +#define AIROHA_GPIO_MAX 32 + +/** + * airoha_gpio_ctrl - Airoha GPIO driver data + * @gc: Associated gpio_chip instance. + * @data: The data register. + * @dir0: The direction register for the lower 16 pins. + * @dir1: The direction register for the higher 16 pins. + * @output: The output enable register. + */ +struct airoha_gpio_ctrl { + struct gpio_chip gc; + void __iomem *data; + void __iomem *dir[2]; + void __iomem *output; +}; + +static struct airoha_gpio_ctrl *gc_to_ctrl(struct gpio_chip *gc) +{ + return container_of(gc, struct airoha_gpio_ctrl, gc); +} + +static int airoha_dir_set(struct gpio_chip *gc, unsigned int gpio, + int val, int out) +{ + struct airoha_gpio_ctrl *ctrl = gc_to_ctrl(gc); + u32 dir = ioread32(ctrl->dir[gpio / 16]); + u32 output = ioread32(ctrl->output); + u32 mask = BIT((gpio % 16) * 2); + + if (out) { + dir |= mask; + output |= BIT(gpio); + } else { + dir &= ~mask; + output &= ~BIT(gpio); + } + + iowrite32(dir, ctrl->dir[gpio / 16]); + + if (out) + gc->set(gc, gpio, val); + + iowrite32(output, ctrl->output); + + return 0; +} + +static int airoha_dir_out(struct gpio_chip *gc, unsigned int gpio, + int val) +{ + return airoha_dir_set(gc, gpio, val, 1); +} + +static int airoha_dir_in(struct gpio_chip *gc, unsigned int gpio) +{ + return airoha_dir_set(gc, gpio, 0, 0); +} + +static int airoha_get_dir(struct gpio_chip *gc, unsigned int gpio) +{ + struct airoha_gpio_ctrl *ctrl = gc_to_ctrl(gc); + u32 dir = ioread32(ctrl->dir[gpio / 16]); + u32 mask = BIT((gpio % 16) * 2); + + return (dir & mask) ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN; +} + +static int airoha_gpio_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct airoha_gpio_ctrl *ctrl; + int err; + + ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); + if (!ctrl) + return -ENOMEM; + + ctrl->data = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(ctrl->data)) + return PTR_ERR(ctrl->data); + + ctrl->dir[0] = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(ctrl->dir[0])) + return PTR_ERR(ctrl->dir[0]); + + ctrl->dir[1] = devm_platform_ioremap_resource(pdev, 2); + if (IS_ERR(ctrl->dir[1])) + return PTR_ERR(ctrl->dir[1]); + + ctrl->output = devm_platform_ioremap_resource(pdev, 3); + if (IS_ERR(ctrl->output)) + return PTR_ERR(ctrl->output); + + err = bgpio_init(&ctrl->gc, dev, 4, ctrl->data, NULL, + NULL, NULL, NULL, 0); + if (err) + return dev_err_probe(dev, err, "unable to init generic GPIO"); + + ctrl->gc.ngpio = AIROHA_GPIO_MAX; + ctrl->gc.owner = THIS_MODULE; + ctrl->gc.direction_output = airoha_dir_out; + ctrl->gc.direction_input = airoha_dir_in; + ctrl->gc.get_direction = airoha_get_dir; + + return devm_gpiochip_add_data(dev, &ctrl->gc, ctrl); +} + +static const struct of_device_id airoha_gpio_of_match[] = { + { .compatible = "airoha,en7523-gpio" }, + { } +}; +MODULE_DEVICE_TABLE(of, airoha_gpio_of_match); + +static struct platform_driver airoha_gpio_driver = { + .driver = { + .name = "airoha-gpio", + .of_match_table = airoha_gpio_of_match, + }, + .probe = airoha_gpio_probe, +}; +module_platform_driver(airoha_gpio_driver); + +MODULE_DESCRIPTION("Airoha GPIO support"); +MODULE_AUTHOR("John Crispin "); +MODULE_LICENSE("GPL v2"); diff --git a/target/linux/airoha/files-5.15/include/dt-bindings/clock/en7523-clk.h b/target/linux/airoha/files-5.15/include/dt-bindings/clock/en7523-clk.h new file mode 100644 index 0000000000..717d23a5e5 --- /dev/null +++ b/target/linux/airoha/files-5.15/include/dt-bindings/clock/en7523-clk.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ + +#ifndef _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ +#define _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ + +#define EN7523_CLK_GSW 0 +#define EN7523_CLK_EMI 1 +#define EN7523_CLK_BUS 2 +#define EN7523_CLK_SLIC 3 +#define EN7523_CLK_SPI 4 +#define EN7523_CLK_NPU 5 +#define EN7523_CLK_CRYPTO 6 +#define EN7523_CLK_PCIE 7 + +#define EN7523_NUM_CLOCKS 8 + +#endif /* _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ */ diff --git a/target/linux/airoha/files/arch/arm/mach-airoha/Makefile b/target/linux/airoha/files/arch/arm/mach-airoha/Makefile deleted file mode 100644 index a5857d0d02..0000000000 --- a/target/linux/airoha/files/arch/arm/mach-airoha/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-y += airoha.o diff --git a/target/linux/airoha/files/arch/arm/mach-airoha/airoha.c b/target/linux/airoha/files/arch/arm/mach-airoha/airoha.c deleted file mode 100644 index ea23b5abb4..0000000000 --- a/target/linux/airoha/files/arch/arm/mach-airoha/airoha.c +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Device Tree support for Airoha SoCs - * - * Copyright (c) 2022 Felix Fietkau - */ -#include - -static const char * const airoha_board_dt_compat[] = { - "airoha,en7523", - NULL, -}; - -DT_MACHINE_START(MEDIATEK_DT, "Airoha Cortex-A53 (Device Tree)") - .dt_compat = airoha_board_dt_compat, -MACHINE_END diff --git a/target/linux/airoha/files/drivers/clk/clk-en7523.c b/target/linux/airoha/files/drivers/clk/clk-en7523.c deleted file mode 100644 index 29f0126cbd..0000000000 --- a/target/linux/airoha/files/drivers/clk/clk-en7523.c +++ /dev/null @@ -1,351 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include -#include -#include -#include -#include -#include -#include - -#define REG_PCI_CONTROL 0x88 -#define REG_PCI_CONTROL_PERSTOUT BIT(29) -#define REG_PCI_CONTROL_PERSTOUT1 BIT(26) -#define REG_PCI_CONTROL_REFCLK_EN1 BIT(22) -#define REG_GSW_CLK_DIV_SEL 0x1b4 -#define REG_EMI_CLK_DIV_SEL 0x1b8 -#define REG_BUS_CLK_DIV_SEL 0x1bc -#define REG_SPI_CLK_DIV_SEL 0x1c4 -#define REG_SPI_CLK_FREQ_SEL 0x1c8 -#define REG_NPU_CLK_DIV_SEL 0x1fc -#define REG_CRYPTO_CLKSRC 0x200 -#define REG_RESET_CONTROL 0x834 -#define REG_RESET_CONTROL_PCIEHB BIT(29) -#define REG_RESET_CONTROL_PCIE1 BIT(27) -#define REG_RESET_CONTROL_PCIE2 BIT(26) - -struct en_clk_desc { - int id; - const char *name; - u32 base_reg; - u8 base_bits; - u8 base_shift; - union { - const unsigned int *base_values; - unsigned int base_value; - }; - size_t n_base_values; - - u16 div_reg; - u8 div_bits; - u8 div_shift; - u16 div_val0; - u8 div_step; -}; - -struct en_clk_gate { - void __iomem *base; - struct clk_hw hw; -}; - -static const u32 gsw_base[] = { 400000000, 500000000 }; -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 }; - -static const struct en_clk_desc en7523_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, - }, { - .id = EN7523_CLK_EMI, - .name = "emi", - - .base_reg = REG_EMI_CLK_DIV_SEL, - .base_bits = 1, - .base_shift = 8, - .base_values = emi_base, - .n_base_values = ARRAY_SIZE(emi_base), - - .div_bits = 3, - .div_shift = 0, - .div_step = 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, - }, { - .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 = npu_base, - .n_base_values = ARRAY_SIZE(npu_base), - - .div_bits = 3, - .div_shift = 0, - .div_step = 1, - }, { - .id = EN7523_CLK_CRYPTO, - .name = "crypto", - - .base_reg = REG_CRYPTO_CLKSRC, - .base_bits = 1, - .base_shift = 8, - .base_values = emi_base, - .n_base_values = ARRAY_SIZE(emi_base), - } -}; - -static const struct of_device_id of_match_clk_en7523[] = { - { .compatible = "airoha,en7523-scu", }, - { /* sentinel */ } -}; - -static unsigned int en7523_get_base_rate(void __iomem *base, unsigned int i) -{ - 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; - - if (val >= desc->n_base_values) - return 0; - - return desc->base_values[val]; -} - -static u32 en7523_get_div(void __iomem *base, int i) -{ - 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; - - if (!val && desc->div_val0) - return desc->div_val0; - - return (val + 1) * desc->div_step; -} - -static int en7523_pci_is_enabled(struct clk_hw *hw) -{ - struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); - - return !!(readl(cg->base + REG_PCI_CONTROL) & REG_PCI_CONTROL_REFCLK_EN1); -} - -static int en7523_pci_prepare(struct clk_hw *hw) -{ - struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); - void __iomem *np_base = cg->base; - u32 val, mask; - - /* Need to pull device low before reset */ - val = readl(np_base + REG_PCI_CONTROL); - val &= ~(REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT); - writel(val, np_base + REG_PCI_CONTROL); - usleep_range(1000, 2000); - - /* Enable PCIe port 1 */ - val |= REG_PCI_CONTROL_REFCLK_EN1; - writel(val, np_base + REG_PCI_CONTROL); - usleep_range(1000, 2000); - - /* Reset to default */ - val = readl(np_base + REG_RESET_CONTROL); - mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 | - REG_RESET_CONTROL_PCIEHB; - writel(val & ~mask, np_base + REG_RESET_CONTROL); - usleep_range(1000, 2000); - writel(val | mask, np_base + REG_RESET_CONTROL); - msleep(100); - writel(val & ~mask, np_base + REG_RESET_CONTROL); - usleep_range(5000, 10000); - - /* Release device */ - mask = REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT; - val = readl(np_base + REG_PCI_CONTROL); - writel(val & ~mask, np_base + REG_PCI_CONTROL); - usleep_range(1000, 2000); - writel(val | mask, np_base + REG_PCI_CONTROL); - msleep(250); - - return 0; -} - -static void en7523_pci_unprepare(struct clk_hw *hw) -{ - struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw); - void __iomem *np_base = cg->base; - u32 val; - - val = readl(np_base + REG_PCI_CONTROL); - val &= ~REG_PCI_CONTROL_REFCLK_EN1; - writel(val, np_base + REG_PCI_CONTROL); -} - -static struct clk_hw *en7523_register_pcie_clk(struct device *dev, - void __iomem *np_base) -{ - static const struct clk_ops pcie_gate_ops = { - .is_enabled = en7523_pci_is_enabled, - .prepare = en7523_pci_prepare, - .unprepare = en7523_pci_unprepare, - }; - struct clk_init_data init = { - .name = "pcie", - .ops = &pcie_gate_ops, - }; - struct en_clk_gate *cg; - - cg = devm_kzalloc(dev, sizeof(*cg), GFP_KERNEL); - if (!cg) - return NULL; - - cg->base = np_base; - cg->hw.init = &init; - en7523_pci_unprepare(&cg->hw); - - if (clk_hw_register(dev, &cg->hw)) - return NULL; - - return &cg->hw; -} - -static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data, - void __iomem *base, void __iomem *np_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]; - - rate = en7523_get_base_rate(base, i); - rate /= en7523_get_div(base, i); - - 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_probe(struct platform_device *pdev) -{ - struct device_node *node = pdev->dev.of_node; - struct clk_hw_onecell_data *clk_data; - void __iomem *base, *np_base; - int r; - - 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); - - clk_data = devm_kzalloc(&pdev->dev, - struct_size(clk_data, hws, EN7523_NUM_CLOCKS), - GFP_KERNEL); - 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); - if (r) - dev_err(&pdev->dev, - "could not register clock provider: %s: %d\n", - pdev->name, r); - - return r; -} - -static struct platform_driver clk_en7523_drv = { - .probe = en7523_clk_probe, - .driver = { - .name = "clk-en7523", - .of_match_table = of_match_clk_en7523, - .suppress_bind_attrs = true, - }, -}; - -static int __init clk_en7523_init(void) -{ - return platform_driver_register(&clk_en7523_drv); -} - -arch_initcall(clk_en7523_init); diff --git a/target/linux/airoha/files/drivers/gpio/gpio-en7523.c b/target/linux/airoha/files/drivers/gpio/gpio-en7523.c deleted file mode 100644 index f836a8db4c..0000000000 --- a/target/linux/airoha/files/drivers/gpio/gpio-en7523.c +++ /dev/null @@ -1,137 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only - -#include -#include -#include -#include -#include -#include -#include -#include - -#define AIROHA_GPIO_MAX 32 - -/** - * airoha_gpio_ctrl - Airoha GPIO driver data - * @gc: Associated gpio_chip instance. - * @data: The data register. - * @dir0: The direction register for the lower 16 pins. - * @dir1: The direction register for the higher 16 pins. - * @output: The output enable register. - */ -struct airoha_gpio_ctrl { - struct gpio_chip gc; - void __iomem *data; - void __iomem *dir[2]; - void __iomem *output; -}; - -static struct airoha_gpio_ctrl *gc_to_ctrl(struct gpio_chip *gc) -{ - return container_of(gc, struct airoha_gpio_ctrl, gc); -} - -static int airoha_dir_set(struct gpio_chip *gc, unsigned int gpio, - int val, int out) -{ - struct airoha_gpio_ctrl *ctrl = gc_to_ctrl(gc); - u32 dir = ioread32(ctrl->dir[gpio / 16]); - u32 output = ioread32(ctrl->output); - u32 mask = BIT((gpio % 16) * 2); - - if (out) { - dir |= mask; - output |= BIT(gpio); - } else { - dir &= ~mask; - output &= ~BIT(gpio); - } - - iowrite32(dir, ctrl->dir[gpio / 16]); - - if (out) - gc->set(gc, gpio, val); - - iowrite32(output, ctrl->output); - - return 0; -} - -static int airoha_dir_out(struct gpio_chip *gc, unsigned int gpio, - int val) -{ - return airoha_dir_set(gc, gpio, val, 1); -} - -static int airoha_dir_in(struct gpio_chip *gc, unsigned int gpio) -{ - return airoha_dir_set(gc, gpio, 0, 0); -} - -static int airoha_get_dir(struct gpio_chip *gc, unsigned int gpio) -{ - struct airoha_gpio_ctrl *ctrl = gc_to_ctrl(gc); - u32 dir = ioread32(ctrl->dir[gpio / 16]); - u32 mask = BIT((gpio % 16) * 2); - - return (dir & mask) ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN; -} - -static int airoha_gpio_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct airoha_gpio_ctrl *ctrl; - int err; - - ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); - if (!ctrl) - return -ENOMEM; - - ctrl->data = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(ctrl->data)) - return PTR_ERR(ctrl->data); - - ctrl->dir[0] = devm_platform_ioremap_resource(pdev, 1); - if (IS_ERR(ctrl->dir[0])) - return PTR_ERR(ctrl->dir[0]); - - ctrl->dir[1] = devm_platform_ioremap_resource(pdev, 2); - if (IS_ERR(ctrl->dir[1])) - return PTR_ERR(ctrl->dir[1]); - - ctrl->output = devm_platform_ioremap_resource(pdev, 3); - if (IS_ERR(ctrl->output)) - return PTR_ERR(ctrl->output); - - err = bgpio_init(&ctrl->gc, dev, 4, ctrl->data, NULL, - NULL, NULL, NULL, 0); - if (err) - return dev_err_probe(dev, err, "unable to init generic GPIO"); - - ctrl->gc.ngpio = AIROHA_GPIO_MAX; - ctrl->gc.owner = THIS_MODULE; - ctrl->gc.direction_output = airoha_dir_out; - ctrl->gc.direction_input = airoha_dir_in; - ctrl->gc.get_direction = airoha_get_dir; - - return devm_gpiochip_add_data(dev, &ctrl->gc, ctrl); -} - -static const struct of_device_id airoha_gpio_of_match[] = { - { .compatible = "airoha,en7523-gpio" }, - { } -}; -MODULE_DEVICE_TABLE(of, airoha_gpio_of_match); - -static struct platform_driver airoha_gpio_driver = { - .driver = { - .name = "airoha-gpio", - .of_match_table = airoha_gpio_of_match, - }, - .probe = airoha_gpio_probe, -}; -module_platform_driver(airoha_gpio_driver); - -MODULE_DESCRIPTION("Airoha GPIO support"); -MODULE_AUTHOR("John Crispin "); -MODULE_LICENSE("GPL v2"); diff --git a/target/linux/airoha/files/include/dt-bindings/clock/en7523-clk.h b/target/linux/airoha/files/include/dt-bindings/clock/en7523-clk.h deleted file mode 100644 index 717d23a5e5..0000000000 --- a/target/linux/airoha/files/include/dt-bindings/clock/en7523-clk.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ - -#ifndef _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ -#define _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ - -#define EN7523_CLK_GSW 0 -#define EN7523_CLK_EMI 1 -#define EN7523_CLK_BUS 2 -#define EN7523_CLK_SLIC 3 -#define EN7523_CLK_SPI 4 -#define EN7523_CLK_NPU 5 -#define EN7523_CLK_CRYPTO 6 -#define EN7523_CLK_PCIE 7 - -#define EN7523_NUM_CLOCKS 8 - -#endif /* _DT_BINDINGS_CLOCK_AIROHA_EN7523_H_ */