1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2020 huangzhenwei@allwinnertech.com
4 * Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
5 */
6
7#include <linux/clk-provider.h>
8#include <linux/module.h>
9#include <linux/platform_device.h>
10
11#include "ccu_common.h"
12#include "ccu_reset.h"
13
14#include "ccu_gate.h"
15#include "ccu_mp.h"
16
17#include "ccu-sun20i-d1-r.h"
18
19static const struct clk_parent_data r_ahb_apb0_parents[] = {
20	{ .fw_name = "hosc" },
21	{ .fw_name = "losc" },
22	{ .fw_name = "iosc" },
23	{ .fw_name = "pll-periph" },
24};
25static SUNXI_CCU_MP_DATA_WITH_MUX(r_ahb_clk, "r-ahb",
26				  r_ahb_apb0_parents, 0x000,
27				  0, 5,		/* M */
28				  8, 2,		/* P */
29				  24, 3,	/* mux */
30				  0);
31static const struct clk_hw *r_ahb_hw = &r_ahb_clk.common.hw;
32
33static SUNXI_CCU_MP_DATA_WITH_MUX(r_apb0_clk, "r-apb0",
34				  r_ahb_apb0_parents, 0x00c,
35				  0, 5,		/* M */
36				  8, 2,		/* P */
37				  24, 3,	/* mux */
38				  0);
39static const struct clk_hw *r_apb0_hw = &r_apb0_clk.common.hw;
40
41static SUNXI_CCU_GATE_HWS(bus_r_timer_clk,	"bus-r-timer",	&r_apb0_hw,
42			  0x11c, BIT(0), 0);
43static SUNXI_CCU_GATE_HWS(bus_r_twd_clk,	"bus-r-twd",	&r_apb0_hw,
44			  0x12c, BIT(0), 0);
45static SUNXI_CCU_GATE_HWS(bus_r_ppu_clk,	"bus-r-ppu",	&r_apb0_hw,
46			  0x1ac, BIT(0), 0);
47
48static const struct clk_parent_data r_ir_rx_parents[] = {
49	{ .fw_name = "losc" },
50	{ .fw_name = "hosc" },
51};
52static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(r_ir_rx_clk, "r-ir-rx",
53				       r_ir_rx_parents, 0x1c0,
54				       0, 5,	/* M */
55				       8, 2,	/* P */
56				       24, 2,	/* mux */
57				       BIT(31),	/* gate */
58				       0);
59
60static SUNXI_CCU_GATE_HWS(bus_r_ir_rx_clk,	"bus-r-ir-rx",	&r_apb0_hw,
61			  0x1cc, BIT(0), 0);
62static SUNXI_CCU_GATE_HWS(bus_r_rtc_clk,	"bus-r-rtc",	&r_ahb_hw,
63			  0x20c, BIT(0), 0);
64static SUNXI_CCU_GATE_HWS(bus_r_cpucfg_clk,	"bus-r-cpucfg",	&r_apb0_hw,
65			  0x22c, BIT(0), 0);
66
67static struct ccu_common *sun20i_d1_r_ccu_clks[] = {
68	&r_ahb_clk.common,
69	&r_apb0_clk.common,
70	&bus_r_timer_clk.common,
71	&bus_r_twd_clk.common,
72	&bus_r_ppu_clk.common,
73	&r_ir_rx_clk.common,
74	&bus_r_ir_rx_clk.common,
75	&bus_r_rtc_clk.common,
76	&bus_r_cpucfg_clk.common,
77};
78
79static struct clk_hw_onecell_data sun20i_d1_r_hw_clks = {
80	.num	= CLK_NUMBER,
81	.hws	= {
82		[CLK_R_AHB]		= &r_ahb_clk.common.hw,
83		[CLK_R_APB0]		= &r_apb0_clk.common.hw,
84		[CLK_BUS_R_TIMER]	= &bus_r_timer_clk.common.hw,
85		[CLK_BUS_R_TWD]		= &bus_r_twd_clk.common.hw,
86		[CLK_BUS_R_PPU]		= &bus_r_ppu_clk.common.hw,
87		[CLK_R_IR_RX]		= &r_ir_rx_clk.common.hw,
88		[CLK_BUS_R_IR_RX]	= &bus_r_ir_rx_clk.common.hw,
89		[CLK_BUS_R_RTC]		= &bus_r_rtc_clk.common.hw,
90		[CLK_BUS_R_CPUCFG]	= &bus_r_cpucfg_clk.common.hw,
91	},
92};
93
94static struct ccu_reset_map sun20i_d1_r_ccu_resets[] = {
95	[RST_BUS_R_TIMER]	= { 0x11c, BIT(16) },
96	[RST_BUS_R_TWD]		= { 0x12c, BIT(16) },
97	[RST_BUS_R_PPU]		= { 0x1ac, BIT(16) },
98	[RST_BUS_R_IR_RX]	= { 0x1cc, BIT(16) },
99	[RST_BUS_R_RTC]		= { 0x20c, BIT(16) },
100	[RST_BUS_R_CPUCFG]	= { 0x22c, BIT(16) },
101};
102
103static const struct sunxi_ccu_desc sun20i_d1_r_ccu_desc = {
104	.ccu_clks	= sun20i_d1_r_ccu_clks,
105	.num_ccu_clks	= ARRAY_SIZE(sun20i_d1_r_ccu_clks),
106
107	.hw_clks	= &sun20i_d1_r_hw_clks,
108
109	.resets		= sun20i_d1_r_ccu_resets,
110	.num_resets	= ARRAY_SIZE(sun20i_d1_r_ccu_resets),
111};
112
113static int sun20i_d1_r_ccu_probe(struct platform_device *pdev)
114{
115	void __iomem *reg;
116
117	reg = devm_platform_ioremap_resource(pdev, 0);
118	if (IS_ERR(reg))
119		return PTR_ERR(reg);
120
121	return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun20i_d1_r_ccu_desc);
122}
123
124static const struct of_device_id sun20i_d1_r_ccu_ids[] = {
125	{ .compatible = "allwinner,sun20i-d1-r-ccu" },
126	{ }
127};
128
129static struct platform_driver sun20i_d1_r_ccu_driver = {
130	.probe	= sun20i_d1_r_ccu_probe,
131	.driver	= {
132		.name			= "sun20i-d1-r-ccu",
133		.suppress_bind_attrs	= true,
134		.of_match_table		= sun20i_d1_r_ccu_ids,
135	},
136};
137module_platform_driver(sun20i_d1_r_ccu_driver);
138
139MODULE_IMPORT_NS(SUNXI_CCU);
140MODULE_LICENSE("GPL");
141