clk: sunxi-ng: add support for the Allwinner A100 CCU

Add support for a100 in the sunxi-ng CCU framework.

Signed-off-by: Yangtao Li <frank@allwinnertech.com>
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
Acked-by: Rob Herring <robh@kernel.org>
Link: https://lore.kernel.org/r/1eb41bf6c966a0e54820200650d27a5d4f2ac160.1595572867.git.frank@allwinnertech.com
This commit is contained in:
Yangtao Li 2020-07-24 14:58:43 +08:00 committed by Maxime Ripard
parent 2f704c2969
commit fb038ce4db
No known key found for this signature in database
GPG key ID: E3EF0D6F671851C5
10 changed files with 1804 additions and 0 deletions

View file

@ -17,6 +17,16 @@ config SUN50I_A64_CCU
default ARM64 && ARCH_SUNXI
depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
config SUN50I_A100_CCU
bool "Support for the Allwinner A100 CCU"
default ARM64 && ARCH_SUNXI
depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
config SUN50I_A100_R_CCU
bool "Support for the Allwinner A100 PRCM CCU"
default ARM64 && ARCH_SUNXI
depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
config SUN50I_H6_CCU
bool "Support for the Allwinner H6 CCU"
default ARM64 && ARCH_SUNXI

View file

@ -23,6 +23,8 @@ obj-y += ccu_mp.o
# SoC support
obj-$(CONFIG_SUNIV_F1C100S_CCU) += ccu-suniv-f1c100s.o
obj-$(CONFIG_SUN50I_A64_CCU) += ccu-sun50i-a64.o
obj-$(CONFIG_SUN50I_A100_CCU) += ccu-sun50i-a100.o
obj-$(CONFIG_SUN50I_A100_R_CCU) += ccu-sun50i-a100-r.o
obj-$(CONFIG_SUN50I_H6_CCU) += ccu-sun50i-h6.o
obj-$(CONFIG_SUN50I_H6_R_CCU) += ccu-sun50i-h6-r.o
obj-$(CONFIG_SUN4I_A10_CCU) += ccu-sun4i-a10.o

View file

