Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2020 huangzhenwei@allwinnertech.com
0004  * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
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,     /* M */
0028                   8, 2,     /* P */
0029                   24, 3,    /* mux */
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,     /* M */
0036                   8, 2,     /* P */
0037                   24, 3,    /* mux */
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,    /* M */
0055                        8, 2,    /* P */
0056                        24, 2,   /* mux */
0057                        BIT(31), /* gate */
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");