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

Configure Feed

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

at master 264 lines 8.4 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2024 Arm Ltd. 4 * Based on the D1 CCU driver: 5 * Copyright (c) 2020 huangzhenwei@allwinnertech.com 6 * Copyright (C) 2021 Samuel Holland <samuel@sholland.org> 7 */ 8 9#include <linux/clk-provider.h> 10#include <linux/module.h> 11#include <linux/platform_device.h> 12 13#include "ccu_common.h" 14#include "ccu_reset.h" 15 16#include "ccu_gate.h" 17#include "ccu_mp.h" 18 19#include "ccu-sun55i-a523-r.h" 20 21static const struct clk_parent_data r_ahb_apb_parents[] = { 22 { .fw_name = "hosc" }, 23 { .fw_name = "losc" }, 24 { .fw_name = "iosc" }, 25 { .fw_name = "pll-periph" }, 26 { .fw_name = "pll-audio" }, 27}; 28static SUNXI_CCU_M_DATA_WITH_MUX(r_ahb_clk, "r-ahb", 29 r_ahb_apb_parents, 0x000, 30 0, 5, /* M */ 31 24, 3, /* mux */ 32 0); 33 34static SUNXI_CCU_M_DATA_WITH_MUX(r_apb0_clk, "r-apb0", 35 r_ahb_apb_parents, 0x00c, 36 0, 5, /* M */ 37 24, 3, /* mux */ 38 0); 39 40static SUNXI_CCU_M_DATA_WITH_MUX(r_apb1_clk, "r-apb1", 41 r_ahb_apb_parents, 0x010, 42 0, 5, /* M */ 43 24, 3, /* mux */ 44 0); 45 46static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(r_cpu_timer0, "r-timer0", 47 r_ahb_apb_parents, 0x100, 48 0, 0, /* no M */ 49 1, 3, /* P */ 50 4, 3, /* mux */ 51 BIT(0), 52 0); 53static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(r_cpu_timer1, "r-timer1", 54 r_ahb_apb_parents, 0x104, 55 0, 0, /* no M */ 56 1, 3, /* P */ 57 4, 3, /* mux */ 58 BIT(0), 59 0); 60static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(r_cpu_timer2, "r-timer2", 61 r_ahb_apb_parents, 0x108, 62 0, 0, /* no M */ 63 1, 3, /* P */ 64 4, 3, /* mux */ 65 BIT(0), 66 0); 67 68static SUNXI_CCU_GATE_HW(bus_r_timer_clk, "bus-r-timer", &r_ahb_clk.common.hw, 69 0x11c, BIT(0), 0); 70static SUNXI_CCU_GATE_HW(bus_r_twd_clk, "bus-r-twd", &r_apb0_clk.common.hw, 71 0x12c, BIT(0), 0); 72 73static const struct clk_parent_data r_pwmctrl_parents[] = { 74 { .fw_name = "hosc" }, 75 { .fw_name = "losc" }, 76 { .fw_name = "iosc" }, 77}; 78static SUNXI_CCU_MUX_DATA_WITH_GATE(r_pwmctrl_clk, "r-pwmctrl", 79 r_pwmctrl_parents, 0x130, 80 24, 2, /* mux */ 81 BIT(31), 82 0); 83static SUNXI_CCU_GATE_HW(bus_r_pwmctrl_clk, "bus-r-pwmctrl", 84 &r_apb0_clk.common.hw, 0x13c, BIT(0), 0); 85 86static const struct clk_parent_data r_spi_parents[] = { 87 { .fw_name = "hosc" }, 88 { .fw_name = "pll-periph" }, 89 { .name = "pll-periph0-300M" }, 90 { .name = "pll-periph1-300M" }, 91 { .name = "pll-audio" }, 92}; 93static SUNXI_CCU_DUALDIV_MUX_GATE(r_spi_clk, "r-spi", r_spi_parents, 0x150, 94 0, 5, /* M */ 95 8, 5, /* P */ 96 24, 3, /* mux */ 97 BIT(31), /* gate */ 98 0); 99static SUNXI_CCU_GATE_HW(bus_r_spi_clk, "bus-r-spi", 100 &r_ahb_clk.common.hw, 0x15c, BIT(0), 0); 101 102static SUNXI_CCU_GATE_HW(bus_r_spinlock_clk, "bus-r-spinlock", 103 &r_ahb_clk.common.hw, 0x16c, BIT(0), 0); 104static SUNXI_CCU_GATE_HW(bus_r_msgbox_clk, "bus-r-msgbox", 105 &r_ahb_clk.common.hw, 0x17c, BIT(0), 0); 106static SUNXI_CCU_GATE_HW(bus_r_uart0_clk, "bus-r-uart0", 107 &r_apb1_clk.common.hw, 0x18c, BIT(0), 0); 108static SUNXI_CCU_GATE_HW(bus_r_uart1_clk, "bus-r-uart1", 109 &r_apb1_clk.common.hw, 0x18c, BIT(1), 0); 110static SUNXI_CCU_GATE_HW(bus_r_i2c0_clk, "bus-r-i2c0", 111 &r_apb1_clk.common.hw, 0x19c, BIT(0), 0); 112static SUNXI_CCU_GATE_HW(bus_r_i2c1_clk, "bus-r-i2c1", 113 &r_apb1_clk.common.hw, 0x19c, BIT(1), 0); 114static SUNXI_CCU_GATE_HW(bus_r_i2c2_clk, "bus-r-i2c2", 115 &r_apb1_clk.common.hw, 0x19c, BIT(2), 0); 116static SUNXI_CCU_GATE_HW(bus_r_ppu0_clk, "bus-r-ppu0", 117 &r_apb0_clk.common.hw, 0x1ac, BIT(0), 0); 118static SUNXI_CCU_GATE_HW(bus_r_ppu1_clk, "bus-r-ppu1", 119 &r_apb0_clk.common.hw, 0x1ac, BIT(1), 0); 120static SUNXI_CCU_GATE_HW(bus_r_cpu_bist_clk, "bus-r-cpu-bist", 121 &r_apb0_clk.common.hw, 0x1bc, BIT(0), 0); 122 123static const struct clk_parent_data r_ir_rx_parents[] = { 124 { .fw_name = "losc" }, 125 { .fw_name = "hosc" }, 126}; 127static SUNXI_CCU_M_DATA_WITH_MUX_GATE(r_ir_rx_clk, "r-ir-rx", 128 r_ir_rx_parents, 0x1c0, 129 0, 5, /* M */ 130 24, 2, /* mux */ 131 BIT(31), /* gate */ 132 0); 133static SUNXI_CCU_GATE_HW(bus_r_ir_rx_clk, "bus-r-ir-rx", 134 &r_apb0_clk.common.hw, 0x1cc, BIT(0), 0); 135 136static SUNXI_CCU_GATE_HW(bus_r_dma_clk, "bus-r-dma", 137 &r_apb0_clk.common.hw, 0x1dc, BIT(0), CLK_IS_CRITICAL); 138static SUNXI_CCU_GATE_HW(bus_r_rtc_clk, "bus-r-rtc", 139 &r_apb0_clk.common.hw, 0x20c, BIT(0), 0); 140static SUNXI_CCU_GATE_HW(bus_r_cpucfg_clk, "bus-r-cpucfg", 141 &r_apb0_clk.common.hw, 0x22c, BIT(0), CLK_IS_CRITICAL); 142 143static struct ccu_common *sun55i_a523_r_ccu_clks[] = { 144 &r_ahb_clk.common, 145 &r_apb0_clk.common, 146 &r_apb1_clk.common, 147 &r_cpu_timer0.common, 148 &r_cpu_timer1.common, 149 &r_cpu_timer2.common, 150 &bus_r_timer_clk.common, 151 &bus_r_twd_clk.common, 152 &r_pwmctrl_clk.common, 153 &bus_r_pwmctrl_clk.common, 154 &r_spi_clk.common, 155 &bus_r_spi_clk.common, 156 &bus_r_spinlock_clk.common, 157 &bus_r_msgbox_clk.common, 158 &bus_r_uart0_clk.common, 159 &bus_r_uart1_clk.common, 160 &bus_r_i2c0_clk.common, 161 &bus_r_i2c1_clk.common, 162 &bus_r_i2c2_clk.common, 163 &bus_r_ppu0_clk.common, 164 &bus_r_ppu1_clk.common, 165 &bus_r_cpu_bist_clk.common, 166 &r_ir_rx_clk.common, 167 &bus_r_ir_rx_clk.common, 168 &bus_r_dma_clk.common, 169 &bus_r_rtc_clk.common, 170 &bus_r_cpucfg_clk.common, 171}; 172 173static struct clk_hw_onecell_data sun55i_a523_r_hw_clks = { 174 .num = CLK_NUMBER, 175 .hws = { 176 [CLK_R_AHB] = &r_ahb_clk.common.hw, 177 [CLK_R_APB0] = &r_apb0_clk.common.hw, 178 [CLK_R_APB1] = &r_apb1_clk.common.hw, 179 [CLK_R_TIMER0] = &r_cpu_timer0.common.hw, 180 [CLK_R_TIMER1] = &r_cpu_timer1.common.hw, 181 [CLK_R_TIMER2] = &r_cpu_timer2.common.hw, 182 [CLK_BUS_R_TIMER] = &bus_r_timer_clk.common.hw, 183 [CLK_BUS_R_TWD] = &bus_r_twd_clk.common.hw, 184 [CLK_R_PWMCTRL] = &r_pwmctrl_clk.common.hw, 185 [CLK_BUS_R_PWMCTRL] = &bus_r_pwmctrl_clk.common.hw, 186 [CLK_R_SPI] = &r_spi_clk.common.hw, 187 [CLK_BUS_R_SPI] = &bus_r_spi_clk.common.hw, 188 [CLK_BUS_R_SPINLOCK] = &bus_r_spinlock_clk.common.hw, 189 [CLK_BUS_R_MSGBOX] = &bus_r_msgbox_clk.common.hw, 190 [CLK_BUS_R_UART0] = &bus_r_uart0_clk.common.hw, 191 [CLK_BUS_R_UART1] = &bus_r_uart1_clk.common.hw, 192 [CLK_BUS_R_I2C0] = &bus_r_i2c0_clk.common.hw, 193 [CLK_BUS_R_I2C1] = &bus_r_i2c1_clk.common.hw, 194 [CLK_BUS_R_I2C2] = &bus_r_i2c2_clk.common.hw, 195 [CLK_BUS_R_PPU0] = &bus_r_ppu0_clk.common.hw, 196 [CLK_BUS_R_PPU1] = &bus_r_ppu1_clk.common.hw, 197 [CLK_BUS_R_CPU_BIST] = &bus_r_cpu_bist_clk.common.hw, 198 [CLK_R_IR_RX] = &r_ir_rx_clk.common.hw, 199 [CLK_BUS_R_IR_RX] = &bus_r_ir_rx_clk.common.hw, 200 [CLK_BUS_R_DMA] = &bus_r_dma_clk.common.hw, 201 [CLK_BUS_R_RTC] = &bus_r_rtc_clk.common.hw, 202 [CLK_BUS_R_CPUCFG] = &bus_r_cpucfg_clk.common.hw, 203 }, 204}; 205 206static struct ccu_reset_map sun55i_a523_r_ccu_resets[] = { 207 [RST_BUS_R_TIMER] = { 0x11c, BIT(16) }, 208 [RST_BUS_R_TWD] = { 0x12c, BIT(16) }, 209 [RST_BUS_R_PWMCTRL] = { 0x13c, BIT(16) }, 210 [RST_BUS_R_SPI] = { 0x15c, BIT(16) }, 211 [RST_BUS_R_SPINLOCK] = { 0x16c, BIT(16) }, 212 [RST_BUS_R_MSGBOX] = { 0x17c, BIT(16) }, 213 [RST_BUS_R_UART0] = { 0x18c, BIT(16) }, 214 [RST_BUS_R_UART1] = { 0x18c, BIT(17) }, 215 [RST_BUS_R_I2C0] = { 0x19c, BIT(16) }, 216 [RST_BUS_R_I2C1] = { 0x19c, BIT(17) }, 217 [RST_BUS_R_I2C2] = { 0x19c, BIT(18) }, 218 [RST_BUS_R_PPU1] = { 0x1ac, BIT(17) }, 219 [RST_BUS_R_IR_RX] = { 0x1cc, BIT(16) }, 220 [RST_BUS_R_RTC] = { 0x20c, BIT(16) }, 221 [RST_BUS_R_CPUCFG] = { 0x22c, BIT(16) }, 222 [RST_BUS_R_PPU0] = { 0x1ac, BIT(16) }, 223}; 224 225static const struct sunxi_ccu_desc sun55i_a523_r_ccu_desc = { 226 .ccu_clks = sun55i_a523_r_ccu_clks, 227 .num_ccu_clks = ARRAY_SIZE(sun55i_a523_r_ccu_clks), 228 229 .hw_clks = &sun55i_a523_r_hw_clks, 230 231 .resets = sun55i_a523_r_ccu_resets, 232 .num_resets = ARRAY_SIZE(sun55i_a523_r_ccu_resets), 233}; 234 235static int sun55i_a523_r_ccu_probe(struct platform_device *pdev) 236{ 237 void __iomem *reg; 238 239 reg = devm_platform_ioremap_resource(pdev, 0); 240 if (IS_ERR(reg)) 241 return PTR_ERR(reg); 242 243 return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun55i_a523_r_ccu_desc); 244} 245 246static const struct of_device_id sun55i_a523_r_ccu_ids[] = { 247 { .compatible = "allwinner,sun55i-a523-r-ccu" }, 248 { } 249}; 250MODULE_DEVICE_TABLE(of, sun55i_a523_r_ccu_ids); 251 252static struct platform_driver sun55i_a523_r_ccu_driver = { 253 .probe = sun55i_a523_r_ccu_probe, 254 .driver = { 255 .name = "sun55i-a523-r-ccu", 256 .suppress_bind_attrs = true, 257 .of_match_table = sun55i_a523_r_ccu_ids, 258 }, 259}; 260module_platform_driver(sun55i_a523_r_ccu_driver); 261 262MODULE_IMPORT_NS("SUNXI_CCU"); 263MODULE_DESCRIPTION("Support for the Allwinner A523 PRCM CCU"); 264MODULE_LICENSE("GPL");