@ -0,0 +1,214 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com>
*/
#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include "ccu_common.h"
#include "ccu_reset.h"
#include "ccu_div.h"
#include "ccu_gate.h"
#include "ccu_mp.h"
#include "ccu_nm.h"
#include "ccu-sun50i-a100-r.h"
static const char * const cpus_r_apb2_parents[] = { "dcxo24M", "osc32k",
"iosc", "pll-periph0" };
static const struct ccu_mux_var_prediv cpus_r_apb2_predivs[] = {
{ .index = 3, .shift = 0, .width = 5 },
};
static struct ccu_div r_cpus_clk = {
.div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
.mux = {
.shift = 24,
.width = 2,
.var_predivs = cpus_r_apb2_predivs,
.n_var_predivs = ARRAY_SIZE(cpus_r_apb2_predivs),
},
.common = {
.reg = 0x000,
.features = CCU_FEATURE_VARIABLE_PREDIV,
.hw.init = CLK_HW_INIT_PARENTS("cpus",
cpus_r_apb2_parents,
&ccu_div_ops,
0),
},
};
static CLK_FIXED_FACTOR_HW(r_ahb_clk, "r-ahb", &r_cpus_clk.common.hw, 1, 1, 0);
static struct ccu_div r_apb1_clk = {
.div = _SUNXI_CCU_DIV(0, 2),
.common = {
.reg = 0x00c,
.hw.init = CLK_HW_INIT("r-apb1",
"r-ahb",
&ccu_div_ops,
0),
},
};
static struct ccu_div r_apb2_clk = {
.div = _SUNXI_CCU_DIV_FLAGS(8, 2, CLK_DIVIDER_POWER_OF_TWO),
.mux = {
.shift = 24,
.width = 2,
.var_predivs = cpus_r_apb2_predivs,
.n_var_predivs = ARRAY_SIZE(cpus_r_apb2_predivs),
},
.common = {
.reg = 0x010,
.features = CCU_FEATURE_VARIABLE_PREDIV,
.hw.init = CLK_HW_INIT_PARENTS("r-apb2",
cpus_r_apb2_parents,
&ccu_div_ops,
0),
},
};
static const struct clk_parent_data clk_parent_r_apb1[] = {
{ .hw = &r_apb1_clk.common.hw },
};
static const struct clk_parent_data clk_parent_r_apb2[] = {
{ .hw = &r_apb2_clk.common.hw },
};
static SUNXI_CCU_GATE_DATA(r_apb1_timer_clk, "r-apb1-timer", clk_parent_r_apb1,
0x11c, BIT(0), 0);
static SUNXI_CCU_GATE_DATA(r_apb1_twd_clk, "r-apb1-twd", clk_parent_r_apb1,
0x12c, BIT(0), 0);
static const char * const r_apb1_pwm_clk_parents[] = { "dcxo24M", "osc32k",
"iosc" };
static SUNXI_CCU_MUX(r_apb1_pwm_clk, "r-apb1-pwm", r_apb1_pwm_clk_parents,
0x130, 24, 2, 0);
static SUNXI_CCU_GATE_DATA(r_apb1_bus_pwm_clk, "r-apb1-bus-pwm",
clk_parent_r_apb1, 0x13c, BIT(0), 0);
static SUNXI_CCU_GATE_DATA(r_apb1_ppu_clk, "r-apb1-ppu", clk_parent_r_apb1,
0x17c, BIT(0), 0);
static SUNXI_CCU_GATE_DATA(r_apb2_uart_clk, "r-apb2-uart", clk_parent_r_apb2,
0x18c, BIT(0), 0);
static SUNXI_CCU_GATE_DATA(r_apb2_i2c0_clk, "r-apb2-i2c0", clk_parent_r_apb2,
0x19c, BIT(0), 0);
static SUNXI_CCU_GATE_DATA(r_apb2_i2c1_clk, "r-apb2-i2c1", clk_parent_r_apb2,
0x19c, BIT(1), 0);
static const char * const r_apb1_ir_rx_parents[] = { "osc32k", "dcxo24M" };
static SUNXI_CCU_MP_WITH_MUX_GATE(r_apb1_ir_rx_clk, "r-apb1-ir-rx",
r_apb1_ir_rx_parents, 0x1c0,
0, 5, /* M */
8, 2, /* P */
24, 1, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_GATE_DATA(r_apb1_bus_ir_rx_clk, "r-apb1-bus-ir-rx",
clk_parent_r_apb1, 0x1cc, BIT(0), 0);
static SUNXI_CCU_GATE(r_ahb_bus_rtc_clk, "r-ahb-rtc", "r-ahb",
0x20c, BIT(0), 0);
static struct ccu_common *sun50i_a100_r_ccu_clks[] = {
&r_cpus_clk.common,
&r_apb1_clk.common,
&r_apb2_clk.common,
&r_apb1_timer_clk.common,
&r_apb1_twd_clk.common,
&r_apb1_pwm_clk.common,
&r_apb1_bus_pwm_clk.common,
&r_apb1_ppu_clk.common,
&r_apb2_uart_clk.common,
&r_apb2_i2c0_clk.common,
&r_apb2_i2c1_clk.common,
&r_apb1_ir_rx_clk.common,
&r_apb1_bus_ir_rx_clk.common,
&r_ahb_bus_rtc_clk.common,
};
static struct clk_hw_onecell_data sun50i_a100_r_hw_clks = {
.hws = {
[CLK_R_CPUS] = &r_cpus_clk.common.hw,
[CLK_R_AHB] = &r_ahb_clk.hw,
[CLK_R_APB1] = &r_apb1_clk.common.hw,
[CLK_R_APB2] = &r_apb2_clk.common.hw,
[CLK_R_APB1_TIMER] = &r_apb1_timer_clk.common.hw,
[CLK_R_APB1_TWD] = &r_apb1_twd_clk.common.hw,
[CLK_R_APB1_PWM] = &r_apb1_pwm_clk.common.hw,
[CLK_R_APB1_BUS_PWM] = &r_apb1_bus_pwm_clk.common.hw,
[CLK_R_APB1_PPU] = &r_apb1_ppu_clk.common.hw,
[CLK_R_APB2_UART] = &r_apb2_uart_clk.common.hw,
[CLK_R_APB2_I2C0] = &r_apb2_i2c0_clk.common.hw,
[CLK_R_APB2_I2C1] = &r_apb2_i2c1_clk.common.hw,
[CLK_R_APB1_IR] = &r_apb1_ir_rx_clk.common.hw,
[CLK_R_APB1_BUS_IR] = &r_apb1_bus_ir_rx_clk.common.hw,
[CLK_R_AHB_BUS_RTC] = &r_ahb_bus_rtc_clk.common.hw,
},
.num = CLK_NUMBER,
};
static struct ccu_reset_map sun50i_a100_r_ccu_resets[] = {
[RST_R_APB1_TIMER] = { 0x11c, BIT(16) },
[RST_R_APB1_BUS_PWM] = { 0x13c, BIT(16) },
[RST_R_APB1_PPU] = { 0x17c, BIT(16) },
[RST_R_APB2_UART] = { 0x18c, BIT(16) },
[RST_R_APB2_I2C0] = { 0x19c, BIT(16) },
[RST_R_APB2_I2C1] = { 0x19c, BIT(17) },
[RST_R_APB1_BUS_IR] = { 0x1cc, BIT(16) },
[RST_R_AHB_BUS_RTC] = { 0x20c, BIT(16) },
};
static const struct sunxi_ccu_desc sun50i_a100_r_ccu_desc = {
.ccu_clks = sun50i_a100_r_ccu_clks,
.num_ccu_clks = ARRAY_SIZE(sun50i_a100_r_ccu_clks),
.hw_clks = &sun50i_a100_r_hw_clks,
.resets = sun50i_a100_r_ccu_resets,
.num_resets = ARRAY_SIZE(sun50i_a100_r_ccu_resets),
};
static int sun50i_a100_r_ccu_probe(struct platform_device *pdev)
{
void __iomem *reg;
reg = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(reg))
return PTR_ERR(reg);
return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a100_r_ccu_desc);
}
static const struct of_device_id sun50i_a100_r_ccu_ids[] = {
{ .compatible = "allwinner,sun50i-a100-r-ccu" },
{ }
};
static struct platform_driver sun50i_a100_r_ccu_driver = {
.probe = sun50i_a100_r_ccu_probe,
.driver = {
.name = "sun50i-a100-r-ccu",
.of_match_table = sun50i_a100_r_ccu_ids,
},
};
module_platform_driver(sun50i_a100_r_ccu_driver);

