mirror of
https://github.com/smaeul/u-boot.git
synced 2025-10-13 20:36:02 +01:00
Merge branch 'patch/clk-support' into allwinner
This commit is contained in:
commit
83456cc1ad
@ -38,12 +38,21 @@ config CLK_SUN6I_A31
|
||||
This enables common clock driver support for platforms based
|
||||
on Allwinner A31/A31s SoC.
|
||||
|
||||
config CLK_SUN6I_A31_APB0
|
||||
bool "Clock driver for Allwinner A31 generation PRCM (legacy)"
|
||||
default MACH_SUN6I || MACH_SUN8I_A23 || MACH_SUN8I_A33
|
||||
help
|
||||
This enables common clock driver support for the PRCM
|
||||
in Allwinner A31/A31s/A23/A33 SoCs using the legacy PRCM
|
||||
MFD binding.
|
||||
|
||||
config CLK_SUN6I_A31_R
|
||||
bool "Clock driver for Allwinner A31 generation PRCM"
|
||||
bool "Clock driver for Allwinner A31 generation PRCM (CCU)"
|
||||
default SUNXI_GEN_SUN6I
|
||||
help
|
||||
This enables common clock driver support for the PRCM
|
||||
in Allwinner A31/A31s/A23/A33/A83T/H3/A64/H5 SoCs.
|
||||
in Allwinner A31/A31s/A23/A33/A83T/H3/A64/H5 SoCs using
|
||||
the new CCU binding.
|
||||
|
||||
config CLK_SUN8I_A23
|
||||
bool "Clock driver for Allwinner A23/A33"
|
||||
@ -87,6 +96,12 @@ config CLK_SUN8I_H3
|
||||
This enables common clock driver support for platforms based
|
||||
on Allwinner H3/H5 SoC.
|
||||
|
||||
config CLK_SUN20I_D1
|
||||
bool "Clock driver for Allwinner D1"
|
||||
help
|
||||
This enables common clock driver support for platforms based
|
||||
on Allwinner D1 SoC.
|
||||
|
||||
config CLK_SUN50I_H6
|
||||
bool "Clock driver for Allwinner H6"
|
||||
default MACH_SUN50I_H6
|
||||
|
@ -12,6 +12,7 @@ obj-$(CONFIG_CLK_SUNIV_F1C100S) += clk_f1c100s.o
|
||||
obj-$(CONFIG_CLK_SUN4I_A10) += clk_a10.o
|
||||
obj-$(CONFIG_CLK_SUN5I_A10S) += clk_a10s.o
|
||||
obj-$(CONFIG_CLK_SUN6I_A31) += clk_a31.o
|
||||
obj-$(CONFIG_CLK_SUN6I_A31_APB0) += clk_a31_apb0.o
|
||||
obj-$(CONFIG_CLK_SUN6I_A31_R) += clk_a31_r.o
|
||||
obj-$(CONFIG_CLK_SUN8I_A23) += clk_a23.o
|
||||
obj-$(CONFIG_CLK_SUN8I_A83T) += clk_a83t.o
|
||||
@ -19,6 +20,7 @@ obj-$(CONFIG_CLK_SUN8I_R40) += clk_r40.o
|
||||
obj-$(CONFIG_CLK_SUN8I_V3S) += clk_v3s.o
|
||||
obj-$(CONFIG_CLK_SUN9I_A80) += clk_a80.o
|
||||
obj-$(CONFIG_CLK_SUN8I_H3) += clk_h3.o
|
||||
obj-$(CONFIG_CLK_SUN20I_D1) += clk_d1.o
|
||||
obj-$(CONFIG_CLK_SUN50I_H6) += clk_h6.o
|
||||
obj-$(CONFIG_CLK_SUN50I_H6_R) += clk_h6_r.o
|
||||
obj-$(CONFIG_CLK_SUN50I_H616) += clk_h616.o
|
||||
|
@ -66,30 +66,9 @@ static struct ccu_reset a10_resets[] = {
|
||||
[RST_USB_PHY2] = RESET(0x0cc, BIT(2)),
|
||||
};
|
||||
|
||||
static const struct ccu_desc a10_ccu_desc = {
|
||||
const struct ccu_desc a10_ccu_desc = {
|
||||
.gates = a10_gates,
|
||||
.resets = a10_resets,
|
||||
};
|
||||
|
||||
static int a10_clk_bind(struct udevice *dev)
|
||||
{
|
||||
return sunxi_reset_bind(dev, ARRAY_SIZE(a10_resets));
|
||||
}
|
||||
|
||||
static const struct udevice_id a10_ccu_ids[] = {
|
||||
{ .compatible = "allwinner,sun4i-a10-ccu",
|
||||
.data = (ulong)&a10_ccu_desc },
|
||||
{ .compatible = "allwinner,sun7i-a20-ccu",
|
||||
.data = (ulong)&a10_ccu_desc },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(clk_sun4i_a10) = {
|
||||
.name = "sun4i_a10_ccu",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = a10_ccu_ids,
|
||||
.priv_auto = sizeof(struct ccu_priv),
|
||||
.ops = &sunxi_clk_ops,
|
||||
.probe = sunxi_clk_probe,
|
||||
.bind = a10_clk_bind,
|
||||
.num_gates = ARRAY_SIZE(a10_gates),
|
||||
.num_resets = ARRAY_SIZE(a10_resets),
|
||||
};
|
||||
|
@ -51,30 +51,9 @@ static struct ccu_reset a10s_resets[] = {
|
||||
[RST_USB_PHY1] = RESET(0x0cc, BIT(1)),
|
||||
};
|
||||
|
||||
static const struct ccu_desc a10s_ccu_desc = {
|
||||
const struct ccu_desc a10s_ccu_desc = {
|
||||
.gates = a10s_gates,
|
||||
.resets = a10s_resets,
|
||||
};
|
||||
|
||||
static int a10s_clk_bind(struct udevice *dev)
|
||||
{
|
||||
return sunxi_reset_bind(dev, ARRAY_SIZE(a10s_resets));
|
||||
}
|
||||
|
||||
static const struct udevice_id a10s_ccu_ids[] = {
|
||||
{ .compatible = "allwinner,sun5i-a10s-ccu",
|
||||
.data = (ulong)&a10s_ccu_desc },
|
||||
{ .compatible = "allwinner,sun5i-a13-ccu",
|
||||
.data = (ulong)&a10s_ccu_desc },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(clk_sun5i_a10s) = {
|
||||
.name = "sun5i_a10s_ccu",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = a10s_ccu_ids,
|
||||
.priv_auto = sizeof(struct ccu_priv),
|
||||
.ops = &sunxi_clk_ops,
|
||||
.probe = sunxi_clk_probe,
|
||||
.bind = a10s_clk_bind,
|
||||
.num_gates = ARRAY_SIZE(a10s_gates),
|
||||
.num_resets = ARRAY_SIZE(a10s_resets),
|
||||
};
|
||||
|
@ -71,30 +71,9 @@ static struct ccu_reset a23_resets[] = {
|
||||
[RST_BUS_UART4] = RESET(0x2d8, BIT(20)),
|
||||
};
|
||||
|
||||
static const struct ccu_desc a23_ccu_desc = {
|
||||
const struct ccu_desc a23_ccu_desc = {
|
||||
.gates = a23_gates,
|
||||
.resets = a23_resets,
|
||||
};
|
||||
|
||||
static int a23_clk_bind(struct udevice *dev)
|
||||
{
|
||||
return sunxi_reset_bind(dev, ARRAY_SIZE(a23_resets));
|
||||
}
|
||||
|
||||
static const struct udevice_id a23_clk_ids[] = {
|
||||
{ .compatible = "allwinner,sun8i-a23-ccu",
|
||||
.data = (ulong)&a23_ccu_desc },
|
||||
{ .compatible = "allwinner,sun8i-a33-ccu",
|
||||
.data = (ulong)&a23_ccu_desc },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(clk_sun8i_a23) = {
|
||||
.name = "sun8i_a23_ccu",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = a23_clk_ids,
|
||||
.priv_auto = sizeof(struct ccu_priv),
|
||||
.ops = &sunxi_clk_ops,
|
||||
.probe = sunxi_clk_probe,
|
||||
.bind = a23_clk_bind,
|
||||
.num_gates = ARRAY_SIZE(a23_gates),
|
||||
.num_resets = ARRAY_SIZE(a23_resets),
|
||||
};
|
||||
|
@ -95,28 +95,9 @@ static struct ccu_reset a31_resets[] = {
|
||||
[RST_APB2_UART5] = RESET(0x2d8, BIT(21)),
|
||||
};
|
||||
|
||||
static const struct ccu_desc a31_ccu_desc = {
|
||||
const struct ccu_desc a31_ccu_desc = {
|
||||
.gates = a31_gates,
|
||||
.resets = a31_resets,
|
||||
};
|
||||
|
||||
static int a31_clk_bind(struct udevice *dev)
|
||||
{
|
||||
return sunxi_reset_bind(dev, ARRAY_SIZE(a31_resets));
|
||||
}
|
||||
|
||||
static const struct udevice_id a31_clk_ids[] = {
|
||||
{ .compatible = "allwinner,sun6i-a31-ccu",
|
||||
.data = (ulong)&a31_ccu_desc },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(clk_sun6i_a31) = {
|
||||
.name = "sun6i_a31_ccu",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = a31_clk_ids,
|
||||
.priv_auto = sizeof(struct ccu_priv),
|
||||
.ops = &sunxi_clk_ops,
|
||||
.probe = sunxi_clk_probe,
|
||||
.bind = a31_clk_bind,
|
||||
.num_gates = ARRAY_SIZE(a31_gates),
|
||||
.num_resets = ARRAY_SIZE(a31_resets),
|
||||
};
|
||||
|
97
drivers/clk/sunxi/clk_a31_apb0.c
Normal file
97
drivers/clk/sunxi/clk_a31_apb0.c
Normal file
@ -0,0 +1,97 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (C) Samuel Holland <samuel@sholland.org>
|
||||
*/
|
||||
|
||||
#include <clk-uclass.h>
|
||||
#include <dm.h>
|
||||
#include <clk/sunxi.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
static struct ccu_clk_gate sun6i_apb0_gates[] = {
|
||||
[0] = GATE(0x028, BIT(0)),
|
||||
[1] = GATE(0x028, BIT(1)),
|
||||
[2] = GATE(0x028, BIT(2)),
|
||||
[3] = GATE(0x028, BIT(3)),
|
||||
[4] = GATE(0x028, BIT(4)),
|
||||
[5] = GATE(0x028, BIT(5)),
|
||||
[6] = GATE(0x028, BIT(6)),
|
||||
[7] = GATE(0x028, BIT(7)),
|
||||
};
|
||||
|
||||
static struct ccu_reset sun6i_apb0_resets[] = {
|
||||
[0] = RESET(0x0b0, BIT(0)),
|
||||
[1] = RESET(0x0b0, BIT(1)),
|
||||
[2] = RESET(0x0b0, BIT(2)),
|
||||
[3] = RESET(0x0b0, BIT(3)),
|
||||
[4] = RESET(0x0b0, BIT(4)),
|
||||
[5] = RESET(0x0b0, BIT(5)),
|
||||
[6] = RESET(0x0b0, BIT(6)),
|
||||
[7] = RESET(0x0b0, BIT(7)),
|
||||
};
|
||||
|
||||
const struct ccu_desc sun6i_apb0_clk_desc = {
|
||||
.gates = sun6i_apb0_gates,
|
||||
.resets = sun6i_apb0_resets,
|
||||
.num_gates = ARRAY_SIZE(sun6i_apb0_gates),
|
||||
.num_resets = ARRAY_SIZE(sun6i_apb0_resets),
|
||||
};
|
||||
|
||||
static int sun6i_apb0_of_to_plat(struct udevice *dev)
|
||||
{
|
||||
struct ccu_plat *plat = dev_get_plat(dev);
|
||||
|
||||
plat->base = dev_read_addr_ptr(dev->parent);
|
||||
if (!plat->base)
|
||||
return -ENOMEM;
|
||||
|
||||
plat->desc = (const struct ccu_desc *)dev_get_driver_data(dev);
|
||||
if (!plat->desc)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id sun6i_apb0_clk_ids[] = {
|
||||
{ .compatible = "allwinner,sun6i-a31-apb0-gates-clk",
|
||||
.data = (ulong)&sun6i_apb0_clk_desc },
|
||||
{ .compatible = "allwinner,sun8i-a23-apb0-gates-clk",
|
||||
.data = (ulong)&sun6i_apb0_clk_desc },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sun6i_apb0_clk) = {
|
||||
.name = "sun6i_apb0_clk",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = sun6i_apb0_clk_ids,
|
||||
.of_to_plat = sun6i_apb0_of_to_plat,
|
||||
.plat_auto = sizeof(struct ccu_plat),
|
||||
.ops = &sunxi_clk_ops,
|
||||
};
|
||||
|
||||
static const struct udevice_id sun6i_apb0_reset_ids[] = {
|
||||
{ .compatible = "allwinner,sun6i-a31-clock-reset",
|
||||
.data = (ulong)&sun6i_apb0_clk_desc },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sun6i_apb0_reset) = {
|
||||
.name = "sun6i_apb0_reset",
|
||||
.id = UCLASS_RESET,
|
||||
.of_match = sun6i_apb0_reset_ids,
|
||||
.of_to_plat = sun6i_apb0_of_to_plat,
|
||||
.plat_auto = sizeof(struct ccu_plat),
|
||||
.ops = &sunxi_reset_ops,
|
||||
};
|
||||
|
||||
static const struct udevice_id sun6i_prcm_mfd_ids[] = {
|
||||
{ .compatible = "allwinner,sun6i-a31-prcm" },
|
||||
{ .compatible = "allwinner,sun8i-a23-prcm" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sun6i_prcm_mfd) = {
|
||||
.name = "sun6i_prcm_mfd",
|
||||
.id = UCLASS_SIMPLE_BUS,
|
||||
.of_match = sun6i_prcm_mfd_ids,
|
||||
};
|
@ -28,32 +28,9 @@ static struct ccu_reset a31_r_resets[] = {
|
||||
[RST_APB0_I2C] = RESET(0x0b0, BIT(6)),
|
||||
};
|
||||
|
||||
static const struct ccu_desc a31_r_ccu_desc = {
|
||||
const struct ccu_desc a31_r_ccu_desc = {
|
||||
.gates = a31_r_gates,
|
||||
.resets = a31_r_resets,
|
||||
};
|
||||
|
||||
static int a31_r_clk_bind(struct udevice *dev)
|
||||
{
|
||||
return sunxi_reset_bind(dev, ARRAY_SIZE(a31_r_resets));
|
||||
}
|
||||
|
||||
static const struct udevice_id a31_r_clk_ids[] = {
|
||||
{ .compatible = "allwinner,sun8i-a83t-r-ccu",
|
||||
.data = (ulong)&a31_r_ccu_desc },
|
||||
{ .compatible = "allwinner,sun8i-h3-r-ccu",
|
||||
.data = (ulong)&a31_r_ccu_desc },
|
||||
{ .compatible = "allwinner,sun50i-a64-r-ccu",
|
||||
.data = (ulong)&a31_r_ccu_desc },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(clk_sun6i_a31_r) = {
|
||||
.name = "sun6i_a31_r_ccu",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = a31_r_clk_ids,
|
||||
.priv_auto = sizeof(struct ccu_priv),
|
||||
.ops = &sunxi_clk_ops,
|
||||
.probe = sunxi_clk_probe,
|
||||
.bind = a31_r_clk_bind,
|
||||
.num_gates = ARRAY_SIZE(a31_r_gates),
|
||||
.num_resets = ARRAY_SIZE(a31_r_resets),
|
||||
};
|
||||
|
@ -80,28 +80,9 @@ static const struct ccu_reset a64_resets[] = {
|
||||
[RST_BUS_UART4] = RESET(0x2d8, BIT(20)),
|
||||
};
|
||||
|
||||
static const struct ccu_desc a64_ccu_desc = {
|
||||
const struct ccu_desc a64_ccu_desc = {
|
||||
.gates = a64_gates,
|
||||
.resets = a64_resets,
|
||||
};
|
||||
|
||||
static int a64_clk_bind(struct udevice *dev)
|
||||
{
|
||||
return sunxi_reset_bind(dev, ARRAY_SIZE(a64_resets));
|
||||
}
|
||||
|
||||
static const struct udevice_id a64_ccu_ids[] = {
|
||||
{ .compatible = "allwinner,sun50i-a64-ccu",
|
||||
.data = (ulong)&a64_ccu_desc },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(clk_sun50i_a64) = {
|
||||
.name = "sun50i_a64_ccu",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = a64_ccu_ids,
|
||||
.priv_auto = sizeof(struct ccu_priv),
|
||||
.ops = &sunxi_clk_ops,
|
||||
.probe = sunxi_clk_probe,
|
||||
.bind = a64_clk_bind,
|
||||
.num_gates = ARRAY_SIZE(a64_gates),
|
||||
.num_resets = ARRAY_SIZE(a64_resets),
|
||||
};
|
||||
|
@ -82,40 +82,16 @@ static const struct ccu_reset a80_mmc_resets[] = {
|
||||
[3] = GATE(0xc, BIT(18)),
|
||||
};
|
||||
|
||||
static const struct ccu_desc a80_ccu_desc = {
|
||||
const struct ccu_desc a80_ccu_desc = {
|
||||
.gates = a80_gates,
|
||||
.resets = a80_resets,
|
||||
.num_gates = ARRAY_SIZE(a80_gates),
|
||||
.num_resets = ARRAY_SIZE(a80_resets),
|
||||
};
|
||||
|
||||
static const struct ccu_desc a80_mmc_clk_desc = {
|
||||
const struct ccu_desc a80_mmc_clk_desc = {
|
||||
.gates = a80_mmc_gates,
|
||||
.resets = a80_mmc_resets,
|
||||
};
|
||||
|
||||
static int a80_clk_bind(struct udevice *dev)
|
||||
{
|
||||
ulong count = ARRAY_SIZE(a80_resets);
|
||||
|
||||
if (device_is_compatible(dev, "allwinner,sun9i-a80-mmc-config-clk"))
|
||||
count = ARRAY_SIZE(a80_mmc_resets);
|
||||
|
||||
return sunxi_reset_bind(dev, count);
|
||||
}
|
||||
|
||||
static const struct udevice_id a80_ccu_ids[] = {
|
||||
{ .compatible = "allwinner,sun9i-a80-ccu",
|
||||
.data = (ulong)&a80_ccu_desc },
|
||||
{ .compatible = "allwinner,sun9i-a80-mmc-config-clk",
|
||||
.data = (ulong)&a80_mmc_clk_desc },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(clk_sun9i_a80) = {
|
||||
.name = "sun9i_a80_ccu",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = a80_ccu_ids,
|
||||
.priv_auto = sizeof(struct ccu_priv),
|
||||
.ops = &sunxi_clk_ops,
|
||||
.probe = sunxi_clk_probe,
|
||||
.bind = a80_clk_bind,
|
||||
.num_gates = ARRAY_SIZE(a80_mmc_gates),
|
||||
.num_resets = ARRAY_SIZE(a80_mmc_resets),
|
||||
};
|
||||
|
@ -75,28 +75,9 @@ static struct ccu_reset a83t_resets[] = {
|
||||
[RST_BUS_UART4] = RESET(0x2d8, BIT(20)),
|
||||
};
|
||||
|
||||
static const struct ccu_desc a83t_ccu_desc = {
|
||||
const struct ccu_desc a83t_ccu_desc = {
|
||||
.gates = a83t_gates,
|
||||
.resets = a83t_resets,
|
||||
};
|
||||
|
||||
static int a83t_clk_bind(struct udevice *dev)
|
||||
{
|
||||
return sunxi_reset_bind(dev, ARRAY_SIZE(a83t_resets));
|
||||
}
|
||||
|
||||
static const struct udevice_id a83t_clk_ids[] = {
|
||||
{ .compatible = "allwinner,sun8i-a83t-ccu",
|
||||
.data = (ulong)&a83t_ccu_desc },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(clk_sun8i_a83t) = {
|
||||
.name = "sun8i_a83t_ccu",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = a83t_clk_ids,
|
||||
.priv_auto = sizeof(struct ccu_priv),
|
||||
.ops = &sunxi_clk_ops,
|
||||
.probe = sunxi_clk_probe,
|
||||
.bind = a83t_clk_bind,
|
||||
.num_gates = ARRAY_SIZE(a83t_gates),
|
||||
.num_resets = ARRAY_SIZE(a83t_resets),
|
||||
};
|
||||
|
82
drivers/clk/sunxi/clk_d1.c
Normal file
82
drivers/clk/sunxi/clk_d1.c
Normal file
@ -0,0 +1,82 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
/*
|
||||
* Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <clk-uclass.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <clk/sunxi.h>
|
||||
#include <dt-bindings/clock/sun20i-d1-ccu.h>
|
||||
#include <dt-bindings/reset/sun20i-d1-ccu.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
static struct ccu_clk_gate d1_gates[] = {
|
||||
[CLK_BUS_MMC0] = GATE(0x84c, BIT(0)),
|
||||
[CLK_BUS_MMC1] = GATE(0x84c, BIT(1)),
|
||||
[CLK_BUS_MMC2] = GATE(0x84c, BIT(2)),
|
||||
[CLK_BUS_UART0] = GATE(0x90c, BIT(0)),
|
||||
[CLK_BUS_UART1] = GATE(0x90c, BIT(1)),
|
||||
[CLK_BUS_UART2] = GATE(0x90c, BIT(2)),
|
||||
[CLK_BUS_UART3] = GATE(0x90c, BIT(3)),
|
||||
[CLK_BUS_UART4] = GATE(0x90c, BIT(4)),
|
||||
[CLK_BUS_UART5] = GATE(0x90c, BIT(5)),
|
||||
[CLK_BUS_I2C0] = GATE(0x91c, BIT(0)),
|
||||
[CLK_BUS_I2C1] = GATE(0x91c, BIT(1)),
|
||||
[CLK_BUS_I2C2] = GATE(0x91c, BIT(2)),
|
||||
[CLK_BUS_I2C3] = GATE(0x91c, BIT(3)),
|
||||
[CLK_SPI0] = GATE(0x940, BIT(31)),
|
||||
[CLK_SPI1] = GATE(0x944, BIT(31)),
|
||||
[CLK_BUS_SPI0] = GATE(0x96c, BIT(0)),
|
||||
[CLK_BUS_SPI1] = GATE(0x96c, BIT(1)),
|
||||
|
||||
[CLK_BUS_EMAC] = GATE(0x97c, BIT(0)),
|
||||
|
||||
[CLK_USB_OHCI0] = GATE(0xa70, BIT(31)),
|
||||
[CLK_USB_OHCI1] = GATE(0xa74, BIT(31)),
|
||||
[CLK_BUS_OHCI0] = GATE(0xa8c, BIT(0)),
|
||||
[CLK_BUS_OHCI1] = GATE(0xa8c, BIT(1)),
|
||||
[CLK_BUS_EHCI0] = GATE(0xa8c, BIT(4)),
|
||||
[CLK_BUS_EHCI1] = GATE(0xa8c, BIT(5)),
|
||||
[CLK_BUS_OTG] = GATE(0xa8c, BIT(8)),
|
||||
[CLK_BUS_LRADC] = GATE(0xa9c, BIT(0)),
|
||||
|
||||
[CLK_RISCV] = GATE(0xd04, BIT(31)),
|
||||
};
|
||||
|
||||
static struct ccu_reset d1_resets[] = {
|
||||
[RST_BUS_MMC0] = RESET(0x84c, BIT(16)),
|
||||
[RST_BUS_MMC1] = RESET(0x84c, BIT(17)),
|
||||
[RST_BUS_MMC2] = RESET(0x84c, BIT(18)),
|
||||
[RST_BUS_UART0] = RESET(0x90c, BIT(16)),
|
||||
[RST_BUS_UART1] = RESET(0x90c, BIT(17)),
|
||||
[RST_BUS_UART2] = RESET(0x90c, BIT(18)),
|
||||
[RST_BUS_UART3] = RESET(0x90c, BIT(19)),
|
||||
[RST_BUS_UART4] = RESET(0x90c, BIT(20)),
|
||||
[RST_BUS_UART5] = RESET(0x90c, BIT(21)),
|
||||
[RST_BUS_I2C0] = RESET(0x91c, BIT(16)),
|
||||
[RST_BUS_I2C1] = RESET(0x91c, BIT(17)),
|
||||
[RST_BUS_I2C2] = RESET(0x91c, BIT(18)),
|
||||
[RST_BUS_I2C3] = RESET(0x91c, BIT(19)),
|
||||
[RST_BUS_SPI0] = RESET(0x96c, BIT(16)),
|
||||
[RST_BUS_SPI1] = RESET(0x96c, BIT(17)),
|
||||
|
||||
[RST_BUS_EMAC] = RESET(0x97c, BIT(16)),
|
||||
|
||||
[RST_USB_PHY0] = RESET(0xa70, BIT(30)),
|
||||
[RST_USB_PHY1] = RESET(0xa74, BIT(30)),
|
||||
[RST_BUS_OHCI0] = RESET(0xa8c, BIT(16)),
|
||||
[RST_BUS_OHCI1] = RESET(0xa8c, BIT(17)),
|
||||
[RST_BUS_EHCI0] = RESET(0xa8c, BIT(20)),
|
||||
[RST_BUS_EHCI1] = RESET(0xa8c, BIT(21)),
|
||||
[RST_BUS_OTG] = RESET(0xa8c, BIT(24)),
|
||||
[RST_BUS_LRADC] = RESET(0xa9c, BIT(16)),
|
||||
};
|
||||
|
||||
const struct ccu_desc d1_ccu_desc = {
|
||||
.gates = d1_gates,
|
||||
.resets = d1_resets,
|
||||
.num_gates = ARRAY_SIZE(d1_gates),
|
||||
.num_resets = ARRAY_SIZE(d1_resets),
|
||||
};
|
@ -93,30 +93,9 @@ static struct ccu_reset h3_resets[] = {
|
||||
[RST_BUS_UART3] = RESET(0x2d8, BIT(19)),
|
||||
};
|
||||
|
||||
static const struct ccu_desc h3_ccu_desc = {
|
||||
const struct ccu_desc h3_ccu_desc = {
|
||||
.gates = h3_gates,
|
||||
.resets = h3_resets,
|
||||
};
|
||||
|
||||
static int h3_clk_bind(struct udevice *dev)
|
||||
{
|
||||
return sunxi_reset_bind(dev, ARRAY_SIZE(h3_resets));
|
||||
}
|
||||
|
||||
static const struct udevice_id h3_ccu_ids[] = {
|
||||
{ .compatible = "allwinner,sun8i-h3-ccu",
|
||||
.data = (ulong)&h3_ccu_desc },
|
||||
{ .compatible = "allwinner,sun50i-h5-ccu",
|
||||
.data = (ulong)&h3_ccu_desc },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(clk_sun8i_h3) = {
|
||||
.name = "sun8i_h3_ccu",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = h3_ccu_ids,
|
||||
.priv_auto = sizeof(struct ccu_priv),
|
||||
.ops = &sunxi_clk_ops,
|
||||
.probe = sunxi_clk_probe,
|
||||
.bind = h3_clk_bind,
|
||||
.num_gates = ARRAY_SIZE(h3_gates),
|
||||
.num_resets = ARRAY_SIZE(h3_resets),
|
||||
};
|
||||
|
@ -97,28 +97,9 @@ static struct ccu_reset h6_resets[] = {
|
||||
[RST_BUS_OTG] = RESET(0xa8c, BIT(24)),
|
||||
};
|
||||
|
||||
static const struct ccu_desc h6_ccu_desc = {
|
||||
const struct ccu_desc h6_ccu_desc = {
|
||||
.gates = h6_gates,
|
||||
.resets = h6_resets,
|
||||
};
|
||||
|
||||
static int h6_clk_bind(struct udevice *dev)
|
||||
{
|
||||
return sunxi_reset_bind(dev, ARRAY_SIZE(h6_resets));
|
||||
}
|
||||
|
||||
static const struct udevice_id h6_ccu_ids[] = {
|
||||
{ .compatible = "allwinner,sun50i-h6-ccu",
|
||||
.data = (ulong)&h6_ccu_desc },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(clk_sun50i_h6) = {
|
||||
.name = "sun50i_h6_ccu",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = h6_ccu_ids,
|
||||
.priv_auto = sizeof(struct ccu_priv),
|
||||
.ops = &sunxi_clk_ops,
|
||||
.probe = sunxi_clk_probe,
|
||||
.bind = h6_clk_bind,
|
||||
.num_gates = ARRAY_SIZE(h6_gates),
|
||||
.num_resets = ARRAY_SIZE(h6_resets),
|
||||
};
|
||||
|
@ -115,28 +115,9 @@ static struct ccu_reset h616_resets[] = {
|
||||
[RST_BUS_OTG] = RESET(0xa8c, BIT(24)),
|
||||
};
|
||||
|
||||
static const struct ccu_desc h616_ccu_desc = {
|
||||
const struct ccu_desc h616_ccu_desc = {
|
||||
.gates = h616_gates,
|
||||
.resets = h616_resets,
|
||||
};
|
||||
|
||||
static int h616_clk_bind(struct udevice *dev)
|
||||
{
|
||||
return sunxi_reset_bind(dev, ARRAY_SIZE(h616_resets));
|
||||
}
|
||||
|
||||
static const struct udevice_id h616_ccu_ids[] = {
|
||||
{ .compatible = "allwinner,sun50i-h616-ccu",
|
||||
.data = (ulong)&h616_ccu_desc },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(clk_sun50i_h616) = {
|
||||
.name = "sun50i_h616_ccu",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = h616_ccu_ids,
|
||||
.priv_auto = sizeof(struct ccu_priv),
|
||||
.ops = &sunxi_clk_ops,
|
||||
.probe = sunxi_clk_probe,
|
||||
.bind = h616_clk_bind,
|
||||
.num_gates = ARRAY_SIZE(h616_gates),
|
||||
.num_resets = ARRAY_SIZE(h616_resets),
|
||||
};
|
||||
|
@ -34,30 +34,9 @@ static struct ccu_reset h6_r_resets[] = {
|
||||
[RST_R_APB1_W1] = RESET(0x1ec, BIT(16)),
|
||||
};
|
||||
|
||||
static const struct ccu_desc h6_r_ccu_desc = {
|
||||
const struct ccu_desc h6_r_ccu_desc = {
|
||||
.gates = h6_r_gates,
|
||||
.resets = h6_r_resets,
|
||||
};
|
||||
|
||||
static int h6_r_clk_bind(struct udevice *dev)
|
||||
{
|
||||
return sunxi_reset_bind(dev, ARRAY_SIZE(h6_r_resets));
|
||||
}
|
||||
|
||||
static const struct udevice_id h6_r_clk_ids[] = {
|
||||
{ .compatible = "allwinner,sun50i-h6-r-ccu",
|
||||
.data = (ulong)&h6_r_ccu_desc },
|
||||
{ .compatible = "allwinner,sun50i-h616-r-ccu",
|
||||
.data = (ulong)&h6_r_ccu_desc },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(clk_sun50i_h6_r) = {
|
||||
.name = "sun50i_h6_r_ccu",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = h6_r_clk_ids,
|
||||
.priv_auto = sizeof(struct ccu_priv),
|
||||
.ops = &sunxi_clk_ops,
|
||||
.probe = sunxi_clk_probe,
|
||||
.bind = h6_r_clk_bind,
|
||||
.num_gates = ARRAY_SIZE(h6_r_gates),
|
||||
.num_resets = ARRAY_SIZE(h6_r_resets),
|
||||
};
|
||||
|
@ -102,28 +102,9 @@ static struct ccu_reset r40_resets[] = {
|
||||
[RST_BUS_UART7] = RESET(0x2d8, BIT(23)),
|
||||
};
|
||||
|
||||
static const struct ccu_desc r40_ccu_desc = {
|
||||
const struct ccu_desc r40_ccu_desc = {
|
||||
.gates = r40_gates,
|
||||
.resets = r40_resets,
|
||||
};
|
||||
|
||||
static int r40_clk_bind(struct udevice *dev)
|
||||
{
|
||||
return sunxi_reset_bind(dev, ARRAY_SIZE(r40_resets));
|
||||
}
|
||||
|
||||
static const struct udevice_id r40_clk_ids[] = {
|
||||
{ .compatible = "allwinner,sun8i-r40-ccu",
|
||||
.data = (ulong)&r40_ccu_desc },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(clk_sun8i_r40) = {
|
||||
.name = "sun8i_r40_ccu",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = r40_clk_ids,
|
||||
.priv_auto = sizeof(struct ccu_priv),
|
||||
.ops = &sunxi_clk_ops,
|
||||
.probe = sunxi_clk_probe,
|
||||
.bind = r40_clk_bind,
|
||||
.num_gates = ARRAY_SIZE(r40_gates),
|
||||
.num_resets = ARRAY_SIZE(r40_resets),
|
||||
};
|
||||
|
@ -24,6 +24,8 @@ static const struct udevice_id sun6i_rtc_ids[] = {
|
||||
{ .compatible = "allwinner,sun8i-v3-rtc" },
|
||||
{ .compatible = "allwinner,sun50i-h5-rtc" },
|
||||
{ .compatible = "allwinner,sun50i-h6-rtc" },
|
||||
{ .compatible = "allwinner,sun50i-h616-rtc" },
|
||||
{ .compatible = "allwinner,sun50i-r329-rtc" },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -12,39 +12,43 @@
|
||||
#include <reset.h>
|
||||
#include <asm/io.h>
|
||||
#include <clk/sunxi.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/log2.h>
|
||||
|
||||
static const struct ccu_clk_gate *priv_to_gate(struct ccu_priv *priv,
|
||||
extern U_BOOT_DRIVER(sunxi_reset);
|
||||
|
||||
static const struct ccu_clk_gate *plat_to_gate(struct ccu_plat *plat,
|
||||
unsigned long id)
|
||||
{
|
||||
return &priv->desc->gates[id];
|
||||
if (id >= plat->desc->num_gates)
|
||||
return NULL;
|
||||
|
||||
return &plat->desc->gates[id];
|
||||
}
|
||||
|
||||
static int sunxi_set_gate(struct clk *clk, bool on)
|
||||
{
|
||||
struct ccu_priv *priv = dev_get_priv(clk->dev);
|
||||
const struct ccu_clk_gate *gate = priv_to_gate(priv, clk->id);
|
||||
struct ccu_plat *plat = dev_get_plat(clk->dev);
|
||||
const struct ccu_clk_gate *gate = plat_to_gate(plat, clk->id);
|
||||
u32 reg;
|
||||
|
||||
if ((gate->flags & CCU_CLK_F_DUMMY_GATE))
|
||||
return 0;
|
||||
|
||||
if (!(gate->flags & CCU_CLK_F_IS_VALID)) {
|
||||
printf("%s: (CLK#%ld) unhandled\n", __func__, clk->id);
|
||||
if (!gate || !(gate->flags & CCU_CLK_F_IS_VALID)) {
|
||||
if (!gate || !(gate->flags & CCU_CLK_F_DUMMY_GATE))
|
||||
printf("%s: (CLK#%ld) unhandled\n", __func__, clk->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
debug("%s: (CLK#%ld) off#0x%x, BIT(%d)\n", __func__,
|
||||
clk->id, gate->off, ilog2(gate->bit));
|
||||
|
||||
reg = readl(priv->base + gate->off);
|
||||
reg = readl(plat->base + gate->off);
|
||||
if (on)
|
||||
reg |= gate->bit;
|
||||
else
|
||||
reg &= ~gate->bit;
|
||||
|
||||
writel(reg, priv->base + gate->off);
|
||||
writel(reg, plat->base + gate->off);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -64,21 +68,19 @@ struct clk_ops sunxi_clk_ops = {
|
||||
.disable = sunxi_clk_disable,
|
||||
};
|
||||
|
||||
int sunxi_clk_probe(struct udevice *dev)
|
||||
static int sunxi_clk_bind(struct udevice *dev)
|
||||
{
|
||||
/* Reuse the platform data for the reset driver. */
|
||||
return device_bind(dev, DM_DRIVER_REF(sunxi_reset), "reset",
|
||||
dev_get_plat(dev), dev_ofnode(dev), NULL);
|
||||
}
|
||||
|
||||
static int sunxi_clk_probe(struct udevice *dev)
|
||||
{
|
||||
struct ccu_priv *priv = dev_get_priv(dev);
|
||||
struct clk_bulk clk_bulk;
|
||||
struct reset_ctl_bulk rst_bulk;
|
||||
int ret;
|
||||
|
||||
priv->base = dev_read_addr_ptr(dev);
|
||||
if (!priv->base)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->desc = (const struct ccu_desc *)dev_get_driver_data(dev);
|
||||
if (!priv->desc)
|
||||
return -EINVAL;
|
||||
|
||||
ret = clk_get_bulk(dev, &clk_bulk);
|
||||
if (!ret)
|
||||
clk_enable_bulk(&clk_bulk);
|
||||
@ -89,3 +91,138 @@ int sunxi_clk_probe(struct udevice *dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sunxi_clk_of_to_plat(struct udevice *dev)
|
||||
{
|
||||
struct ccu_plat *plat = dev_get_plat(dev);
|
||||
|
||||
plat->base = dev_read_addr_ptr(dev);
|
||||
if (!plat->base)
|
||||
return -ENOMEM;
|
||||
|
||||
plat->desc = (const struct ccu_desc *)dev_get_driver_data(dev);
|
||||
if (!plat->desc)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern const struct ccu_desc a10_ccu_desc;
|
||||
extern const struct ccu_desc a10s_ccu_desc;
|
||||
extern const struct ccu_desc a23_ccu_desc;
|
||||
extern const struct ccu_desc a31_ccu_desc;
|
||||
extern const struct ccu_desc a31_r_ccu_desc;
|
||||
extern const struct ccu_desc a64_ccu_desc;
|
||||
extern const struct ccu_desc a80_ccu_desc;
|
||||
extern const struct ccu_desc a80_mmc_clk_desc;
|
||||
extern const struct ccu_desc a83t_ccu_desc;
|
||||
extern const struct ccu_desc d1_ccu_desc;
|
||||
extern const struct ccu_desc h3_ccu_desc;
|
||||
extern const struct ccu_desc h6_ccu_desc;
|
||||
extern const struct ccu_desc h616_ccu_desc;
|
||||
extern const struct ccu_desc h6_r_ccu_desc;
|
||||
extern const struct ccu_desc r40_ccu_desc;
|
||||
extern const struct ccu_desc v3s_ccu_desc;
|
||||
|
||||
static const struct udevice_id sunxi_clk_ids[] = {
|
||||
#ifdef CONFIG_CLK_SUN4I_A10
|
||||
{ .compatible = "allwinner,sun4i-a10-ccu",
|
||||
.data = (ulong)&a10_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN5I_A10S
|
||||
{ .compatible = "allwinner,sun5i-a10s-ccu",
|
||||
.data = (ulong)&a10s_ccu_desc },
|
||||
{ .compatible = "allwinner,sun5i-a13-ccu",
|
||||
.data = (ulong)&a10s_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN6I_A31
|
||||
{ .compatible = "allwinner,sun6i-a31-ccu",
|
||||
.data = (ulong)&a31_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN4I_A10
|
||||
{ .compatible = "allwinner,sun7i-a20-ccu",
|
||||
.data = (ulong)&a10_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN8I_A23
|
||||
{ .compatible = "allwinner,sun8i-a23-ccu",
|
||||
.data = (ulong)&a23_ccu_desc },
|
||||
{ .compatible = "allwinner,sun8i-a33-ccu",
|
||||
.data = (ulong)&a23_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN8I_A83T
|
||||
{ .compatible = "allwinner,sun8i-a83t-ccu",
|
||||
.data = (ulong)&a83t_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN6I_A31_R
|
||||
{ .compatible = "allwinner,sun8i-a83t-r-ccu",
|
||||
.data = (ulong)&a31_r_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN8I_H3
|
||||
{ .compatible = "allwinner,sun8i-h3-ccu",
|
||||
.data = (ulong)&h3_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN6I_A31_R
|
||||
{ .compatible = "allwinner,sun8i-h3-r-ccu",
|
||||
.data = (ulong)&a31_r_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN8I_R40
|
||||
{ .compatible = "allwinner,sun8i-r40-ccu",
|
||||
.data = (ulong)&r40_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN8I_V3S
|
||||
{ .compatible = "allwinner,sun8i-v3-ccu",
|
||||
.data = (ulong)&v3s_ccu_desc },
|
||||
{ .compatible = "allwinner,sun8i-v3s-ccu",
|
||||
.data = (ulong)&v3s_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN9I_A80
|
||||
{ .compatible = "allwinner,sun9i-a80-ccu",
|
||||
.data = (ulong)&a80_ccu_desc },
|
||||
{ .compatible = "allwinner,sun9i-a80-mmc-config-clk",
|
||||
.data = (ulong)&a80_mmc_clk_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN20I_D1
|
||||
{ .compatible = "allwinner,sun20i-d1-ccu",
|
||||
.data = (ulong)&d1_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN50I_A64
|
||||
{ .compatible = "allwinner,sun50i-a64-ccu",
|
||||
.data = (ulong)&a64_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN6I_A31_R
|
||||
{ .compatible = "allwinner,sun50i-a64-r-ccu",
|
||||
.data = (ulong)&a31_r_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN8I_H3
|
||||
{ .compatible = "allwinner,sun50i-h5-ccu",
|
||||
.data = (ulong)&h3_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN50I_H6
|
||||
{ .compatible = "allwinner,sun50i-h6-ccu",
|
||||
.data = (ulong)&h6_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN50I_H6_R
|
||||
{ .compatible = "allwinner,sun50i-h6-r-ccu",
|
||||
.data = (ulong)&h6_r_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN50I_H616
|
||||
{ .compatible = "allwinner,sun50i-h616-ccu",
|
||||
.data = (ulong)&h616_ccu_desc },
|
||||
#endif
|
||||
#ifdef CONFIG_CLK_SUN50I_H6_R
|
||||
{ .compatible = "allwinner,sun50i-h616-r-ccu",
|
||||
.data = (ulong)&h6_r_ccu_desc },
|
||||
#endif
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sunxi_clk) = {
|
||||
.name = "sunxi_clk",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = sunxi_clk_ids,
|
||||
.bind = sunxi_clk_bind,
|
||||
.probe = sunxi_clk_probe,
|
||||
.of_to_plat = sunxi_clk_of_to_plat,
|
||||
.plat_auto = sizeof(struct ccu_plat),
|
||||
.ops = &sunxi_clk_ops,
|
||||
};
|
||||
|
@ -49,30 +49,9 @@ static struct ccu_reset v3s_resets[] = {
|
||||
[RST_BUS_UART2] = RESET(0x2d8, BIT(18)),
|
||||
};
|
||||
|
||||
static const struct ccu_desc v3s_ccu_desc = {
|
||||
const struct ccu_desc v3s_ccu_desc = {
|
||||
.gates = v3s_gates,
|
||||
.resets = v3s_resets,
|
||||
};
|
||||
|
||||
static int v3s_clk_bind(struct udevice *dev)
|
||||
{
|
||||
return sunxi_reset_bind(dev, ARRAY_SIZE(v3s_resets));
|
||||
}
|
||||
|
||||
static const struct udevice_id v3s_clk_ids[] = {
|
||||
{ .compatible = "allwinner,sun8i-v3s-ccu",
|
||||
.data = (ulong)&v3s_ccu_desc },
|
||||
{ .compatible = "allwinner,sun8i-v3-ccu",
|
||||
.data = (ulong)&v3s_ccu_desc },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(clk_sun8i_v3s) = {
|
||||
.name = "sun8i_v3s_ccu",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = v3s_clk_ids,
|
||||
.priv_auto = sizeof(struct ccu_priv),
|
||||
.ops = &sunxi_clk_ops,
|
||||
.probe = sunxi_clk_probe,
|
||||
.bind = v3s_clk_bind,
|
||||
.num_gates = ARRAY_SIZE(v3s_gates),
|
||||
.num_resets = ARRAY_SIZE(v3s_resets),
|
||||
};
|
||||
|
@ -12,30 +12,22 @@
|
||||
#include <reset-uclass.h>
|
||||
#include <asm/io.h>
|
||||
#include <clk/sunxi.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/lists.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/log2.h>
|
||||
|
||||
struct sunxi_reset_priv {
|
||||
void *base;
|
||||
ulong count;
|
||||
const struct ccu_desc *desc;
|
||||
};
|
||||
|
||||
static const struct ccu_reset *priv_to_reset(struct sunxi_reset_priv *priv,
|
||||
static const struct ccu_reset *plat_to_reset(struct ccu_plat *plat,
|
||||
unsigned long id)
|
||||
{
|
||||
return &priv->desc->resets[id];
|
||||
return &plat->desc->resets[id];
|
||||
}
|
||||
|
||||
static int sunxi_reset_request(struct reset_ctl *reset_ctl)
|
||||
{
|
||||
struct sunxi_reset_priv *priv = dev_get_priv(reset_ctl->dev);
|
||||
struct ccu_plat *plat = dev_get_plat(reset_ctl->dev);
|
||||
|
||||
debug("%s: (RST#%ld)\n", __func__, reset_ctl->id);
|
||||
|
||||
if (reset_ctl->id >= priv->count)
|
||||
if (reset_ctl->id >= plat->desc->num_resets)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@ -43,8 +35,8 @@ static int sunxi_reset_request(struct reset_ctl *reset_ctl)
|
||||
|
||||
static int sunxi_set_reset(struct reset_ctl *reset_ctl, bool on)
|
||||
{
|
||||
struct sunxi_reset_priv *priv = dev_get_priv(reset_ctl->dev);
|
||||
const struct ccu_reset *reset = priv_to_reset(priv, reset_ctl->id);
|
||||
struct ccu_plat *plat = dev_get_plat(reset_ctl->dev);
|
||||
const struct ccu_reset *reset = plat_to_reset(plat, reset_ctl->id);
|
||||
u32 reg;
|
||||
|
||||
if (!(reset->flags & CCU_RST_F_IS_VALID)) {
|
||||
@ -55,13 +47,13 @@ static int sunxi_set_reset(struct reset_ctl *reset_ctl, bool on)
|
||||
debug("%s: (RST#%ld) off#0x%x, BIT(%d)\n", __func__,
|
||||
reset_ctl->id, reset->off, ilog2(reset->bit));
|
||||
|
||||
reg = readl(priv->base + reset->off);
|
||||
reg = readl(plat->base + reset->off);
|
||||
if (on)
|
||||
reg |= reset->bit;
|
||||
else
|
||||
reg &= ~reset->bit;
|
||||
|
||||
writel(reg, priv->base + reset->off);
|
||||
writel(reg, plat->base + reset->off);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -82,39 +74,8 @@ struct reset_ops sunxi_reset_ops = {
|
||||
.rst_deassert = sunxi_reset_deassert,
|
||||
};
|
||||
|
||||
static int sunxi_reset_probe(struct udevice *dev)
|
||||
{
|
||||
struct sunxi_reset_priv *priv = dev_get_priv(dev);
|
||||
|
||||
priv->base = dev_read_addr_ptr(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sunxi_reset_bind(struct udevice *dev, ulong count)
|
||||
{
|
||||
struct udevice *rst_dev;
|
||||
struct sunxi_reset_priv *priv;
|
||||
int ret;
|
||||
|
||||
ret = device_bind_driver_to_node(dev, "sunxi_reset", "reset",
|
||||
dev_ofnode(dev), &rst_dev);
|
||||
if (ret) {
|
||||
debug("failed to bind sunxi_reset driver (ret=%d)\n", ret);
|
||||
return ret;
|
||||
}
|
||||
priv = malloc(sizeof(struct sunxi_reset_priv));
|
||||
priv->count = count;
|
||||
priv->desc = (const struct ccu_desc *)dev_get_driver_data(dev);
|
||||
dev_set_priv(rst_dev, priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_DRIVER(sunxi_reset) = {
|
||||
.name = "sunxi_reset",
|
||||
.id = UCLASS_RESET,
|
||||
.ops = &sunxi_reset_ops,
|
||||
.probe = sunxi_reset_probe,
|
||||
.priv_auto = sizeof(struct sunxi_reset_priv),
|
||||
};
|
||||
|
@ -70,34 +70,22 @@ struct ccu_reset {
|
||||
struct ccu_desc {
|
||||
const struct ccu_clk_gate *gates;
|
||||
const struct ccu_reset *resets;
|
||||
u8 num_gates;
|
||||
u8 num_resets;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ccu_priv - sunxi clock control unit
|
||||
* struct ccu_plat - sunxi clock control unit platform data
|
||||
*
|
||||
* @base: base address
|
||||
* @desc: ccu descriptor
|
||||
*/
|
||||
struct ccu_priv {
|
||||
struct ccu_plat {
|
||||
void *base;
|
||||
const struct ccu_desc *desc;
|
||||
};
|
||||
|
||||
/**
|
||||
* sunxi_clk_probe - common sunxi clock probe
|
||||
* @dev: clock device
|
||||
*/
|
||||
int sunxi_clk_probe(struct udevice *dev);
|
||||
|
||||
extern struct clk_ops sunxi_clk_ops;
|
||||
|
||||
/**
|
||||
* sunxi_reset_bind() - reset binding
|
||||
*
|
||||
* @dev: reset device
|
||||
* @count: reset count
|
||||
* Return: 0 success, or error value
|
||||
*/
|
||||
int sunxi_reset_bind(struct udevice *dev, ulong count);
|
||||
extern struct reset_ops sunxi_reset_ops;
|
||||
|
||||
#endif /* _CLK_SUNXI_H */
|
||||
|
156
include/dt-bindings/clock/sun20i-d1-ccu.h
Normal file
156
include/dt-bindings/clock/sun20i-d1-ccu.h
Normal file
@ -0,0 +1,156 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
|
||||
/*
|
||||
* Copyright (C) 2020 huangzhenwei@allwinnertech.com
|
||||
* Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_SUN20I_D1_CCU_H_
|
||||
#define _DT_BINDINGS_CLK_SUN20I_D1_CCU_H_
|
||||
|
||||
#define CLK_PLL_CPUX 0
|
||||
#define CLK_PLL_DDR0 1
|
||||
#define CLK_PLL_PERIPH0_4X 2
|
||||
#define CLK_PLL_PERIPH0_2X 3
|
||||
#define CLK_PLL_PERIPH0_800M 4
|
||||
#define CLK_PLL_PERIPH0 5
|
||||
#define CLK_PLL_PERIPH0_DIV3 6
|
||||
#define CLK_PLL_VIDEO0_4X 7
|
||||
#define CLK_PLL_VIDEO0_2X 8
|
||||
#define CLK_PLL_VIDEO0 9
|
||||
#define CLK_PLL_VIDEO1_4X 10
|
||||
#define CLK_PLL_VIDEO1_2X 11
|
||||
#define CLK_PLL_VIDEO1 12
|
||||
#define CLK_PLL_VE 13
|
||||
#define CLK_PLL_AUDIO0_4X 14
|
||||
#define CLK_PLL_AUDIO0_2X 15
|
||||
#define CLK_PLL_AUDIO0 16
|
||||
#define CLK_PLL_AUDIO1 17
|
||||
#define CLK_PLL_AUDIO1_DIV2 18
|
||||
#define CLK_PLL_AUDIO1_DIV5 19
|
||||
#define CLK_CPUX 20
|
||||
#define CLK_CPUX_AXI 21
|
||||
#define CLK_CPUX_APB 22
|
||||
#define CLK_PSI_AHB 23
|
||||
#define CLK_APB0 24
|
||||
#define CLK_APB1 25
|
||||
#define CLK_MBUS 26
|
||||
#define CLK_DE 27
|
||||
#define CLK_BUS_DE 28
|
||||
#define CLK_DI 29
|
||||
#define CLK_BUS_DI 30
|
||||
#define CLK_G2D 31
|
||||
#define CLK_BUS_G2D 32
|
||||
#define CLK_CE 33
|
||||
#define CLK_BUS_CE 34
|
||||
#define CLK_VE 35
|
||||
#define CLK_BUS_VE 36
|
||||
#define CLK_BUS_DMA 37
|
||||
#define CLK_BUS_MSGBOX0 38
|
||||
#define CLK_BUS_MSGBOX1 39
|
||||
#define CLK_BUS_MSGBOX2 40
|
||||
#define CLK_BUS_SPINLOCK 41
|
||||
#define CLK_BUS_HSTIMER 42
|
||||
#define CLK_AVS 43
|
||||
#define CLK_BUS_DBG 44
|
||||
#define CLK_BUS_PWM 45
|
||||
#define CLK_BUS_IOMMU 46
|
||||
#define CLK_DRAM 47
|
||||
#define CLK_MBUS_DMA 48
|
||||
#define CLK_MBUS_VE 49
|
||||
#define CLK_MBUS_CE 50
|
||||
#define CLK_MBUS_TVIN 51
|
||||
#define CLK_MBUS_CSI 52
|
||||
#define CLK_MBUS_G2D 53
|
||||
#define CLK_MBUS_RISCV 54
|
||||
#define CLK_BUS_DRAM 55
|
||||
#define CLK_MMC0 56
|
||||
#define CLK_MMC1 57
|
||||
#define CLK_MMC2 58
|
||||
#define CLK_BUS_MMC0 59
|
||||
#define CLK_BUS_MMC1 60
|
||||
#define CLK_BUS_MMC2 61
|
||||
#define CLK_BUS_UART0 62
|
||||
#define CLK_BUS_UART1 63
|
||||
#define CLK_BUS_UART2 64
|
||||
#define CLK_BUS_UART3 65
|
||||
#define CLK_BUS_UART4 66
|
||||
#define CLK_BUS_UART5 67
|
||||
#define CLK_BUS_I2C0 68
|
||||
#define CLK_BUS_I2C1 69
|
||||
#define CLK_BUS_I2C2 70
|
||||
#define CLK_BUS_I2C3 71
|
||||
#define CLK_SPI0 72
|
||||
#define CLK_SPI1 73
|
||||
#define CLK_BUS_SPI0 74
|
||||
#define CLK_BUS_SPI1 75
|
||||
#define CLK_EMAC_25M 76
|
||||
#define CLK_BUS_EMAC 77
|
||||
#define CLK_IR_TX 78
|
||||
#define CLK_BUS_IR_TX 79
|
||||
#define CLK_BUS_GPADC 80
|
||||
#define CLK_BUS_THS 81
|
||||
#define CLK_I2S0 82
|
||||
#define CLK_I2S1 83
|
||||
#define CLK_I2S2 84
|
||||
#define CLK_I2S2_ASRC 85
|
||||
#define CLK_BUS_I2S0 86
|
||||
#define CLK_BUS_I2S1 87
|
||||
#define CLK_BUS_I2S2 88
|
||||
#define CLK_SPDIF_TX 89
|
||||
#define CLK_SPDIF_RX 90
|
||||
#define CLK_BUS_SPDIF 91
|
||||
#define CLK_DMIC 92
|
||||
#define CLK_BUS_DMIC 93
|
||||
#define CLK_AUDIO_DAC 94
|
||||
#define CLK_AUDIO_ADC 95
|
||||
#define CLK_BUS_AUDIO 96
|
||||
#define CLK_USB_OHCI0 97
|
||||
#define CLK_USB_OHCI1 98
|
||||
#define CLK_BUS_OHCI0 99
|
||||
#define CLK_BUS_OHCI1 100
|
||||
#define CLK_BUS_EHCI0 101
|
||||
#define CLK_BUS_EHCI1 102
|
||||
#define CLK_BUS_OTG 103
|
||||
#define CLK_BUS_LRADC 104
|
||||
#define CLK_BUS_DPSS_TOP 105
|
||||
#define CLK_HDMI_24M 106
|
||||
#define CLK_HDMI_CEC_32K 107
|
||||
#define CLK_HDMI_CEC 108
|
||||
#define CLK_BUS_HDMI 109
|
||||
#define CLK_MIPI_DSI 110
|
||||
#define CLK_BUS_MIPI_DSI 111
|
||||
#define CLK_TCON_LCD0 112
|
||||
#define CLK_BUS_TCON_LCD0 113
|
||||
#define CLK_TCON_TV 114
|
||||
#define CLK_BUS_TCON_TV 115
|
||||
#define CLK_TVE 116
|
||||
#define CLK_BUS_TVE_TOP 117
|
||||
#define CLK_BUS_TVE 118
|
||||
#define CLK_TVD 119
|
||||
#define CLK_BUS_TVD_TOP 120
|
||||
#define CLK_BUS_TVD 121
|
||||
#define CLK_LEDC 122
|
||||
#define CLK_BUS_LEDC 123
|
||||
#define CLK_CSI_TOP 124
|
||||
#define CLK_CSI_MCLK 125
|
||||
#define CLK_BUS_CSI 126
|
||||
#define CLK_TPADC 127
|
||||
#define CLK_BUS_TPADC 128
|
||||
#define CLK_BUS_TZMA 129
|
||||
#define CLK_DSP 130
|
||||
#define CLK_BUS_DSP_CFG 131
|
||||
#define CLK_RISCV 132
|
||||
#define CLK_RISCV_AXI 133
|
||||
#define CLK_BUS_RISCV_CFG 134
|
||||
#define CLK_FANOUT_24M 135
|
||||
#define CLK_FANOUT_12M 136
|
||||
#define CLK_FANOUT_16M 137
|
||||
#define CLK_FANOUT_25M 138
|
||||
#define CLK_FANOUT_32K 139
|
||||
#define CLK_FANOUT_27M 140
|
||||
#define CLK_FANOUT_PCLK 141
|
||||
#define CLK_FANOUT0 142
|
||||
#define CLK_FANOUT1 143
|
||||
#define CLK_FANOUT2 144
|
||||
|
||||
#endif /* _DT_BINDINGS_CLK_SUN20I_D1_CCU_H_ */
|
77
include/dt-bindings/reset/sun20i-d1-ccu.h
Normal file
77
include/dt-bindings/reset/sun20i-d1-ccu.h
Normal file
@ -0,0 +1,77 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
|
||||
/*
|
||||
* Copyright (c) 2020 huangzhenwei@allwinnertech.com
|
||||
* Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_RST_SUN20I_D1_CCU_H_
|
||||
#define _DT_BINDINGS_RST_SUN20I_D1_CCU_H_
|
||||
|
||||
#define RST_MBUS 0
|
||||
#define RST_BUS_DE 1
|
||||
#define RST_BUS_DI 2
|
||||
#define RST_BUS_G2D 3
|
||||
#define RST_BUS_CE 4
|
||||
#define RST_BUS_VE 5
|
||||
#define RST_BUS_DMA 6
|
||||
#define RST_BUS_MSGBOX0 7
|
||||
#define RST_BUS_MSGBOX1 8
|
||||
#define RST_BUS_MSGBOX2 9
|
||||
#define RST_BUS_SPINLOCK 10
|
||||
#define RST_BUS_HSTIMER 11
|
||||
#define RST_BUS_DBG 12
|
||||
#define RST_BUS_PWM 13
|
||||
#define RST_BUS_DRAM 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_UART5 23
|
||||
#define RST_BUS_I2C0 24
|
||||
#define RST_BUS_I2C1 25
|
||||
#define RST_BUS_I2C2 26
|
||||
#define RST_BUS_I2C3 27
|
||||
#define RST_BUS_SPI0 28
|
||||
#define RST_BUS_SPI1 29
|
||||
#define RST_BUS_EMAC 30
|
||||
#define RST_BUS_IR_TX 31
|
||||
#define RST_BUS_GPADC 32
|
||||
#define RST_BUS_THS 33
|
||||
#define RST_BUS_I2S0 34
|
||||
#define RST_BUS_I2S1 35
|
||||
#define RST_BUS_I2S2 36
|
||||
#define RST_BUS_SPDIF 37
|
||||
#define RST_BUS_DMIC 38
|
||||
#define RST_BUS_AUDIO 39
|
||||
#define RST_USB_PHY0 40
|
||||
#define RST_USB_PHY1 41
|
||||
#define RST_BUS_OHCI0 42
|
||||
#define RST_BUS_OHCI1 43
|
||||
#define RST_BUS_EHCI0 44
|
||||
#define RST_BUS_EHCI1 45
|
||||
#define RST_BUS_OTG 46
|
||||
#define RST_BUS_LRADC 47
|
||||
#define RST_BUS_DPSS_TOP 48
|
||||
#define RST_BUS_HDMI_SUB 49
|
||||
#define RST_BUS_HDMI_MAIN 50
|
||||
#define RST_BUS_MIPI_DSI 51
|
||||
#define RST_BUS_TCON_LCD0 52
|
||||
#define RST_BUS_TCON_TV 53
|
||||
#define RST_BUS_LVDS0 54
|
||||
#define RST_BUS_TVE 55
|
||||
#define RST_BUS_TVE_TOP 56
|
||||
#define RST_BUS_TVD 57
|
||||
#define RST_BUS_TVD_TOP 58
|
||||
#define RST_BUS_LEDC 59
|
||||
#define RST_BUS_CSI 60
|
||||
#define RST_BUS_TPADC 61
|
||||
#define RST_DSP 62
|
||||
#define RST_BUS_DSP_CFG 63
|
||||
#define RST_BUS_DSP_DBG 64
|
||||
#define RST_BUS_RISCV_CFG 65
|
||||
|
||||
#endif /* _DT_BINDINGS_RST_SUN20I_D1_CCU_H_ */
|
Loading…
x
Reference in New Issue
Block a user