0001
0002
0003
0004
0005
0006
0007 #include <linux/clk-provider.h>
0008 #include <linux/module.h>
0009 #include <linux/platform_device.h>
0010
0011 #include "ccu_common.h"
0012 #include "ccu_reset.h"
0013
0014 #include "ccu_gate.h"
0015 #include "ccu_mp.h"
0016
0017 #include "ccu-sun20i-d1-r.h"
0018
0019 static const struct clk_parent_data r_ahb_apb0_parents[] = {
0020 { .fw_name = "hosc" },
0021 { .fw_name = "losc" },
0022 { .fw_name = "iosc" },
0023 { .fw_name = "pll-periph" },
0024 };
0025 static SUNXI_CCU_MP_DATA_WITH_MUX(r_ahb_clk, "r-ahb",
0026 r_ahb_apb0_parents, 0x000,
0027 0, 5,
0028 8, 2,
0029 24, 3,
0030 0);
0031 static const struct clk_hw *r_ahb_hw = &r_ahb_clk.common.hw;
0032
0033 static SUNXI_CCU_MP_DATA_WITH_MUX(r_apb0_clk, "r-apb0",
0034 r_ahb_apb0_parents, 0x00c,
0035 0, 5,
0036 8, 2,
0037 24, 3,
0038 0);
0039 static const struct clk_hw *r_apb0_hw = &r_apb0_clk.common.hw;
0040
0041 static SUNXI_CCU_GATE_HWS(bus_r_timer_clk, "bus-r-timer", &r_apb0_hw,
0042 0x11c, BIT(0), 0);
0043 static SUNXI_CCU_GATE_HWS(bus_r_twd_clk, "bus-r-twd", &r_apb0_hw,
0044 0x12c, BIT(0), 0);
0045 static SUNXI_CCU_GATE_HWS(bus_r_ppu_clk, "bus-r-ppu", &r_apb0_hw,
0046 0x1ac, BIT(0), 0);
0047
0048 static const struct clk_parent_data r_ir_rx_parents[] = {
0049 { .fw_name = "losc" },
0050 { .fw_name = "hosc" },
0051 };
0052 static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(r_ir_rx_clk, "r-ir-rx",
0053 r_ir_rx_parents, 0x1c0,
0054 0, 5,
0055 8, 2,
0056 24, 2,
0057 BIT(31),
0058 0);
0059
0060 static SUNXI_CCU_GATE_HWS(bus_r_ir_rx_clk, "bus-r-ir-rx", &r_apb0_hw,
0061 0x1cc, BIT(0), 0);
0062 static SUNXI_CCU_GATE_HWS(bus_r_rtc_clk, "bus-r-rtc", &r_ahb_hw,
0063 0x20c, BIT(0), 0);
0064 static SUNXI_CCU_GATE_HWS(bus_r_cpucfg_clk, "bus-r-cpucfg", &r_apb0_hw,
0065 0x22c, BIT(0), 0);
0066
0067 static struct ccu_common *sun20i_d1_r_ccu_clks[] = {
0068 &r_ahb_clk.common,
0069 &r_apb0_clk.common,
0070 &bus_r_timer_clk.common,
0071 &bus_r_twd_clk.common,
0072 &bus_r_ppu_clk.common,
0073 &r_ir_rx_clk.common,
0074 &bus_r_ir_rx_clk.common,
0075 &bus_r_rtc_clk.common,
0076 &bus_r_cpucfg_clk.common,
0077 };
0078
0079 static struct clk_hw_onecell_data sun20i_d1_r_hw_clks = {
0080 .num = CLK_NUMBER,
0081 .hws = {
0082 [CLK_R_AHB] = &r_ahb_clk.common.hw,
0083 [CLK_R_APB0] = &r_apb0_clk.common.hw,
0084 [CLK_BUS_R_TIMER] = &bus_r_timer_clk.common.hw,
0085 [CLK_BUS_R_TWD] = &bus_r_twd_clk.common.hw,
0086 [CLK_BUS_R_PPU] = &bus_r_ppu_clk.common.hw,
0087 [CLK_R_IR_RX] = &r_ir_rx_clk.common.hw,
0088 [CLK_BUS_R_IR_RX] = &bus_r_ir_rx_clk.common.hw,
0089 [CLK_BUS_R_RTC] = &bus_r_rtc_clk.common.hw,
0090 [CLK_BUS_R_CPUCFG] = &bus_r_cpucfg_clk.common.hw,
0091 },
0092 };
0093
0094 static struct ccu_reset_map sun20i_d1_r_ccu_resets[] = {
0095 [RST_BUS_R_TIMER] = { 0x11c, BIT(16) },
0096 [RST_BUS_R_TWD] = { 0x12c, BIT(16) },
0097 [RST_BUS_R_PPU] = { 0x1ac, BIT(16) },
0098 [RST_BUS_R_IR_RX] = { 0x1cc, BIT(16) },
0099 [RST_BUS_R_RTC] = { 0x20c, BIT(16) },
0100 [RST_BUS_R_CPUCFG] = { 0x22c, BIT(16) },
0101 };
0102
0103 static const struct sunxi_ccu_desc sun20i_d1_r_ccu_desc = {
0104 .ccu_clks = sun20i_d1_r_ccu_clks,
0105 .num_ccu_clks = ARRAY_SIZE(sun20i_d1_r_ccu_clks),
0106
0107 .hw_clks = &sun20i_d1_r_hw_clks,
0108
0109 .resets = sun20i_d1_r_ccu_resets,
0110 .num_resets = ARRAY_SIZE(sun20i_d1_r_ccu_resets),
0111 };
0112
0113 static int sun20i_d1_r_ccu_probe(struct platform_device *pdev)
0114 {
0115 void __iomem *reg;
0116
0117 reg = devm_platform_ioremap_resource(pdev, 0);
0118 if (IS_ERR(reg))
0119 return PTR_ERR(reg);
0120
0121 return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun20i_d1_r_ccu_desc);
0122 }
0123
0124 static const struct of_device_id sun20i_d1_r_ccu_ids[] = {
0125 { .compatible = "allwinner,sun20i-d1-r-ccu" },
0126 { }
0127 };
0128
0129 static struct platform_driver sun20i_d1_r_ccu_driver = {
0130 .probe = sun20i_d1_r_ccu_probe,
0131 .driver = {
0132 .name = "sun20i-d1-r-ccu",
0133 .suppress_bind_attrs = true,
0134 .of_match_table = sun20i_d1_r_ccu_ids,
0135 },
0136 };
0137 module_platform_driver(sun20i_d1_r_ccu_driver);
0138
0139 MODULE_IMPORT_NS(SUNXI_CCU);
0140 MODULE_LICENSE("GPL");