View file

@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com>
*/
#ifndef _CCU_SUN50I_A100_R_H
#define _CCU_SUN50I_A100_R_H
#include <dt-bindings/clock/sun50i-a100-r-ccu.h>
#include <dt-bindings/reset/sun50i-a100-r-ccu.h>
#define CLK_R_CPUS 0
#define CLK_R_AHB 1
/* exported except APB1 for R_PIO */
#define CLK_R_APB2 3
#define CLK_NUMBER (CLK_R_AHB_BUS_RTC + 1)
#endif /* _CCU_SUN50I_A100_R_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,56 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com>
*/
#ifndef _CCU_SUN50I_A100_H_
#define _CCU_SUN50I_A100_H_
#include <dt-bindings/clock/sun50i-a100-ccu.h>
#include <dt-bindings/reset/sun50i-a100-ccu.h>
#define CLK_OSC12M 0
#define CLK_PLL_CPUX 1
#define CLK_PLL_DDR0 2
/* PLL_PERIPH0 exported for PRCM */
#define CLK_PLL_PERIPH0_2X 4
#define CLK_PLL_PERIPH1 5
#define CLK_PLL_PERIPH1_2X 6
#define CLK_PLL_GPU 7
#define CLK_PLL_VIDEO0 8
#define CLK_PLL_VIDEO0_2X 9
#define CLK_PLL_VIDEO0_4X 10
#define CLK_PLL_VIDEO1 11
#define CLK_PLL_VIDEO1_2X 12
#define CLK_PLL_VIDEO1_4X 13
#define CLK_PLL_VIDEO2 14
#define CLK_PLL_VIDEO2_2X 15
#define CLK_PLL_VIDEO2_4X 16
#define CLK_PLL_VIDEO3 17
#define CLK_PLL_VIDEO3_2X 18
#define CLK_PLL_VIDEO3_4X 19
#define CLK_PLL_VE 20
#define CLK_PLL_COM 21
#define CLK_PLL_COM_AUDIO 22
#define CLK_PLL_AUDIO 23
/* CPUX clock exported for DVFS */
#define CLK_AXI 25
#define CLK_CPUX_APB 26
#define CLK_PSI_AHB1_AHB2 27
#define CLK_AHB3 28
/* APB1 clock exported for PIO */
#define CLK_APB2 30
/* All module clocks and bus gates are exported except DRAM */
#define CLK_BUS_DRAM 58
#define CLK_NUMBER (CLK_CSI_ISP + 1)
#endif /* _CCU_SUN50I_A100_H_ */

