• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2020 huangzhenwei@allwinnertech.com
4  */
5 
6 #include <linux/clk-provider.h>
7 #include <linux/module.h>
8 #include <linux/of_address.h>
9 #include <linux/platform_device.h>
10 
11 #include "ccu_common.h"
12 #include "ccu_reset.h"
13 
14 #include "ccu_div.h"
15 #include "ccu_gate.h"
16 #include "ccu_mp.h"
17 #include "ccu_nm.h"
18 
19 #include "ccu-sun8iw20-r.h"
20 
21 static const char * const ahbs_apbs0_parents[] = { "dcxo24M", "osc32k",
22 						   "iosc", "pll-periph0-div3" };
23 static SUNXI_CCU_MP_WITH_MUX(r_ahb_clk, "r-ahb",
24 			     ahbs_apbs0_parents, 0x000,
25 			     0, 5,
26 			     8, 2,
27 			     24, 3,
28 			     0);
29 
30 static SUNXI_CCU_MP_WITH_MUX(r_apb0_clk, "r-apb0",
31 			     ahbs_apbs0_parents, 0x00c,
32 			     0, 5,
33 			     8, 2,
34 			     24, 3,
35 			     0);
36 
37 static SUNXI_CCU_GATE(r_apb0_timer_clk, "r-apb0-timer", "r-apb0",
38 		      0x11c, BIT(0), 0);
39 
40 static SUNXI_CCU_GATE(r_apb0_twd_clk, "r-apb0-twd", "r-apb0",
41 		      0x12c, BIT(0), 0);
42 
43 static SUNXI_CCU_GATE(r_ppu_clk, "r-ppu", "r-apb0",
44 		      0x1ac, BIT(0), 0);
45 
46 static const char * const r_apb0_ir_rx_parents[] = { "osc32k", "dcxo24M" };
47 static SUNXI_CCU_MP_WITH_MUX_GATE(r_apb0_ir_rx_clk, "r-apb0-ir-rx",
48 				  r_apb0_ir_rx_parents, 0x1c0,
49 				  0, 5,		/* M */
50 				  8, 2,		/* P */
51 				  24, 2,	/* mux */
52 				  BIT(31),	/* gate */
53 				  0);
54 
55 static SUNXI_CCU_GATE(r_apb0_bus_ir_rx_clk, "r-apb0-bus-ir-rx", "r-apb0",
56 		      0x1cc, BIT(0), 0);
57 
58 static SUNXI_CCU_GATE(r_ahb_bus_rtc_clk, "r-ahb-rtc", "r-ahb",
59 		      0x20c, BIT(0), 0);
60 
61 static SUNXI_CCU_GATE(r_apb0_cpucfg_clk, "r-apb0-cpucfg", "r-apb0",
62 		      0x22c, BIT(0), 0);
63 
64 static struct ccu_common *sun8iw20_r_ccu_clks[] = {
65 	&r_ahb_clk.common,
66 	&r_apb0_clk.common,
67 	&r_apb0_timer_clk.common,
68 	&r_apb0_twd_clk.common,
69 	&r_ppu_clk.common,
70 	&r_apb0_ir_rx_clk.common,
71 	&r_apb0_bus_ir_rx_clk.common,
72 	&r_ahb_bus_rtc_clk.common,
73 	&r_apb0_cpucfg_clk.common,
74 };
75 
76 static struct clk_hw_onecell_data sun8iw20_r_hw_clks = {
77 	.hws	= {
78 		[CLK_R_AHB]		= &r_ahb_clk.common.hw,
79 		[CLK_R_APB0]		= &r_apb0_clk.common.hw,
80 		[CLK_R_APB0_TIMER]	= &r_apb0_timer_clk.common.hw,
81 		[CLK_R_APB0_TWD]	= &r_apb0_twd_clk.common.hw,
82 		[CLK_R_PPU]		= &r_ppu_clk.common.hw,
83 		[CLK_R_APB0_IRRX]	= &r_apb0_ir_rx_clk.common.hw,
84 		[CLK_R_APB0_BUS_IRRX]	= &r_apb0_bus_ir_rx_clk.common.hw,
85 		[CLK_R_AHB_BUS_RTC]	= &r_ahb_bus_rtc_clk.common.hw,
86 		[CLK_R_APB0_CPUCFG]	= &r_apb0_cpucfg_clk.common.hw,
87 	},
88 	.num	= CLK_NUMBER,
89 };
90 
91 static struct ccu_reset_map sun8iw20_r_ccu_resets[] = {
92 	[RST_R_APB0_TIMER]	=  { 0x11c, BIT(16) },
93 	[RST_R_APB0_TWD]	=  { 0x12c, BIT(16) },
94 	[RST_R_PPU]		=  { 0x1ac, BIT(16) },
95 	[RST_R_APB0_BUS_IRRX]	=  { 0x1cc, BIT(16) },
96 	[RST_R_AHB_BUS_RTC]	=  { 0x20c, BIT(16) },
97 	[RST_R_APB0_CPUCFG]	=  { 0x22c, BIT(16) },
98 };
99 
100 static const struct sunxi_ccu_desc sun8iw20_r_ccu_desc = {
101 	.ccu_clks	= sun8iw20_r_ccu_clks,
102 	.num_ccu_clks	= ARRAY_SIZE(sun8iw20_r_ccu_clks),
103 
104 	.hw_clks	= &sun8iw20_r_hw_clks,
105 
106 	.resets		= sun8iw20_r_ccu_resets,
107 	.num_resets	= ARRAY_SIZE(sun8iw20_r_ccu_resets),
108 };
109 
sun8iw20_r_ccu_probe(struct platform_device * pdev)110 static int sun8iw20_r_ccu_probe(struct platform_device *pdev)
111 {
112 	void __iomem *reg;
113 	int ret;
114 
115 	reg = devm_platform_ioremap_resource(pdev, 0);
116 	if (IS_ERR(reg))
117 		return PTR_ERR(reg);
118 
119 	ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun8iw20_r_ccu_desc);
120 	if (ret)
121 		return ret;
122 
123 	sunxi_ccu_sleep_init(reg, sun8iw20_r_ccu_clks,
124 			     ARRAY_SIZE(sun8iw20_r_ccu_clks),
125 			     NULL, 0);
126 
127 	return 0;
128 }
129 
130 static const struct of_device_id sun8iw20_r_ccu_ids[] = {
131 	{ .compatible = "allwinner,sun8iw20-r-ccu" },
132 	{ .compatible = "allwinner,sun20iw1-r-ccu" },
133 	{ }
134 };
135 
136 static struct platform_driver sun8iw20_r_ccu_driver = {
137 	.probe	= sun8iw20_r_ccu_probe,
138 	.driver	= {
139 		.name	= "sun8iw20-r-ccu",
140 		.of_match_table	= sun8iw20_r_ccu_ids,
141 	},
142 };
143 
sunxi_r_ccu_sun8iw20_init(void)144 static int __init sunxi_r_ccu_sun8iw20_init(void)
145 {
146 	int ret;
147 
148 	ret = platform_driver_register(&sun8iw20_r_ccu_driver);
149 	if (ret)
150 		pr_err("register ccu sun8iw20 failed\n");
151 
152 	return ret;
153 }
154 core_initcall(sunxi_r_ccu_sun8iw20_init);
155 
sunxi_r_ccu_sun8iw20_exit(void)156 static void __exit sunxi_r_ccu_sun8iw20_exit(void)
157 {
158 	return platform_driver_unregister(&sun8iw20_r_ccu_driver);
159 }
160 module_exit(sunxi_r_ccu_sun8iw20_exit);
161 
162 MODULE_VERSION("0.5.0");
163