View file

@ -0,0 +1,116 @@
/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
/*
* Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com>
*/
#ifndef _DT_BINDINGS_CLK_SUN50I_A100_H_
#define _DT_BINDINGS_CLK_SUN50I_A100_H_
#define CLK_PLL_PERIPH0 3
#define CLK_CPUX 24
#define CLK_APB1 29
#define CLK_MBUS 31
#define CLK_DE 32
#define CLK_BUS_DE 33
#define CLK_G2D 34
#define CLK_BUS_G2D 35
#define CLK_GPU 36
#define CLK_BUS_GPU 37
#define CLK_CE 38
#define CLK_BUS_CE 39
#define CLK_VE 40
#define CLK_BUS_VE 41
#define CLK_BUS_DMA 42
#define CLK_BUS_MSGBOX 43
#define CLK_BUS_SPINLOCK 44
#define CLK_BUS_HSTIMER 45
#define CLK_AVS 46
#define CLK_BUS_DBG 47
#define CLK_BUS_PSI 48
#define CLK_BUS_PWM 49
#define CLK_BUS_IOMMU 50
#define CLK_MBUS_DMA 51
#define CLK_MBUS_VE 52
#define CLK_MBUS_CE 53
#define CLK_MBUS_NAND 54
#define CLK_MBUS_CSI 55
#define CLK_MBUS_ISP 56
#define CLK_MBUS_G2D 57
#define CLK_NAND0 59
#define CLK_NAND1 60
#define CLK_BUS_NAND 61
#define CLK_MMC0 62
#define CLK_MMC1 63
#define CLK_MMC2 64
#define CLK_MMC3 65
#define CLK_BUS_MMC0 66
#define CLK_BUS_MMC1 67
#define CLK_BUS_MMC2 68
#define CLK_BUS_UART0 69
#define CLK_BUS_UART1 70
#define CLK_BUS_UART2 71
#define CLK_BUS_UART3 72
#define CLK_BUS_UART4 73
#define CLK_BUS_I2C0 74
#define CLK_BUS_I2C1 75
#define CLK_BUS_I2C2 76
#define CLK_BUS_I2C3 77
#define CLK_SPI0 78
#define CLK_SPI1 79
#define CLK_SPI2 80
#define CLK_BUS_SPI0 81
#define CLK_BUS_SPI1 82
#define CLK_BUS_SPI2 83
#define CLK_EMAC_25M 84
#define CLK_BUS_EMAC 85
#define CLK_IR_RX 86
#define CLK_BUS_IR_RX 87
#define CLK_IR_TX 88
#define CLK_BUS_IR_TX 89
#define CLK_BUS_GPADC 90
#define CLK_BUS_THS 91
#define CLK_I2S0 92
#define CLK_I2S1 93
#define CLK_I2S2 94
#define CLK_I2S3 95
#define CLK_BUS_I2S0 96
#define CLK_BUS_I2S1 97
#define CLK_BUS_I2S2 98
#define CLK_BUS_I2S3 99
#define CLK_SPDIF 100
#define CLK_BUS_SPDIF 101
#define CLK_DMIC 102
#define CLK_BUS_DMIC 103
#define CLK_AUDIO_DAC 104
#define CLK_AUDIO_ADC 105
#define CLK_AUDIO_4X 106
#define CLK_BUS_AUDIO_CODEC 107
#define CLK_USB_OHCI0 108
#define CLK_USB_PHY0 109
#define CLK_USB_OHCI1 110
#define CLK_USB_PHY1 111
#define CLK_BUS_OHCI0 112
#define CLK_BUS_OHCI1 113
#define CLK_BUS_EHCI0 114
#define CLK_BUS_EHCI1 115
#define CLK_BUS_OTG 116
#define CLK_BUS_LRADC 117
#define CLK_BUS_DPSS_TOP0 118
#define CLK_BUS_DPSS_TOP1 119
#define CLK_MIPI_DSI 120
#define CLK_BUS_MIPI_DSI 121
#define CLK_TCON_LCD 122
#define CLK_BUS_TCON_LCD 123
#define CLK_LEDC 124
#define CLK_BUS_LEDC 125
#define CLK_CSI_TOP 126
#define CLK_CSI0_MCLK 127
#define CLK_CSI1_MCLK 128
#define CLK_BUS_CSI 129
#define CLK_CSI_ISP 130
#endif /* _DT_BINDINGS_CLK_SUN50I_A100_H_ */

View file

@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com>
*/
#ifndef _DT_BINDINGS_CLK_SUN50I_A100_R_CCU_H_
#define _DT_BINDINGS_CLK_SUN50I_A100_R_CCU_H_
#define CLK_R_APB1 2
#define CLK_R_APB1_TIMER 4
#define CLK_R_APB1_TWD 5
#define CLK_R_APB1_PWM 6
#define CLK_R_APB1_BUS_PWM 7
#define CLK_R_APB1_PPU 8
#define CLK_R_APB2_UART 9
#define CLK_R_APB2_I2C0 10
#define CLK_R_APB2_I2C1 11
#define CLK_R_APB1_IR 12
#define CLK_R_APB1_BUS_IR 13
#define CLK_R_AHB_BUS_RTC 14
#endif /* _DT_BINDINGS_CLK_SUN50I_A100_R_CCU_H_ */

View file

@ -0,0 +1,68 @@
/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
/*
* Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com>
*/
#ifndef _DT_BINDINGS_RESET_SUN50I_A100_H_
#define _DT_BINDINGS_RESET_SUN50I_A100_H_
#define RST_MBUS 0
#define RST_BUS_DE 1
#define RST_BUS_G2D 2
#define RST_BUS_GPU 3
#define RST_BUS_CE 4
#define RST_BUS_VE 5
#define RST_BUS_DMA 6
#define RST_BUS_MSGBOX 7
#define RST_BUS_SPINLOCK 8
#define RST_BUS_HSTIMER 9
#define RST_BUS_DBG 10
#define RST_BUS_PSI 11
#define RST_BUS_PWM 12
#define RST_BUS_DRAM 13
#define RST_BUS_NAND 14
#define RST_BUS_MMC0 15
#define RST_BUS_MMC1 16
#define RST_BUS_MMC2 17
#define RST_BUS_UART0 18
#define RST_BUS_UART1 19
#define RST_BUS_UART2 20
#define RST_BUS_UART3 21
#define RST_BUS_UART4 22
#define RST_BUS_I2C0 23
#define RST_BUS_I2C1 24
#define RST_BUS_I2C2 25
#define RST_BUS_I2C3 26
#define RST_BUS_SPI0 27
#define RST_BUS_SPI1 28
#define RST_BUS_SPI2 29
#define RST_BUS_EMAC 30
#define RST_BUS_IR_RX 31
#define RST_BUS_IR_TX 32
#define RST_BUS_GPADC 33
#define RST_BUS_THS 34
#define RST_BUS_I2S0 35
#define RST_BUS_I2S1 36
#define RST_BUS_I2S2 37
#define RST_BUS_I2S3 38
#define RST_BUS_SPDIF 39
#define RST_BUS_DMIC 40
#define RST_BUS_AUDIO_CODEC 41
#define RST_USB_PHY0 42
#define RST_USB_PHY1 43
#define RST_BUS_OHCI0 44
#define RST_BUS_OHCI1 45
#define RST_BUS_EHCI0 46
#define RST_BUS_EHCI1 47
#define RST_BUS_OTG 48
#define RST_BUS_LRADC 49
#define RST_BUS_DPSS_TOP0 50
#define RST_BUS_DPSS_TOP1 51
#define RST_BUS_MIPI_DSI 52
#define RST_BUS_TCON_LCD 53
#define RST_BUS_LVDS 54
#define RST_BUS_LEDC 55
#define RST_BUS_CSI 56
#define RST_BUS_CSI_ISP 57
#endif /* _DT_BINDINGS_RESET_SUN50I_A100_H_ */

View file

@ -0,0 +1,18 @@
/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
/*
* Copyright (c) 2020 Yangtao Li <frank@allwinnertech.com>
*/
#ifndef _DT_BINDINGS_RST_SUN50I_A100_R_CCU_H_
#define _DT_BINDINGS_RST_SUN50I_A100_R_CCU_H_
#define RST_R_APB1_TIMER 0
#define RST_R_APB1_BUS_PWM 1
#define RST_R_APB1_PPU 2
#define RST_R_APB2_UART 3
#define RST_R_APB2_I2C0 4
#define RST_R_APB2_I2C1 5
#define RST_R_APB1_BUS_IR 6
#define RST_R_AHB_BUS_RTC 7
#endif /* _DT_BINDINGS_RST_SUN50I_A100_R_CCU_H_ */