clk/samsung updates for v5.16
- Initial clock driver for the Exynos850 SoC - Refactoring of the CPU clock code and conversion of Exynos5433 CPU clock driver to the platform driver - A few conversions to devm_platform_ioremap_resource() - Updates of the Kconfig help text -----BEGIN PGP SIGNATURE----- iQJLBAABCAA1FiEEujTcHEnaPOkZ6f78TVsgp4CceosFAmFtzN4XHHMubmF3cm9j a2lAc2Ftc3VuZy5jb20ACgkQTVsgp4CceosTsQ//Z3xm7iDhI8z5hTrUJb9udp/i ZWxLxlkq6QevBlVBps85yPhrbKy8UG0ml8Ejt1eVRSvJPdoDhlBJYieVQh7fjHI+ +gApO+VTkr5A9LvpEPUKmn/ybwKrvXRVkgVmjzIigKqRFkOEZU+h8NnhKbwdpK1F chRqJ3pLEtSewXjyHfi6Kto/jXXcWWnYudXgr+zkFW1tWwJn3h+RH+grH+o30u+X Qy7MIpnB12BZlFEmnd0Y2mcGnNsSTE1gWaqFds/ZhpYwcehzBoQnOnME6FNBs63S rRSIUdMH4b+o4waPXkTkj4fu2lRsqPuof6w29KRelBmr+tM5zptMXwTjBA9sn96O ic4x1eAuetiiAYTqDXIkxRirYmvU2kLfY07xh8x67FEWtkiosYV780wrCrXXPlc1 ebv8uRhFCyrrclUgE0sJTW6zJRNqCB81MbUyXfxOe7Z0Qt128Iec3Nmw8yWCqkIM zlbGJ+roTdL5GJ6UF4bSHYsY/cvSQdTtTncQ0WY6/zXl19qt3Px0Qe9vW1BEq6G9 sUq1RjeBoyqcYEXGQ/u/f6b45oAW7BadM94S7fRFXkWLBSVpW8toGvRHONEOgSQm UDmRnDCM5kfelis0OTVOsdgDQdrfIDv7fMTQrmDr22DEjhsqrFlFyudqwCfiT21W IYJupFi4nJiaI/f6ges= =uBdF -----END PGP SIGNATURE----- Merge tag 'clk-v5.16-samsung' of https://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk into clk-samsung Pull Samsung clk driver updates from Sylwester Nawrocki: - Initial clock driver for the Exynos850 SoC - Refactoring of the CPU clock code and conversion of Exynos5433 CPU clock driver to the platform driver - A few conversions to devm_platform_ioremap_resource() - Updates of the Samsung Kconfig help text * tag 'clk-v5.16-samsung' of https://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk: clk: samsung: describe drivers in Kconfig clk: samsung: exynos5433: update apollo and atlas clock probing clk: samsung: add support for CPU clocks clk: samsung: Introduce Exynos850 clock driver dt-bindings: clock: Document Exynos850 CMU bindings dt-bindings: clock: Add bindings definitions for Exynos850 CMU clk: samsung: clk-pll: Implement pll0831x PLL type clk: samsung: clk-pll: Implement pll0822x PLL type clk: samsung: s5pv210-audss: Make use of devm_platform_ioremap_resource() clk: samsung: exynos5433: Make use of devm_platform_ioremap_resource() clk: samsung: exynos4412-isp: Make use of devm_platform_ioremap_resource() clk: samsung: exynos-audss: Make use of devm_platform_ioremap_resource()
This commit is contained in:
Коммит
4e44a0ba4d
|
@ -0,0 +1,185 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/samsung,exynos850-clock.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung Exynos850 SoC clock controller
|
||||
|
||||
maintainers:
|
||||
- Sam Protsenko <semen.protsenko@linaro.org>
|
||||
- Chanwoo Choi <cw00.choi@samsung.com>
|
||||
- Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
|
||||
- Sylwester Nawrocki <s.nawrocki@samsung.com>
|
||||
- Tomasz Figa <tomasz.figa@gmail.com>
|
||||
|
||||
description: |
|
||||
Exynos850 clock controller is comprised of several CMU units, generating
|
||||
clocks for different domains. Those CMU units are modeled as separate device
|
||||
tree nodes, and might depend on each other. Root clocks in that clock tree are
|
||||
two external clocks:: OSCCLK (26 MHz) and RTCCLK (32768 Hz). Those external
|
||||
clocks must be defined as fixed-rate clocks in dts.
|
||||
|
||||
CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and
|
||||
dividers; all other leaf clocks (other CMUs) are usually derived from CMU_TOP.
|
||||
|
||||
Each clock is assigned an identifier and client nodes can use this identifier
|
||||
to specify the clock which they consume. All clocks available for usage
|
||||
in clock consumer nodes are defined as preprocessor macros in
|
||||
'dt-bindings/clock/exynos850.h' header.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- samsung,exynos850-cmu-top
|
||||
- samsung,exynos850-cmu-core
|
||||
- samsung,exynos850-cmu-dpu
|
||||
- samsung,exynos850-cmu-hsi
|
||||
- samsung,exynos850-cmu-peri
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 5
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 5
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: samsung,exynos850-cmu-top
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: External reference clock (26 MHz)
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: oscclk
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: samsung,exynos850-cmu-core
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: External reference clock (26 MHz)
|
||||
- description: CMU_CORE bus clock (from CMU_TOP)
|
||||
- description: CCI clock (from CMU_TOP)
|
||||
- description: eMMC clock (from CMU_TOP)
|
||||
- description: SSS clock (from CMU_TOP)
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: oscclk
|
||||
- const: dout_core_bus
|
||||
- const: dout_core_cci
|
||||
- const: dout_core_mmc_embd
|
||||
- const: dout_core_sss
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: samsung,exynos850-cmu-dpu
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: External reference clock (26 MHz)
|
||||
- description: DPU clock (from CMU_TOP)
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: oscclk
|
||||
- const: dout_dpu
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: samsung,exynos850-cmu-hsi
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: External reference clock (26 MHz)
|
||||
- description: External RTC clock (32768 Hz)
|
||||
- description: CMU_HSI bus clock (from CMU_TOP)
|
||||
- description: SD card clock (from CMU_TOP)
|
||||
- description: "USB 2.0 DRD clock (from CMU_TOP)"
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: oscclk
|
||||
- const: rtcclk
|
||||
- const: dout_hsi_bus
|
||||
- const: dout_hsi_mmc_card
|
||||
- const: dout_hsi_usb20drd
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: samsung,exynos850-cmu-peri
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: External reference clock (26 MHz)
|
||||
- description: CMU_PERI bus clock (from CMU_TOP)
|
||||
- description: UART clock (from CMU_TOP)
|
||||
- description: Parent clock for HSI2C and SPI (from CMU_TOP)
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: oscclk
|
||||
- const: dout_peri_bus
|
||||
- const: dout_peri_uart
|
||||
- const: dout_peri_ip
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#clock-cells"
|
||||
- clocks
|
||||
- clock-names
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
# Clock controller node for CMU_PERI
|
||||
- |
|
||||
#include <dt-bindings/clock/exynos850.h>
|
||||
|
||||
cmu_peri: clock-controller@10030000 {
|
||||
compatible = "samsung,exynos850-cmu-peri";
|
||||
reg = <0x10030000 0x8000>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clocks = <&oscclk>, <&cmu_top CLK_DOUT_PERI_BUS>,
|
||||
<&cmu_top CLK_DOUT_PERI_UART>,
|
||||
<&cmu_top CLK_DOUT_PERI_IP>;
|
||||
clock-names = "oscclk", "dout_peri_bus",
|
||||
"dout_peri_uart", "dout_peri_ip";
|
||||
};
|
||||
|
||||
...
|
|
@ -67,7 +67,8 @@ config EXYNOS_5420_COMMON_CLK
|
|||
depends on COMMON_CLK_SAMSUNG
|
||||
help
|
||||
Support for the clock controller present on the Samsung
|
||||
Exynos5420 SoCs. Choose Y here only if you build for this SoC.
|
||||
Exynos5420/Exynos5422/Exynos5800 SoCs. Choose Y here only if you
|
||||
build for this SoC.
|
||||
|
||||
config EXYNOS_ARM64_COMMON_CLK
|
||||
bool "Samsung Exynos ARMv8-family clock controller support" if COMPILE_TEST
|
||||
|
@ -79,38 +80,47 @@ config EXYNOS_AUDSS_CLK_CON
|
|||
default y if ARCH_EXYNOS
|
||||
help
|
||||
Support for the Audio Subsystem CLKCON clock controller present
|
||||
on some Exynos SoC variants. Choose M or Y here if you want to
|
||||
use audio devices such as I2S, PCM, etc.
|
||||
on some Samsung Exynos SoC variants. Choose M or Y here if you want
|
||||
to use audio devices such as I2S, PCM, etc.
|
||||
|
||||
config EXYNOS_CLKOUT
|
||||
tristate "Samsung Exynos clock output driver"
|
||||
depends on COMMON_CLK_SAMSUNG
|
||||
default y if ARCH_EXYNOS
|
||||
help
|
||||
Support for the clock output (XCLKOUT) present on some of Exynos SoC
|
||||
variants. Usually the XCLKOUT is used to monitor the status of the
|
||||
certains clocks from SoC, but it could also be tied to other devices
|
||||
as an input clock.
|
||||
Support for the clock output (XCLKOUT) present on some of Samsung
|
||||
Exynos SoC variants. Usually the XCLKOUT is used to monitor the
|
||||
status of the certains clocks from SoC, but it could also be tied to
|
||||
other devices as an input clock.
|
||||
|
||||
# For S3C24XX platforms, select following symbols:
|
||||
config S3C2410_COMMON_CLK
|
||||
bool "Samsung S3C2410 clock controller support" if COMPILE_TEST
|
||||
select COMMON_CLK_SAMSUNG
|
||||
help
|
||||
Build the s3c2410 clock driver based on the common clock framework.
|
||||
Support for the clock controller present on the Samsung
|
||||
S3C2410/S3C2440/S3C2442 SoCs. Choose Y here only if you build for
|
||||
this SoC.
|
||||
|
||||
config S3C2410_COMMON_DCLK
|
||||
bool
|
||||
select COMMON_CLK_SAMSUNG
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
Temporary symbol to build the dclk driver based on the common clock
|
||||
framework.
|
||||
Support for the dclk clock controller present on the Samsung
|
||||
S3C2410/S3C2412/S3C2440/S3C2443 SoCs. Choose Y here only if you build
|
||||
for this SoC.
|
||||
|
||||
config S3C2412_COMMON_CLK
|
||||
bool "Samsung S3C2412 clock controller support" if COMPILE_TEST
|
||||
select COMMON_CLK_SAMSUNG
|
||||
help
|
||||
Support for the clock controller present on the Samsung S3C2412 SoCs.
|
||||
Choose Y here only if you build for this SoC.
|
||||
|
||||
config S3C2443_COMMON_CLK
|
||||
bool "Samsung S3C2443 clock controller support" if COMPILE_TEST
|
||||
select COMMON_CLK_SAMSUNG
|
||||
help
|
||||
Support for the clock controller present on the Samsung
|
||||
S3C2416/S3C2443 SoCs. Choose Y here only if you build for this SoC.
|
||||
|
|
|
@ -17,6 +17,7 @@ obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o
|
|||
obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
|
||||
obj-$(CONFIG_EXYNOS_CLKOUT) += clk-exynos-clkout.o
|
||||
obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos7.o
|
||||
obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos850.o
|
||||
obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
|
||||
obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
|
||||
obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
|
||||
|
|
|
@ -469,3 +469,21 @@ free_cpuclk:
|
|||
kfree(cpuclk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __init samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
|
||||
const struct samsung_cpu_clock *list, unsigned int nr_clk)
|
||||
{
|
||||
unsigned int idx;
|
||||
unsigned int num_cfgs;
|
||||
struct clk_hw **hws = ctx->clk_data.hws;
|
||||
|
||||
for (idx = 0; idx < nr_clk; idx++, list++) {
|
||||
/* find count of configuration rates in cfg */
|
||||
for (num_cfgs = 0; list->cfg[num_cfgs].prate != 0; )
|
||||
num_cfgs++;
|
||||
|
||||
exynos_register_cpu_clock(ctx, list->id, list->name, hws[list->parent_id],
|
||||
hws[list->alt_parent_id], list->offset, list->cfg, num_cfgs,
|
||||
list->flags);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,7 +129,6 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
|
|||
struct clk *pll_ref, *pll_in, *cdclk, *sclk_audio, *sclk_pcm_in;
|
||||
const struct exynos_audss_clk_drvdata *variant;
|
||||
struct clk_hw **clk_table;
|
||||
struct resource *res;
|
||||
struct device *dev = &pdev->dev;
|
||||
int i, ret = 0;
|
||||
|
||||
|
@ -137,8 +136,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
|
|||
if (!variant)
|
||||
return -EINVAL;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg_base = devm_ioremap_resource(dev, res);
|
||||
reg_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg_base))
|
||||
return PTR_ERR(reg_base);
|
||||
|
||||
|
|
|
@ -110,11 +110,9 @@ static int __init exynos4x12_isp_clk_probe(struct platform_device *pdev)
|
|||
struct samsung_clk_provider *ctx;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct resource *res;
|
||||
void __iomem *reg_base;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg_base = devm_ioremap_resource(dev, res);
|
||||
reg_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg_base))
|
||||
return PTR_ERR(reg_base);
|
||||
|
||||
|
|
|
@ -3675,44 +3675,32 @@ static const struct exynos_cpuclk_cfg_data exynos5433_apolloclk_d[] __initconst
|
|||
{ 0 },
|
||||
};
|
||||
|
||||
static const struct samsung_cpu_clock apollo_cpu_clks[] __initconst = {
|
||||
CPU_CLK(CLK_SCLK_APOLLO, "apolloclk", CLK_MOUT_APOLLO_PLL,
|
||||
CLK_MOUT_BUS_PLL_APOLLO_USER,
|
||||
CLK_CPU_HAS_E5433_REGS_LAYOUT, 0x200,
|
||||
exynos5433_apolloclk_d),
|
||||
};
|
||||
|
||||
static const struct samsung_cmu_info apollo_cmu_info __initconst = {
|
||||
.pll_clks = apollo_pll_clks,
|
||||
.nr_pll_clks = ARRAY_SIZE(apollo_pll_clks),
|
||||
.mux_clks = apollo_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(apollo_mux_clks),
|
||||
.div_clks = apollo_div_clks,
|
||||
.nr_div_clks = ARRAY_SIZE(apollo_div_clks),
|
||||
.gate_clks = apollo_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(apollo_gate_clks),
|
||||
.cpu_clks = apollo_cpu_clks,
|
||||
.nr_cpu_clks = ARRAY_SIZE(apollo_cpu_clks),
|
||||
.nr_clk_ids = APOLLO_NR_CLK,
|
||||
.clk_regs = apollo_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(apollo_clk_regs),
|
||||
};
|
||||
|
||||
static void __init exynos5433_cmu_apollo_init(struct device_node *np)
|
||||
{
|
||||
void __iomem *reg_base;
|
||||
struct samsung_clk_provider *ctx;
|
||||
struct clk_hw **hws;
|
||||
|
||||
reg_base = of_iomap(np, 0);
|
||||
if (!reg_base) {
|
||||
panic("%s: failed to map registers\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx = samsung_clk_init(np, reg_base, APOLLO_NR_CLK);
|
||||
if (!ctx) {
|
||||
panic("%s: unable to allocate ctx\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
samsung_clk_register_pll(ctx, apollo_pll_clks,
|
||||
ARRAY_SIZE(apollo_pll_clks), reg_base);
|
||||
samsung_clk_register_mux(ctx, apollo_mux_clks,
|
||||
ARRAY_SIZE(apollo_mux_clks));
|
||||
samsung_clk_register_div(ctx, apollo_div_clks,
|
||||
ARRAY_SIZE(apollo_div_clks));
|
||||
samsung_clk_register_gate(ctx, apollo_gate_clks,
|
||||
ARRAY_SIZE(apollo_gate_clks));
|
||||
|
||||
hws = ctx->clk_data.hws;
|
||||
|
||||
exynos_register_cpu_clock(ctx, CLK_SCLK_APOLLO, "apolloclk",
|
||||
hws[CLK_MOUT_APOLLO_PLL], hws[CLK_MOUT_BUS_PLL_APOLLO_USER], 0x200,
|
||||
exynos5433_apolloclk_d, ARRAY_SIZE(exynos5433_apolloclk_d),
|
||||
CLK_CPU_HAS_E5433_REGS_LAYOUT);
|
||||
|
||||
samsung_clk_sleep_init(reg_base, apollo_clk_regs,
|
||||
ARRAY_SIZE(apollo_clk_regs));
|
||||
|
||||
samsung_clk_of_add_provider(np, ctx);
|
||||
samsung_cmu_register_one(np, &apollo_cmu_info);
|
||||
}
|
||||
CLK_OF_DECLARE(exynos5433_cmu_apollo, "samsung,exynos5433-cmu-apollo",
|
||||
exynos5433_cmu_apollo_init);
|
||||
|
@ -3932,44 +3920,32 @@ static const struct exynos_cpuclk_cfg_data exynos5433_atlasclk_d[] __initconst =
|
|||
{ 0 },
|
||||
};
|
||||
|
||||
static const struct samsung_cpu_clock atlas_cpu_clks[] __initconst = {
|
||||
CPU_CLK(CLK_SCLK_ATLAS, "atlasclk", CLK_MOUT_ATLAS_PLL,
|
||||
CLK_MOUT_BUS_PLL_ATLAS_USER,
|
||||
CLK_CPU_HAS_E5433_REGS_LAYOUT, 0x200,
|
||||
exynos5433_atlasclk_d),
|
||||
};
|
||||
|
||||
static const struct samsung_cmu_info atlas_cmu_info __initconst = {
|
||||
.pll_clks = atlas_pll_clks,
|
||||
.nr_pll_clks = ARRAY_SIZE(atlas_pll_clks),
|
||||
.mux_clks = atlas_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(atlas_mux_clks),
|
||||
.div_clks = atlas_div_clks,
|
||||
.nr_div_clks = ARRAY_SIZE(atlas_div_clks),
|
||||
.gate_clks = atlas_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(atlas_gate_clks),
|
||||
.cpu_clks = atlas_cpu_clks,
|
||||
.nr_cpu_clks = ARRAY_SIZE(atlas_cpu_clks),
|
||||
.nr_clk_ids = ATLAS_NR_CLK,
|
||||
.clk_regs = atlas_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(atlas_clk_regs),
|
||||
};
|
||||
|
||||
static void __init exynos5433_cmu_atlas_init(struct device_node *np)
|
||||
{
|
||||
void __iomem *reg_base;
|
||||
struct samsung_clk_provider *ctx;
|
||||
struct clk_hw **hws;
|
||||
|
||||
reg_base = of_iomap(np, 0);
|
||||
if (!reg_base) {
|
||||
panic("%s: failed to map registers\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx = samsung_clk_init(np, reg_base, ATLAS_NR_CLK);
|
||||
if (!ctx) {
|
||||
panic("%s: unable to allocate ctx\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
samsung_clk_register_pll(ctx, atlas_pll_clks,
|
||||
ARRAY_SIZE(atlas_pll_clks), reg_base);
|
||||
samsung_clk_register_mux(ctx, atlas_mux_clks,
|
||||
ARRAY_SIZE(atlas_mux_clks));
|
||||
samsung_clk_register_div(ctx, atlas_div_clks,
|
||||
ARRAY_SIZE(atlas_div_clks));
|
||||
samsung_clk_register_gate(ctx, atlas_gate_clks,
|
||||
ARRAY_SIZE(atlas_gate_clks));
|
||||
|
||||
hws = ctx->clk_data.hws;
|
||||
|
||||
exynos_register_cpu_clock(ctx, CLK_SCLK_ATLAS, "atlasclk",
|
||||
hws[CLK_MOUT_ATLAS_PLL], hws[CLK_MOUT_BUS_PLL_ATLAS_USER], 0x200,
|
||||
exynos5433_atlasclk_d, ARRAY_SIZE(exynos5433_atlasclk_d),
|
||||
CLK_CPU_HAS_E5433_REGS_LAYOUT);
|
||||
|
||||
samsung_clk_sleep_init(reg_base, atlas_clk_regs,
|
||||
ARRAY_SIZE(atlas_clk_regs));
|
||||
|
||||
samsung_clk_of_add_provider(np, ctx);
|
||||
samsung_cmu_register_one(np, &atlas_cmu_info);
|
||||
}
|
||||
CLK_OF_DECLARE(exynos5433_cmu_atlas, "samsung,exynos5433-cmu-atlas",
|
||||
exynos5433_cmu_atlas_init);
|
||||
|
@ -5564,7 +5540,6 @@ static int __init exynos5433_cmu_probe(struct platform_device *pdev)
|
|||
struct exynos5433_cmu_data *data;
|
||||
struct samsung_clk_provider *ctx;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
void __iomem *reg_base;
|
||||
int i;
|
||||
|
||||
|
@ -5577,8 +5552,7 @@ static int __init exynos5433_cmu_probe(struct platform_device *pdev)
|
|||
return -ENOMEM;
|
||||
ctx = &data->ctx;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg_base = devm_ioremap_resource(dev, res);
|
||||
reg_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg_base))
|
||||
return PTR_ERR(reg_base);
|
||||
|
||||
|
|
|
@ -0,0 +1,835 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021 Linaro Ltd.
|
||||
* Author: Sam Protsenko <semen.protsenko@linaro.org>
|
||||
*
|
||||
* Common Clock Framework support for Exynos850 SoC.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <dt-bindings/clock/exynos850.h>
|
||||
|
||||
#include "clk.h"
|
||||
|
||||
/* Gate register bits */
|
||||
#define GATE_MANUAL BIT(20)
|
||||
#define GATE_ENABLE_HWACG BIT(28)
|
||||
|
||||
/* Gate register offsets range */
|
||||
#define GATE_OFF_START 0x2000
|
||||
#define GATE_OFF_END 0x2fff
|
||||
|
||||
/**
|
||||
* exynos850_init_clocks - Set clocks initial configuration
|
||||
* @np: CMU device tree node with "reg" property (CMU addr)
|
||||
* @reg_offs: Register offsets array for clocks to init
|
||||
* @reg_offs_len: Number of register offsets in reg_offs array
|
||||
*
|
||||
* Set manual control mode for all gate clocks.
|
||||
*/
|
||||
static void __init exynos850_init_clocks(struct device_node *np,
|
||||
const unsigned long *reg_offs, size_t reg_offs_len)
|
||||
{
|
||||
void __iomem *reg_base;
|
||||
size_t i;
|
||||
|
||||
reg_base = of_iomap(np, 0);
|
||||
if (!reg_base)
|
||||
panic("%s: failed to map registers\n", __func__);
|
||||
|
||||
for (i = 0; i < reg_offs_len; ++i) {
|
||||
void __iomem *reg = reg_base + reg_offs[i];
|
||||
u32 val;
|
||||
|
||||
/* Modify only gate clock registers */
|
||||
if (reg_offs[i] < GATE_OFF_START || reg_offs[i] > GATE_OFF_END)
|
||||
continue;
|
||||
|
||||
val = readl(reg);
|
||||
val |= GATE_MANUAL;
|
||||
val &= ~GATE_ENABLE_HWACG;
|
||||
writel(val, reg);
|
||||
}
|
||||
|
||||
iounmap(reg_base);
|
||||
}
|
||||
|
||||
/* ---- CMU_TOP ------------------------------------------------------------- */
|
||||
|
||||
/* Register Offset definitions for CMU_TOP (0x120e0000) */
|
||||
#define PLL_LOCKTIME_PLL_MMC 0x0000
|
||||
#define PLL_LOCKTIME_PLL_SHARED0 0x0004
|
||||
#define PLL_LOCKTIME_PLL_SHARED1 0x0008
|
||||
#define PLL_CON0_PLL_MMC 0x0100
|
||||
#define PLL_CON3_PLL_MMC 0x010c
|
||||
#define PLL_CON0_PLL_SHARED0 0x0140
|
||||
#define PLL_CON3_PLL_SHARED0 0x014c
|
||||
#define PLL_CON0_PLL_SHARED1 0x0180
|
||||
#define PLL_CON3_PLL_SHARED1 0x018c
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS 0x1014
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_CORE_CCI 0x1018
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD 0x101c
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_CORE_SSS 0x1020
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_DPU 0x1034
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_HSI_BUS 0x103c
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD 0x1040
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD 0x1044
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_PERI_BUS 0x1070
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_PERI_IP 0x1074
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_PERI_UART 0x1078
|
||||
#define CLK_CON_DIV_CLKCMU_CORE_BUS 0x1820
|
||||
#define CLK_CON_DIV_CLKCMU_CORE_CCI 0x1824
|
||||
#define CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD 0x1828
|
||||
#define CLK_CON_DIV_CLKCMU_CORE_SSS 0x182c
|
||||
#define CLK_CON_DIV_CLKCMU_DPU 0x1840
|
||||
#define CLK_CON_DIV_CLKCMU_HSI_BUS 0x1848
|
||||
#define CLK_CON_DIV_CLKCMU_HSI_MMC_CARD 0x184c
|
||||
#define CLK_CON_DIV_CLKCMU_HSI_USB20DRD 0x1850
|
||||
#define CLK_CON_DIV_CLKCMU_PERI_BUS 0x187c
|
||||
#define CLK_CON_DIV_CLKCMU_PERI_IP 0x1880
|
||||
#define CLK_CON_DIV_CLKCMU_PERI_UART 0x1884
|
||||
#define CLK_CON_DIV_PLL_SHARED0_DIV2 0x188c
|
||||
#define CLK_CON_DIV_PLL_SHARED0_DIV3 0x1890
|
||||
#define CLK_CON_DIV_PLL_SHARED0_DIV4 0x1894
|
||||
#define CLK_CON_DIV_PLL_SHARED1_DIV2 0x1898
|
||||
#define CLK_CON_DIV_PLL_SHARED1_DIV3 0x189c
|
||||
#define CLK_CON_DIV_PLL_SHARED1_DIV4 0x18a0
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS 0x201c
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_CORE_CCI 0x2020
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD 0x2024
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_CORE_SSS 0x2028
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_DPU 0x203c
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_HSI_BUS 0x2044
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD 0x2048
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD 0x204c
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_PERI_BUS 0x2080
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_PERI_IP 0x2084
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_PERI_UART 0x2088
|
||||
|
||||
static const unsigned long top_clk_regs[] __initconst = {
|
||||
PLL_LOCKTIME_PLL_MMC,
|
||||
PLL_LOCKTIME_PLL_SHARED0,
|
||||
PLL_LOCKTIME_PLL_SHARED1,
|
||||
PLL_CON0_PLL_MMC,
|
||||
PLL_CON3_PLL_MMC,
|
||||
PLL_CON0_PLL_SHARED0,
|
||||
PLL_CON3_PLL_SHARED0,
|
||||
PLL_CON0_PLL_SHARED1,
|
||||
PLL_CON3_PLL_SHARED1,
|
||||
CLK_CON_MUX_MUX_CLKCMU_CORE_BUS,
|
||||
CLK_CON_MUX_MUX_CLKCMU_CORE_CCI,
|
||||
CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD,
|
||||
CLK_CON_MUX_MUX_CLKCMU_CORE_SSS,
|
||||
CLK_CON_MUX_MUX_CLKCMU_DPU,
|
||||
CLK_CON_MUX_MUX_CLKCMU_HSI_BUS,
|
||||
CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD,
|
||||
CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD,
|
||||
CLK_CON_MUX_MUX_CLKCMU_PERI_BUS,
|
||||
CLK_CON_MUX_MUX_CLKCMU_PERI_IP,
|
||||
CLK_CON_MUX_MUX_CLKCMU_PERI_UART,
|
||||
CLK_CON_DIV_CLKCMU_CORE_BUS,
|
||||
CLK_CON_DIV_CLKCMU_CORE_CCI,
|
||||
CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD,
|
||||
CLK_CON_DIV_CLKCMU_CORE_SSS,
|
||||
CLK_CON_DIV_CLKCMU_DPU,
|
||||
CLK_CON_DIV_CLKCMU_HSI_BUS,
|
||||
CLK_CON_DIV_CLKCMU_HSI_MMC_CARD,
|
||||
CLK_CON_DIV_CLKCMU_HSI_USB20DRD,
|
||||
CLK_CON_DIV_CLKCMU_PERI_BUS,
|
||||
CLK_CON_DIV_CLKCMU_PERI_IP,
|
||||
CLK_CON_DIV_CLKCMU_PERI_UART,
|
||||
CLK_CON_DIV_PLL_SHARED0_DIV2,
|
||||
CLK_CON_DIV_PLL_SHARED0_DIV3,
|
||||
CLK_CON_DIV_PLL_SHARED0_DIV4,
|
||||
CLK_CON_DIV_PLL_SHARED1_DIV2,
|
||||
CLK_CON_DIV_PLL_SHARED1_DIV3,
|
||||
CLK_CON_DIV_PLL_SHARED1_DIV4,
|
||||
CLK_CON_GAT_GATE_CLKCMU_CORE_BUS,
|
||||
CLK_CON_GAT_GATE_CLKCMU_CORE_CCI,
|
||||
CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD,
|
||||
CLK_CON_GAT_GATE_CLKCMU_CORE_SSS,
|
||||
CLK_CON_GAT_GATE_CLKCMU_DPU,
|
||||
CLK_CON_GAT_GATE_CLKCMU_HSI_BUS,
|
||||
CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD,
|
||||
CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD,
|
||||
CLK_CON_GAT_GATE_CLKCMU_PERI_BUS,
|
||||
CLK_CON_GAT_GATE_CLKCMU_PERI_IP,
|
||||
CLK_CON_GAT_GATE_CLKCMU_PERI_UART,
|
||||
};
|
||||
|
||||
/*
|
||||
* Do not provide PLL tables to core PLLs, as MANUAL_PLL_CTRL bit is not set
|
||||
* for those PLLs by default, so set_rate operation would fail.
|
||||
*/
|
||||
static const struct samsung_pll_clock top_pll_clks[] __initconst = {
|
||||
/* CMU_TOP_PURECLKCOMP */
|
||||
PLL(pll_0822x, CLK_FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk",
|
||||
PLL_LOCKTIME_PLL_SHARED0, PLL_CON3_PLL_SHARED0,
|
||||
NULL),
|
||||
PLL(pll_0822x, CLK_FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk",
|
||||
PLL_LOCKTIME_PLL_SHARED1, PLL_CON3_PLL_SHARED1,
|
||||
NULL),
|
||||
PLL(pll_0831x, CLK_FOUT_MMC_PLL, "fout_mmc_pll", "oscclk",
|
||||
PLL_LOCKTIME_PLL_MMC, PLL_CON3_PLL_MMC, NULL),
|
||||
};
|
||||
|
||||
/* List of parent clocks for Muxes in CMU_TOP */
|
||||
PNAME(mout_shared0_pll_p) = { "oscclk", "fout_shared0_pll" };
|
||||
PNAME(mout_shared1_pll_p) = { "oscclk", "fout_shared1_pll" };
|
||||
PNAME(mout_mmc_pll_p) = { "oscclk", "fout_mmc_pll" };
|
||||
/* List of parent clocks for Muxes in CMU_TOP: for CMU_CORE */
|
||||
PNAME(mout_core_bus_p) = { "dout_shared1_div2", "dout_shared0_div3",
|
||||
"dout_shared1_div3", "dout_shared0_div4" };
|
||||
PNAME(mout_core_cci_p) = { "dout_shared0_div2", "dout_shared1_div2",
|
||||
"dout_shared0_div3", "dout_shared1_div3" };
|
||||
PNAME(mout_core_mmc_embd_p) = { "oscclk", "dout_shared0_div2",
|
||||
"dout_shared1_div2", "dout_shared0_div3",
|
||||
"dout_shared1_div3", "mout_mmc_pll",
|
||||
"oscclk", "oscclk" };
|
||||
PNAME(mout_core_sss_p) = { "dout_shared0_div3", "dout_shared1_div3",
|
||||
"dout_shared0_div4", "dout_shared1_div4" };
|
||||
/* List of parent clocks for Muxes in CMU_TOP: for CMU_HSI */
|
||||
PNAME(mout_hsi_bus_p) = { "dout_shared0_div2", "dout_shared1_div2" };
|
||||
PNAME(mout_hsi_mmc_card_p) = { "oscclk", "dout_shared0_div2",
|
||||
"dout_shared1_div2", "dout_shared0_div3",
|
||||
"dout_shared1_div3", "mout_mmc_pll",
|
||||
"oscclk", "oscclk" };
|
||||
PNAME(mout_hsi_usb20drd_p) = { "oscclk", "dout_shared0_div4",
|
||||
"dout_shared1_div4", "oscclk" };
|
||||
/* List of parent clocks for Muxes in CMU_TOP: for CMU_PERI */
|
||||
PNAME(mout_peri_bus_p) = { "dout_shared0_div4", "dout_shared1_div4" };
|
||||
PNAME(mout_peri_uart_p) = { "oscclk", "dout_shared0_div4",
|
||||
"dout_shared1_div4", "oscclk" };
|
||||
PNAME(mout_peri_ip_p) = { "oscclk", "dout_shared0_div4",
|
||||
"dout_shared1_div4", "oscclk" };
|
||||
|
||||
/* List of parent clocks for Muxes in CMU_TOP: for CMU_DPU */
|
||||
PNAME(mout_dpu_p) = { "dout_shared0_div3", "dout_shared1_div3",
|
||||
"dout_shared0_div4", "dout_shared1_div4" };
|
||||
|
||||
static const struct samsung_mux_clock top_mux_clks[] __initconst = {
|
||||
/* CMU_TOP_PURECLKCOMP */
|
||||
MUX(CLK_MOUT_SHARED0_PLL, "mout_shared0_pll", mout_shared0_pll_p,
|
||||
PLL_CON0_PLL_SHARED0, 4, 1),
|
||||
MUX(CLK_MOUT_SHARED1_PLL, "mout_shared1_pll", mout_shared1_pll_p,
|
||||
PLL_CON0_PLL_SHARED1, 4, 1),
|
||||
MUX(CLK_MOUT_MMC_PLL, "mout_mmc_pll", mout_mmc_pll_p,
|
||||
PLL_CON0_PLL_MMC, 4, 1),
|
||||
|
||||
/* CORE */
|
||||
MUX(CLK_MOUT_CORE_BUS, "mout_core_bus", mout_core_bus_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, 0, 2),
|
||||
MUX(CLK_MOUT_CORE_CCI, "mout_core_cci", mout_core_cci_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_CORE_CCI, 0, 2),
|
||||
MUX(CLK_MOUT_CORE_MMC_EMBD, "mout_core_mmc_embd", mout_core_mmc_embd_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD, 0, 3),
|
||||
MUX(CLK_MOUT_CORE_SSS, "mout_core_sss", mout_core_sss_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_CORE_SSS, 0, 2),
|
||||
|
||||
/* DPU */
|
||||
MUX(CLK_MOUT_DPU, "mout_dpu", mout_dpu_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_DPU, 0, 2),
|
||||
|
||||
/* HSI */
|
||||
MUX(CLK_MOUT_HSI_BUS, "mout_hsi_bus", mout_hsi_bus_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_HSI_BUS, 0, 1),
|
||||
MUX(CLK_MOUT_HSI_MMC_CARD, "mout_hsi_mmc_card", mout_hsi_mmc_card_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD, 0, 3),
|
||||
MUX(CLK_MOUT_HSI_USB20DRD, "mout_hsi_usb20drd", mout_hsi_usb20drd_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD, 0, 2),
|
||||
|
||||
/* PERI */
|
||||
MUX(CLK_MOUT_PERI_BUS, "mout_peri_bus", mout_peri_bus_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_PERI_BUS, 0, 1),
|
||||
MUX(CLK_MOUT_PERI_UART, "mout_peri_uart", mout_peri_uart_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_PERI_UART, 0, 2),
|
||||
MUX(CLK_MOUT_PERI_IP, "mout_peri_ip", mout_peri_ip_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_PERI_IP, 0, 2),
|
||||
};
|
||||
|
||||
static const struct samsung_div_clock top_div_clks[] __initconst = {
|
||||
/* CMU_TOP_PURECLKCOMP */
|
||||
DIV(CLK_DOUT_SHARED0_DIV3, "dout_shared0_div3", "mout_shared0_pll",
|
||||
CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2),
|
||||
DIV(CLK_DOUT_SHARED0_DIV2, "dout_shared0_div2", "mout_shared0_pll",
|
||||
CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1),
|
||||
DIV(CLK_DOUT_SHARED1_DIV3, "dout_shared1_div3", "mout_shared1_pll",
|
||||
CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2),
|
||||
DIV(CLK_DOUT_SHARED1_DIV2, "dout_shared1_div2", "mout_shared1_pll",
|
||||
CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1),
|
||||
DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "dout_shared0_div2",
|
||||
CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1),
|
||||
DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "dout_shared1_div2",
|
||||
CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1),
|
||||
|
||||
/* CORE */
|
||||
DIV(CLK_DOUT_CORE_BUS, "dout_core_bus", "gout_core_bus",
|
||||
CLK_CON_DIV_CLKCMU_CORE_BUS, 0, 4),
|
||||
DIV(CLK_DOUT_CORE_CCI, "dout_core_cci", "gout_core_cci",
|
||||
CLK_CON_DIV_CLKCMU_CORE_CCI, 0, 4),
|
||||
DIV(CLK_DOUT_CORE_MMC_EMBD, "dout_core_mmc_embd", "gout_core_mmc_embd",
|
||||
CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD, 0, 9),
|
||||
DIV(CLK_DOUT_CORE_SSS, "dout_core_sss", "gout_core_sss",
|
||||
CLK_CON_DIV_CLKCMU_CORE_SSS, 0, 4),
|
||||
|
||||
/* DPU */
|
||||
DIV(CLK_DOUT_DPU, "dout_dpu", "gout_dpu",
|
||||
CLK_CON_DIV_CLKCMU_DPU, 0, 4),
|
||||
|
||||
/* HSI */
|
||||
DIV(CLK_DOUT_HSI_BUS, "dout_hsi_bus", "gout_hsi_bus",
|
||||
CLK_CON_DIV_CLKCMU_HSI_BUS, 0, 4),
|
||||
DIV(CLK_DOUT_HSI_MMC_CARD, "dout_hsi_mmc_card", "gout_hsi_mmc_card",
|
||||
CLK_CON_DIV_CLKCMU_HSI_MMC_CARD, 0, 9),
|
||||
DIV(CLK_DOUT_HSI_USB20DRD, "dout_hsi_usb20drd", "gout_hsi_usb20drd",
|
||||
CLK_CON_DIV_CLKCMU_HSI_USB20DRD, 0, 4),
|
||||
|
||||
/* PERI */
|
||||
DIV(CLK_DOUT_PERI_BUS, "dout_peri_bus", "gout_peri_bus",
|
||||
CLK_CON_DIV_CLKCMU_PERI_BUS, 0, 4),
|
||||
DIV(CLK_DOUT_PERI_UART, "dout_peri_uart", "gout_peri_uart",
|
||||
CLK_CON_DIV_CLKCMU_PERI_UART, 0, 4),
|
||||
DIV(CLK_DOUT_PERI_IP, "dout_peri_ip", "gout_peri_ip",
|
||||
CLK_CON_DIV_CLKCMU_PERI_IP, 0, 4),
|
||||
};
|
||||
|
||||
static const struct samsung_gate_clock top_gate_clks[] __initconst = {
|
||||
/* CORE */
|
||||
GATE(CLK_GOUT_CORE_BUS, "gout_core_bus", "mout_core_bus",
|
||||
CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, 21, 0, 0),
|
||||
GATE(CLK_GOUT_CORE_CCI, "gout_core_cci", "mout_core_cci",
|
||||
CLK_CON_GAT_GATE_CLKCMU_CORE_CCI, 21, 0, 0),
|
||||
GATE(CLK_GOUT_CORE_MMC_EMBD, "gout_core_mmc_embd", "mout_core_mmc_embd",
|
||||
CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD, 21, 0, 0),
|
||||
GATE(CLK_GOUT_CORE_SSS, "gout_core_sss", "mout_core_sss",
|
||||
CLK_CON_GAT_GATE_CLKCMU_CORE_SSS, 21, 0, 0),
|
||||
|
||||
/* DPU */
|
||||
GATE(CLK_GOUT_DPU, "gout_dpu", "mout_dpu",
|
||||
CLK_CON_GAT_GATE_CLKCMU_DPU, 21, 0, 0),
|
||||
|
||||
/* HSI */
|
||||
GATE(CLK_GOUT_HSI_BUS, "gout_hsi_bus", "mout_hsi_bus",
|
||||
CLK_CON_GAT_GATE_CLKCMU_HSI_BUS, 21, 0, 0),
|
||||
GATE(CLK_GOUT_HSI_MMC_CARD, "gout_hsi_mmc_card", "mout_hsi_mmc_card",
|
||||
CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD, 21, 0, 0),
|
||||
GATE(CLK_GOUT_HSI_USB20DRD, "gout_hsi_usb20drd", "mout_hsi_usb20drd",
|
||||
CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD, 21, 0, 0),
|
||||
|
||||
/* PERI */
|
||||
GATE(CLK_GOUT_PERI_BUS, "gout_peri_bus", "mout_peri_bus",
|
||||
CLK_CON_GAT_GATE_CLKCMU_PERI_BUS, 21, 0, 0),
|
||||
GATE(CLK_GOUT_PERI_UART, "gout_peri_uart", "mout_peri_uart",
|
||||
CLK_CON_GAT_GATE_CLKCMU_PERI_UART, 21, 0, 0),
|
||||
GATE(CLK_GOUT_PERI_IP, "gout_peri_ip", "mout_peri_ip",
|
||||
CLK_CON_GAT_GATE_CLKCMU_PERI_IP, 21, 0, 0),
|
||||
};
|
||||
|
||||
static const struct samsung_cmu_info top_cmu_info __initconst = {
|
||||
.pll_clks = top_pll_clks,
|
||||
.nr_pll_clks = ARRAY_SIZE(top_pll_clks),
|
||||
.mux_clks = top_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(top_mux_clks),
|
||||
.div_clks = top_div_clks,
|
||||
.nr_div_clks = ARRAY_SIZE(top_div_clks),
|
||||
.gate_clks = top_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(top_gate_clks),
|
||||
.nr_clk_ids = TOP_NR_CLK,
|
||||
.clk_regs = top_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(top_clk_regs),
|
||||
};
|
||||
|
||||
static void __init exynos850_cmu_top_init(struct device_node *np)
|
||||
{
|
||||
exynos850_init_clocks(np, top_clk_regs, ARRAY_SIZE(top_clk_regs));
|
||||
samsung_cmu_register_one(np, &top_cmu_info);
|
||||
}
|
||||
|
||||
CLK_OF_DECLARE(exynos850_cmu_top, "samsung,exynos850-cmu-top",
|
||||
exynos850_cmu_top_init);
|
||||
|
||||
/* ---- CMU_HSI ------------------------------------------------------------- */
|
||||
|
||||
/* Register Offset definitions for CMU_HSI (0x13400000) */
|
||||
#define PLL_CON0_MUX_CLKCMU_HSI_BUS_USER 0x0600
|
||||
#define PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER 0x0610
|
||||
#define PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER 0x0620
|
||||
#define CLK_CON_MUX_MUX_CLK_HSI_RTC 0x1000
|
||||
#define CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV 0x2008
|
||||
#define CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50 0x200c
|
||||
#define CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26 0x2010
|
||||
#define CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK 0x2018
|
||||
#define CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK 0x2024
|
||||
#define CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN 0x2028
|
||||
#define CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK 0x2038
|
||||
#define CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20 0x203c
|
||||
#define CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY 0x2040
|
||||
|
||||
static const unsigned long hsi_clk_regs[] __initconst = {
|
||||
PLL_CON0_MUX_CLKCMU_HSI_BUS_USER,
|
||||
PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER,
|
||||
PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER,
|
||||
CLK_CON_MUX_MUX_CLK_HSI_RTC,
|
||||
CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV,
|
||||
CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50,
|
||||
CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26,
|
||||
CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK,
|
||||
CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK,
|
||||
CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN,
|
||||
CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK,
|
||||
CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20,
|
||||
CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY,
|
||||
};
|
||||
|
||||
/* List of parent clocks for Muxes in CMU_PERI */
|
||||
PNAME(mout_hsi_bus_user_p) = { "oscclk", "dout_hsi_bus" };
|
||||
PNAME(mout_hsi_mmc_card_user_p) = { "oscclk", "dout_hsi_mmc_card" };
|
||||
PNAME(mout_hsi_usb20drd_user_p) = { "oscclk", "dout_hsi_usb20drd" };
|
||||
PNAME(mout_hsi_rtc_p) = { "rtcclk", "oscclk" };
|
||||
|
||||
static const struct samsung_mux_clock hsi_mux_clks[] __initconst = {
|
||||
MUX(CLK_MOUT_HSI_BUS_USER, "mout_hsi_bus_user", mout_hsi_bus_user_p,
|
||||
PLL_CON0_MUX_CLKCMU_HSI_BUS_USER, 4, 1),
|
||||
MUX_F(CLK_MOUT_HSI_MMC_CARD_USER, "mout_hsi_mmc_card_user",
|
||||
mout_hsi_mmc_card_user_p, PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER,
|
||||
4, 1, CLK_SET_RATE_PARENT, 0),
|
||||
MUX(CLK_MOUT_HSI_USB20DRD_USER, "mout_hsi_usb20drd_user",
|
||||
mout_hsi_usb20drd_user_p, PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER,
|
||||
4, 1),
|
||||
MUX(CLK_MOUT_HSI_RTC, "mout_hsi_rtc", mout_hsi_rtc_p,
|
||||
CLK_CON_MUX_MUX_CLK_HSI_RTC, 0, 1),
|
||||
};
|
||||
|
||||
static const struct samsung_gate_clock hsi_gate_clks[] __initconst = {
|
||||
GATE(CLK_GOUT_USB_RTC_CLK, "gout_usb_rtc", "mout_hsi_rtc",
|
||||
CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV, 21, 0, 0),
|
||||
GATE(CLK_GOUT_USB_REF_CLK, "gout_usb_ref", "mout_hsi_usb20drd_user",
|
||||
CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50, 21, 0, 0),
|
||||
GATE(CLK_GOUT_USB_PHY_REF_CLK, "gout_usb_phy_ref", "oscclk",
|
||||
CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26, 21, 0, 0),
|
||||
GATE(CLK_GOUT_GPIO_HSI_PCLK, "gout_gpio_hsi_pclk", "mout_hsi_bus_user",
|
||||
CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_MMC_CARD_ACLK, "gout_mmc_card_aclk", "mout_hsi_bus_user",
|
||||
CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_MMC_CARD_SDCLKIN, "gout_mmc_card_sdclkin",
|
||||
"mout_hsi_mmc_card_user",
|
||||
CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN, 21, CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_SYSREG_HSI_PCLK, "gout_sysreg_hsi_pclk",
|
||||
"mout_hsi_bus_user",
|
||||
CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_USB_PHY_ACLK, "gout_usb_phy_aclk", "mout_hsi_bus_user",
|
||||
CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20, 21, 0, 0),
|
||||
GATE(CLK_GOUT_USB_BUS_EARLY_CLK, "gout_usb_bus_early",
|
||||
"mout_hsi_bus_user",
|
||||
CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY, 21, 0, 0),
|
||||
};
|
||||
|
||||
static const struct samsung_cmu_info hsi_cmu_info __initconst = {
|
||||
.mux_clks = hsi_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(hsi_mux_clks),
|
||||
.gate_clks = hsi_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(hsi_gate_clks),
|
||||
.nr_clk_ids = HSI_NR_CLK,
|
||||
.clk_regs = hsi_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(hsi_clk_regs),
|
||||
.clk_name = "dout_hsi_bus",
|
||||
};
|
||||
|
||||
/* ---- CMU_PERI ------------------------------------------------------------ */
|
||||
|
||||
/* Register Offset definitions for CMU_PERI (0x10030000) */
|
||||
#define PLL_CON0_MUX_CLKCMU_PERI_BUS_USER 0x0600
|
||||
#define PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER 0x0610
|
||||
#define PLL_CON0_MUX_CLKCMU_PERI_SPI_USER 0x0620
|
||||
#define PLL_CON0_MUX_CLKCMU_PERI_UART_USER 0x0630
|
||||
#define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0 0x1800
|
||||
#define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1 0x1804
|
||||
#define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2 0x1808
|
||||
#define CLK_CON_DIV_DIV_CLK_PERI_SPI_0 0x180c
|
||||
#define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0 0x200c
|
||||
#define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1 0x2010
|
||||
#define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2 0x2014
|
||||
#define CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK 0x2020
|
||||
#define CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK 0x2024
|
||||
#define CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK 0x2028
|
||||
#define CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK 0x202c
|
||||
#define CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK 0x2030
|
||||
#define CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK 0x2034
|
||||
#define CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK 0x2038
|
||||
#define CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK 0x203c
|
||||
#define CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK 0x2040
|
||||
#define CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK 0x2044
|
||||
#define CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK 0x2048
|
||||
#define CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK 0x204c
|
||||
#define CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK 0x2050
|
||||
#define CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK 0x2054
|
||||
#define CLK_CON_GAT_GOUT_PERI_MCT_PCLK 0x205c
|
||||
#define CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK 0x2064
|
||||
#define CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK 0x209c
|
||||
#define CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK 0x20a0
|
||||
#define CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK 0x20a4
|
||||
#define CLK_CON_GAT_GOUT_PERI_UART_IPCLK 0x20a8
|
||||
#define CLK_CON_GAT_GOUT_PERI_UART_PCLK 0x20ac
|
||||
#define CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK 0x20b0
|
||||
#define CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK 0x20b4
|
||||
|
||||
static const unsigned long peri_clk_regs[] __initconst = {
|
||||
PLL_CON0_MUX_CLKCMU_PERI_BUS_USER,
|
||||
PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER,
|
||||
PLL_CON0_MUX_CLKCMU_PERI_SPI_USER,
|
||||
PLL_CON0_MUX_CLKCMU_PERI_UART_USER,
|
||||
CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0,
|
||||
CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1,
|
||||
CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2,
|
||||
CLK_CON_DIV_DIV_CLK_PERI_SPI_0,
|
||||
CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0,
|
||||
CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1,
|
||||
CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2,
|
||||
CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_MCT_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_UART_IPCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_UART_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK,
|
||||
};
|
||||
|
||||
/* List of parent clocks for Muxes in CMU_PERI */
|
||||
PNAME(mout_peri_bus_user_p) = { "oscclk", "dout_peri_bus" };
|
||||
PNAME(mout_peri_uart_user_p) = { "oscclk", "dout_peri_uart" };
|
||||
PNAME(mout_peri_hsi2c_user_p) = { "oscclk", "dout_peri_ip" };
|
||||
PNAME(mout_peri_spi_user_p) = { "oscclk", "dout_peri_ip" };
|
||||
|
||||
static const struct samsung_mux_clock peri_mux_clks[] __initconst = {
|
||||
MUX(CLK_MOUT_PERI_BUS_USER, "mout_peri_bus_user", mout_peri_bus_user_p,
|
||||
PLL_CON0_MUX_CLKCMU_PERI_BUS_USER, 4, 1),
|
||||
MUX(CLK_MOUT_PERI_UART_USER, "mout_peri_uart_user",
|
||||
mout_peri_uart_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART_USER, 4, 1),
|
||||
MUX(CLK_MOUT_PERI_HSI2C_USER, "mout_peri_hsi2c_user",
|
||||
mout_peri_hsi2c_user_p, PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER, 4, 1),
|
||||
MUX(CLK_MOUT_PERI_SPI_USER, "mout_peri_spi_user", mout_peri_spi_user_p,
|
||||
PLL_CON0_MUX_CLKCMU_PERI_SPI_USER, 4, 1),
|
||||
};
|
||||
|
||||
static const struct samsung_div_clock peri_div_clks[] __initconst = {
|
||||
DIV(CLK_DOUT_PERI_HSI2C0, "dout_peri_hsi2c0", "gout_peri_hsi2c0",
|
||||
CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0, 0, 5),
|
||||
DIV(CLK_DOUT_PERI_HSI2C1, "dout_peri_hsi2c1", "gout_peri_hsi2c1",
|
||||
CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1, 0, 5),
|
||||
DIV(CLK_DOUT_PERI_HSI2C2, "dout_peri_hsi2c2", "gout_peri_hsi2c2",
|
||||
CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2, 0, 5),
|
||||
DIV(CLK_DOUT_PERI_SPI0, "dout_peri_spi0", "mout_peri_spi_user",
|
||||
CLK_CON_DIV_DIV_CLK_PERI_SPI_0, 0, 5),
|
||||
};
|
||||
|
||||
static const struct samsung_gate_clock peri_gate_clks[] __initconst = {
|
||||
GATE(CLK_GOUT_PERI_HSI2C0, "gout_peri_hsi2c0", "mout_peri_hsi2c_user",
|
||||
CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0, 21, 0, 0),
|
||||
GATE(CLK_GOUT_PERI_HSI2C1, "gout_peri_hsi2c1", "mout_peri_hsi2c_user",
|
||||
CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1, 21, 0, 0),
|
||||
GATE(CLK_GOUT_PERI_HSI2C2, "gout_peri_hsi2c2", "mout_peri_hsi2c_user",
|
||||
CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2, 21, 0, 0),
|
||||
GATE(CLK_GOUT_HSI2C0_IPCLK, "gout_hsi2c0_ipclk", "dout_peri_hsi2c0",
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_HSI2C0_PCLK, "gout_hsi2c0_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_HSI2C1_IPCLK, "gout_hsi2c1_ipclk", "dout_peri_hsi2c1",
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_HSI2C1_PCLK, "gout_hsi2c1_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_HSI2C2_IPCLK, "gout_hsi2c2_ipclk", "dout_peri_hsi2c2",
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_HSI2C2_PCLK, "gout_hsi2c2_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_I2C0_PCLK, "gout_i2c0_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_I2C1_PCLK, "gout_i2c1_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_I2C2_PCLK, "gout_i2c2_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_I2C3_PCLK, "gout_i2c3_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_I2C4_PCLK, "gout_i2c4_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_I2C5_PCLK, "gout_i2c5_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_I2C6_PCLK, "gout_i2c6_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_MCT_PCLK, "gout_mct_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_MCT_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_PWM_MOTOR_PCLK, "gout_pwm_motor_pclk",
|
||||
"mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_SPI0_IPCLK, "gout_spi0_ipclk", "dout_peri_spi0",
|
||||
CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_SPI0_PCLK, "gout_spi0_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_SYSREG_PERI_PCLK, "gout_sysreg_peri_pclk",
|
||||
"mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_UART_IPCLK, "gout_uart_ipclk", "mout_peri_uart_user",
|
||||
CLK_CON_GAT_GOUT_PERI_UART_IPCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_UART_PCLK, "gout_uart_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_UART_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_WDT0_PCLK, "gout_wdt0_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_WDT1_PCLK, "gout_wdt1_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_GPIO_PERI_PCLK, "gout_gpio_peri_pclk",
|
||||
"mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK, 21, 0, 0),
|
||||
};
|
||||
|
||||
static const struct samsung_cmu_info peri_cmu_info __initconst = {
|
||||
.mux_clks = peri_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(peri_mux_clks),
|
||||
.div_clks = peri_div_clks,
|
||||
.nr_div_clks = ARRAY_SIZE(peri_div_clks),
|
||||
.gate_clks = peri_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(peri_gate_clks),
|
||||
.nr_clk_ids = PERI_NR_CLK,
|
||||
.clk_regs = peri_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(peri_clk_regs),
|
||||
.clk_name = "dout_peri_bus",
|
||||
};
|
||||
|
||||
/* ---- CMU_CORE ------------------------------------------------------------ */
|
||||
|
||||
/* Register Offset definitions for CMU_CORE (0x12000000) */
|
||||
#define PLL_CON0_MUX_CLKCMU_CORE_BUS_USER 0x0600
|
||||
#define PLL_CON0_MUX_CLKCMU_CORE_CCI_USER 0x0610
|
||||
#define PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER 0x0620
|
||||
#define PLL_CON0_MUX_CLKCMU_CORE_SSS_USER 0x0630
|
||||
#define CLK_CON_MUX_MUX_CLK_CORE_GIC 0x1000
|
||||
#define CLK_CON_DIV_DIV_CLK_CORE_BUSP 0x1800
|
||||
#define CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK 0x2038
|
||||
#define CLK_CON_GAT_GOUT_CORE_GIC_CLK 0x2040
|
||||
#define CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK 0x20e8
|
||||
#define CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN 0x20ec
|
||||
#define CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK 0x2128
|
||||
#define CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK 0x212c
|
||||
|
||||
static const unsigned long core_clk_regs[] __initconst = {
|
||||
PLL_CON0_MUX_CLKCMU_CORE_BUS_USER,
|
||||
PLL_CON0_MUX_CLKCMU_CORE_CCI_USER,
|
||||
PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER,
|
||||
PLL_CON0_MUX_CLKCMU_CORE_SSS_USER,
|
||||
CLK_CON_MUX_MUX_CLK_CORE_GIC,
|
||||
CLK_CON_DIV_DIV_CLK_CORE_BUSP,
|
||||
CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK,
|
||||
CLK_CON_GAT_GOUT_CORE_GIC_CLK,
|
||||
CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK,
|
||||
CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN,
|
||||
CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK,
|
||||
CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK,
|
||||
};
|
||||
|
||||
/* List of parent clocks for Muxes in CMU_CORE */
|
||||
PNAME(mout_core_bus_user_p) = { "oscclk", "dout_core_bus" };
|
||||
PNAME(mout_core_cci_user_p) = { "oscclk", "dout_core_cci" };
|
||||
PNAME(mout_core_mmc_embd_user_p) = { "oscclk", "dout_core_mmc_embd" };
|
||||
PNAME(mout_core_sss_user_p) = { "oscclk", "dout_core_sss" };
|
||||
PNAME(mout_core_gic_p) = { "dout_core_busp", "oscclk" };
|
||||
|
||||
static const struct samsung_mux_clock core_mux_clks[] __initconst = {
|
||||
MUX(CLK_MOUT_CORE_BUS_USER, "mout_core_bus_user", mout_core_bus_user_p,
|
||||
PLL_CON0_MUX_CLKCMU_CORE_BUS_USER, 4, 1),
|
||||
MUX(CLK_MOUT_CORE_CCI_USER, "mout_core_cci_user", mout_core_cci_user_p,
|
||||
PLL_CON0_MUX_CLKCMU_CORE_CCI_USER, 4, 1),
|
||||
MUX_F(CLK_MOUT_CORE_MMC_EMBD_USER, "mout_core_mmc_embd_user",
|
||||
mout_core_mmc_embd_user_p, PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER,
|
||||
4, 1, CLK_SET_RATE_PARENT, 0),
|
||||
MUX(CLK_MOUT_CORE_SSS_USER, "mout_core_sss_user", mout_core_sss_user_p,
|
||||
PLL_CON0_MUX_CLKCMU_CORE_SSS_USER, 4, 1),
|
||||
MUX(CLK_MOUT_CORE_GIC, "mout_core_gic", mout_core_gic_p,
|
||||
CLK_CON_MUX_MUX_CLK_CORE_GIC, 0, 1),
|
||||
};
|
||||
|
||||
static const struct samsung_div_clock core_div_clks[] __initconst = {
|
||||
DIV(CLK_DOUT_CORE_BUSP, "dout_core_busp", "mout_core_bus_user",
|
||||
CLK_CON_DIV_DIV_CLK_CORE_BUSP, 0, 2),
|
||||
};
|
||||
|
||||
static const struct samsung_gate_clock core_gate_clks[] __initconst = {
|
||||
GATE(CLK_GOUT_CCI_ACLK, "gout_cci_aclk", "mout_core_cci_user",
|
||||
CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_GIC_CLK, "gout_gic_clk", "mout_core_gic",
|
||||
CLK_CON_GAT_GOUT_CORE_GIC_CLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_MMC_EMBD_ACLK, "gout_mmc_embd_aclk", "dout_core_busp",
|
||||
CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_MMC_EMBD_SDCLKIN, "gout_mmc_embd_sdclkin",
|
||||
"mout_core_mmc_embd_user", CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN,
|
||||
21, CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_SSS_ACLK, "gout_sss_aclk", "mout_core_sss_user",
|
||||
CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_SSS_PCLK, "gout_sss_pclk", "dout_core_busp",
|
||||
CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK, 21, 0, 0),
|
||||
};
|
||||
|
||||
static const struct samsung_cmu_info core_cmu_info __initconst = {
|
||||
.mux_clks = core_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(core_mux_clks),
|
||||
.div_clks = core_div_clks,
|
||||
.nr_div_clks = ARRAY_SIZE(core_div_clks),
|
||||
.gate_clks = core_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(core_gate_clks),
|
||||
.nr_clk_ids = CORE_NR_CLK,
|
||||
.clk_regs = core_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(core_clk_regs),
|
||||
.clk_name = "dout_core_bus",
|
||||
};
|
||||
|
||||
/* ---- CMU_DPU ------------------------------------------------------------- */
|
||||
|
||||
/* Register Offset definitions for CMU_DPU (0x13000000) */
|
||||
#define PLL_CON0_MUX_CLKCMU_DPU_USER 0x0600
|
||||
#define CLK_CON_DIV_DIV_CLK_DPU_BUSP 0x1800
|
||||
#define CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK 0x2004
|
||||
#define CLK_CON_GAT_GOUT_DPU_ACLK_DECON0 0x2010
|
||||
#define CLK_CON_GAT_GOUT_DPU_ACLK_DMA 0x2014
|
||||
#define CLK_CON_GAT_GOUT_DPU_ACLK_DPP 0x2018
|
||||
#define CLK_CON_GAT_GOUT_DPU_PPMU_ACLK 0x2028
|
||||
#define CLK_CON_GAT_GOUT_DPU_PPMU_PCLK 0x202c
|
||||
#define CLK_CON_GAT_GOUT_DPU_SMMU_CLK 0x2038
|
||||
#define CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK 0x203c
|
||||
|
||||
static const unsigned long dpu_clk_regs[] __initconst = {
|
||||
PLL_CON0_MUX_CLKCMU_DPU_USER,
|
||||
CLK_CON_DIV_DIV_CLK_DPU_BUSP,
|
||||
CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK,
|
||||
CLK_CON_GAT_GOUT_DPU_ACLK_DECON0,
|
||||
CLK_CON_GAT_GOUT_DPU_ACLK_DMA,
|
||||
CLK_CON_GAT_GOUT_DPU_ACLK_DPP,
|
||||
CLK_CON_GAT_GOUT_DPU_PPMU_ACLK,
|
||||
CLK_CON_GAT_GOUT_DPU_PPMU_PCLK,
|
||||
CLK_CON_GAT_GOUT_DPU_SMMU_CLK,
|
||||
CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK,
|
||||
};
|
||||
|
||||
/* List of parent clocks for Muxes in CMU_CORE */
|
||||
PNAME(mout_dpu_user_p) = { "oscclk", "dout_dpu" };
|
||||
|
||||
static const struct samsung_mux_clock dpu_mux_clks[] __initconst = {
|
||||
MUX(CLK_MOUT_DPU_USER, "mout_dpu_user", mout_dpu_user_p,
|
||||
PLL_CON0_MUX_CLKCMU_DPU_USER, 4, 1),
|
||||
};
|
||||
|
||||
static const struct samsung_div_clock dpu_div_clks[] __initconst = {
|
||||
DIV(CLK_DOUT_DPU_BUSP, "dout_dpu_busp", "mout_dpu_user",
|
||||
CLK_CON_DIV_DIV_CLK_DPU_BUSP, 0, 3),
|
||||
};
|
||||
|
||||
static const struct samsung_gate_clock dpu_gate_clks[] __initconst = {
|
||||
GATE(CLK_GOUT_DPU_CMU_DPU_PCLK, "gout_dpu_cmu_dpu_pclk",
|
||||
"dout_dpu_busp", CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_DPU_DECON0_ACLK, "gout_dpu_decon0_aclk", "mout_dpu_user",
|
||||
CLK_CON_GAT_GOUT_DPU_ACLK_DECON0, 21, 0, 0),
|
||||
GATE(CLK_GOUT_DPU_DMA_ACLK, "gout_dpu_dma_aclk", "mout_dpu_user",
|
||||
CLK_CON_GAT_GOUT_DPU_ACLK_DMA, 21, 0, 0),
|
||||
GATE(CLK_GOUT_DPU_DPP_ACLK, "gout_dpu_dpp_aclk", "mout_dpu_user",
|
||||
CLK_CON_GAT_GOUT_DPU_ACLK_DPP, 21, 0, 0),
|
||||
GATE(CLK_GOUT_DPU_PPMU_ACLK, "gout_dpu_ppmu_aclk", "mout_dpu_user",
|
||||
CLK_CON_GAT_GOUT_DPU_PPMU_ACLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_DPU_PPMU_PCLK, "gout_dpu_ppmu_pclk", "dout_dpu_busp",
|
||||
CLK_CON_GAT_GOUT_DPU_PPMU_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_DPU_SMMU_CLK, "gout_dpu_smmu_clk", "mout_dpu_user",
|
||||
CLK_CON_GAT_GOUT_DPU_SMMU_CLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_DPU_SYSREG_PCLK, "gout_dpu_sysreg_pclk", "dout_dpu_busp",
|
||||
CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK, 21, 0, 0),
|
||||
};
|
||||
|
||||
static const struct samsung_cmu_info dpu_cmu_info __initconst = {
|
||||
.mux_clks = dpu_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(dpu_mux_clks),
|
||||
.div_clks = dpu_div_clks,
|
||||
.nr_div_clks = ARRAY_SIZE(dpu_div_clks),
|
||||
.gate_clks = dpu_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(dpu_gate_clks),
|
||||
.nr_clk_ids = DPU_NR_CLK,
|
||||
.clk_regs = dpu_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(dpu_clk_regs),
|
||||
.clk_name = "dout_dpu",
|
||||
};
|
||||
|
||||
/* ---- platform_driver ----------------------------------------------------- */
|
||||
|
||||
static int __init exynos850_cmu_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct samsung_cmu_info *info;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
|
||||
info = of_device_get_match_data(dev);
|
||||
exynos850_init_clocks(np, info->clk_regs, info->nr_clk_regs);
|
||||
samsung_cmu_register_one(np, info);
|
||||
|
||||
/* Keep bus clock running, so it's possible to access CMU registers */
|
||||
if (info->clk_name) {
|
||||
struct clk *bus_clk;
|
||||
|
||||
bus_clk = clk_get(dev, info->clk_name);
|
||||
if (IS_ERR(bus_clk)) {
|
||||
pr_err("%s: could not find bus clock %s; err = %ld\n",
|
||||
__func__, info->clk_name, PTR_ERR(bus_clk));
|
||||
} else {
|
||||
clk_prepare_enable(bus_clk);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* CMUs which belong to Power Domains and need runtime PM to be implemented */
|
||||
static const struct of_device_id exynos850_cmu_of_match[] = {
|
||||
{
|
||||
.compatible = "samsung,exynos850-cmu-hsi",
|
||||
.data = &hsi_cmu_info,
|
||||
}, {
|
||||
.compatible = "samsung,exynos850-cmu-peri",
|
||||
.data = &peri_cmu_info,
|
||||
}, {
|
||||
.compatible = "samsung,exynos850-cmu-core",
|
||||
.data = &core_cmu_info,
|
||||
}, {
|
||||
.compatible = "samsung,exynos850-cmu-dpu",
|
||||
.data = &dpu_cmu_info,
|
||||
}, {
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_driver exynos850_cmu_driver __refdata = {
|
||||
.driver = {
|
||||
.name = "exynos850-cmu",
|
||||
.of_match_table = exynos850_cmu_of_match,
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
.probe = exynos850_cmu_probe,
|
||||
};
|
||||
|
||||
static int __init exynos850_cmu_init(void)
|
||||
{
|
||||
return platform_driver_register(&exynos850_cmu_driver);
|
||||
}
|
||||
core_initcall(exynos850_cmu_init);
|
|
@ -415,6 +415,186 @@ static const struct clk_ops samsung_pll36xx_clk_min_ops = {
|
|||
.recalc_rate = samsung_pll36xx_recalc_rate,
|
||||
};
|
||||
|
||||
/*
|
||||
* PLL0822x Clock Type
|
||||
*/
|
||||
/* Maximum lock time can be 150 * PDIV cycles */
|
||||
#define PLL0822X_LOCK_FACTOR (150)
|
||||
|
||||
#define PLL0822X_MDIV_MASK (0x3FF)
|
||||
#define PLL0822X_PDIV_MASK (0x3F)
|
||||
#define PLL0822X_SDIV_MASK (0x7)
|
||||
#define PLL0822X_MDIV_SHIFT (16)
|
||||
#define PLL0822X_PDIV_SHIFT (8)
|
||||
#define PLL0822X_SDIV_SHIFT (0)
|
||||
#define PLL0822X_LOCK_STAT_SHIFT (29)
|
||||
#define PLL0822X_ENABLE_SHIFT (31)
|
||||
|
||||
static unsigned long samsung_pll0822x_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 mdiv, pdiv, sdiv, pll_con3;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_con3 = readl_relaxed(pll->con_reg);
|
||||
mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL0822X_MDIV_MASK;
|
||||
pdiv = (pll_con3 >> PLL0822X_PDIV_SHIFT) & PLL0822X_PDIV_MASK;
|
||||
sdiv = (pll_con3 >> PLL0822X_SDIV_SHIFT) & PLL0822X_SDIV_MASK;
|
||||
|
||||
fvco *= mdiv;
|
||||
do_div(fvco, (pdiv << sdiv));
|
||||
|
||||
return (unsigned long)fvco;
|
||||
}
|
||||
|
||||
static int samsung_pll0822x_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
unsigned long prate)
|
||||
{
|
||||
const struct samsung_pll_rate_table *rate;
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 pll_con3;
|
||||
|
||||
/* Get required rate settings from table */
|
||||
rate = samsung_get_pll_settings(pll, drate);
|
||||
if (!rate) {
|
||||
pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
|
||||
drate, clk_hw_get_name(hw));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Change PLL PMS values */
|
||||
pll_con3 = readl_relaxed(pll->con_reg);
|
||||
pll_con3 &= ~((PLL0822X_MDIV_MASK << PLL0822X_MDIV_SHIFT) |
|
||||
(PLL0822X_PDIV_MASK << PLL0822X_PDIV_SHIFT) |
|
||||
(PLL0822X_SDIV_MASK << PLL0822X_SDIV_SHIFT));
|
||||
pll_con3 |= (rate->mdiv << PLL0822X_MDIV_SHIFT) |
|
||||
(rate->pdiv << PLL0822X_PDIV_SHIFT) |
|
||||
(rate->sdiv << PLL0822X_SDIV_SHIFT);
|
||||
|
||||
/* Set PLL lock time */
|
||||
writel_relaxed(rate->pdiv * PLL0822X_LOCK_FACTOR,
|
||||
pll->lock_reg);
|
||||
|
||||
/* Write PMS values */
|
||||
writel_relaxed(pll_con3, pll->con_reg);
|
||||
|
||||
/* Wait for PLL lock if the PLL is enabled */
|
||||
if (pll_con3 & BIT(pll->enable_offs))
|
||||
return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops samsung_pll0822x_clk_ops = {
|
||||
.recalc_rate = samsung_pll0822x_recalc_rate,
|
||||
.round_rate = samsung_pll_round_rate,
|
||||
.set_rate = samsung_pll0822x_set_rate,
|
||||
.enable = samsung_pll3xxx_enable,
|
||||
.disable = samsung_pll3xxx_disable,
|
||||
};
|
||||
|
||||
static const struct clk_ops samsung_pll0822x_clk_min_ops = {
|
||||
.recalc_rate = samsung_pll0822x_recalc_rate,
|
||||
};
|
||||
|
||||
/*
|
||||
* PLL0831x Clock Type
|
||||
*/
|
||||
/* Maximum lock time can be 500 * PDIV cycles */
|
||||
#define PLL0831X_LOCK_FACTOR (500)
|
||||
|
||||
#define PLL0831X_KDIV_MASK (0xFFFF)
|
||||
#define PLL0831X_MDIV_MASK (0x1FF)
|
||||
#define PLL0831X_PDIV_MASK (0x3F)
|
||||
#define PLL0831X_SDIV_MASK (0x7)
|
||||
#define PLL0831X_MDIV_SHIFT (16)
|
||||
#define PLL0831X_PDIV_SHIFT (8)
|
||||
#define PLL0831X_SDIV_SHIFT (0)
|
||||
#define PLL0831X_KDIV_SHIFT (0)
|
||||
#define PLL0831X_LOCK_STAT_SHIFT (29)
|
||||
#define PLL0831X_ENABLE_SHIFT (31)
|
||||
|
||||
static unsigned long samsung_pll0831x_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 mdiv, pdiv, sdiv, pll_con3, pll_con5;
|
||||
s16 kdiv;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_con3 = readl_relaxed(pll->con_reg);
|
||||
pll_con5 = readl_relaxed(pll->con_reg + 8);
|
||||
mdiv = (pll_con3 >> PLL0831X_MDIV_SHIFT) & PLL0831X_MDIV_MASK;
|
||||
pdiv = (pll_con3 >> PLL0831X_PDIV_SHIFT) & PLL0831X_PDIV_MASK;
|
||||
sdiv = (pll_con3 >> PLL0831X_SDIV_SHIFT) & PLL0831X_SDIV_MASK;
|
||||
kdiv = (s16)((pll_con5 >> PLL0831X_KDIV_SHIFT) & PLL0831X_KDIV_MASK);
|
||||
|
||||
fvco *= (mdiv << 16) + kdiv;
|
||||
do_div(fvco, (pdiv << sdiv));
|
||||
fvco >>= 16;
|
||||
|
||||
return (unsigned long)fvco;
|
||||
}
|
||||
|
||||
static int samsung_pll0831x_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
const struct samsung_pll_rate_table *rate;
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 pll_con3, pll_con5;
|
||||
|
||||
/* Get required rate settings from table */
|
||||
rate = samsung_get_pll_settings(pll, drate);
|
||||
if (!rate) {
|
||||
pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
|
||||
drate, clk_hw_get_name(hw));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pll_con3 = readl_relaxed(pll->con_reg);
|
||||
pll_con5 = readl_relaxed(pll->con_reg + 8);
|
||||
|
||||
/* Change PLL PMSK values */
|
||||
pll_con3 &= ~((PLL0831X_MDIV_MASK << PLL0831X_MDIV_SHIFT) |
|
||||
(PLL0831X_PDIV_MASK << PLL0831X_PDIV_SHIFT) |
|
||||
(PLL0831X_SDIV_MASK << PLL0831X_SDIV_SHIFT));
|
||||
pll_con3 |= (rate->mdiv << PLL0831X_MDIV_SHIFT) |
|
||||
(rate->pdiv << PLL0831X_PDIV_SHIFT) |
|
||||
(rate->sdiv << PLL0831X_SDIV_SHIFT);
|
||||
pll_con5 &= ~(PLL0831X_KDIV_MASK << PLL0831X_KDIV_SHIFT);
|
||||
/*
|
||||
* kdiv is 16-bit 2's complement (s16), but stored as unsigned int.
|
||||
* Cast it to u16 to avoid leading 0xffff's in case of negative value.
|
||||
*/
|
||||
pll_con5 |= ((u16)rate->kdiv << PLL0831X_KDIV_SHIFT);
|
||||
|
||||
/* Set PLL lock time */
|
||||
writel_relaxed(rate->pdiv * PLL0831X_LOCK_FACTOR, pll->lock_reg);
|
||||
|
||||
/* Write PMSK values */
|
||||
writel_relaxed(pll_con3, pll->con_reg);
|
||||
writel_relaxed(pll_con5, pll->con_reg + 8);
|
||||
|
||||
/* Wait for PLL lock if the PLL is enabled */
|
||||
if (pll_con3 & BIT(pll->enable_offs))
|
||||
return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops samsung_pll0831x_clk_ops = {
|
||||
.recalc_rate = samsung_pll0831x_recalc_rate,
|
||||
.set_rate = samsung_pll0831x_set_rate,
|
||||
.round_rate = samsung_pll_round_rate,
|
||||
.enable = samsung_pll3xxx_enable,
|
||||
.disable = samsung_pll3xxx_disable,
|
||||
};
|
||||
|
||||
static const struct clk_ops samsung_pll0831x_clk_min_ops = {
|
||||
.recalc_rate = samsung_pll0831x_recalc_rate,
|
||||
};
|
||||
|
||||
/*
|
||||
* PLL45xx Clock Type
|
||||
*/
|
||||
|
@ -1296,6 +1476,14 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
|
|||
else
|
||||
init.ops = &samsung_pll35xx_clk_ops;
|
||||
break;
|
||||
case pll_0822x:
|
||||
pll->enable_offs = PLL0822X_ENABLE_SHIFT;
|
||||
pll->lock_offs = PLL0822X_LOCK_STAT_SHIFT;
|
||||
if (!pll->rate_table)
|
||||
init.ops = &samsung_pll0822x_clk_min_ops;
|
||||
else
|
||||
init.ops = &samsung_pll0822x_clk_ops;
|
||||
break;
|
||||
case pll_4500:
|
||||
init.ops = &samsung_pll45xx_clk_min_ops;
|
||||
break;
|
||||
|
@ -1316,6 +1504,14 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
|
|||
else
|
||||
init.ops = &samsung_pll36xx_clk_ops;
|
||||
break;
|
||||
case pll_0831x:
|
||||
pll->enable_offs = PLL0831X_ENABLE_SHIFT;
|
||||
pll->lock_offs = PLL0831X_LOCK_STAT_SHIFT;
|
||||
if (!pll->rate_table)
|
||||
init.ops = &samsung_pll0831x_clk_min_ops;
|
||||
else
|
||||
init.ops = &samsung_pll0831x_clk_ops;
|
||||
break;
|
||||
case pll_6552:
|
||||
case pll_6552_s3c2416:
|
||||
init.ops = &samsung_pll6552_clk_ops;
|
||||
|
|
|
@ -36,6 +36,8 @@ enum samsung_pll_type {
|
|||
pll_1451x,
|
||||
pll_1452x,
|
||||
pll_1460x,
|
||||
pll_0822x,
|
||||
pll_0831x,
|
||||
};
|
||||
|
||||
#define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \
|
||||
|
|
|
@ -63,15 +63,13 @@ static struct syscore_ops s5pv210_audss_clk_syscore_ops = {
|
|||
static int s5pv210_audss_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
int i, ret = 0;
|
||||
struct resource *res;
|
||||
const char *mout_audss_p[2];
|
||||
const char *mout_i2s_p[3];
|
||||
const char *hclk_p;
|
||||
struct clk_hw **clk_table;
|
||||
struct clk *hclk, *pll_ref, *pll_in, *cdclk, *sclk_audio;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
reg_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg_base))
|
||||
return PTR_ERR(reg_base);
|
||||
|
||||
|
|
|
@ -378,6 +378,8 @@ struct samsung_clk_provider * __init samsung_cmu_register_one(
|
|||
samsung_clk_extended_sleep_init(reg_base,
|
||||
cmu->clk_regs, cmu->nr_clk_regs,
|
||||
cmu->suspend_regs, cmu->nr_suspend_regs);
|
||||
if (cmu->cpu_clks)
|
||||
samsung_clk_register_cpu(ctx, cmu->cpu_clks, cmu->nr_cpu_clks);
|
||||
|
||||
samsung_clk_of_add_provider(np, ctx);
|
||||
|
||||
|
|
|
@ -271,6 +271,27 @@ struct samsung_pll_clock {
|
|||
__PLL(_typ, _id, _name, _pname, CLK_GET_RATE_NOCACHE, _lock, \
|
||||
_con, _rtable)
|
||||
|
||||
struct samsung_cpu_clock {
|
||||
unsigned int id;
|
||||
const char *name;
|
||||
unsigned int parent_id;
|
||||
unsigned int alt_parent_id;
|
||||
unsigned long flags;
|
||||
int offset;
|
||||
const struct exynos_cpuclk_cfg_data *cfg;
|
||||
};
|
||||
|
||||
#define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _cfg) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_id = _pid, \
|
||||
.alt_parent_id = _apid, \
|
||||
.flags = _flags, \
|
||||
.offset = _offset, \
|
||||
.cfg = _cfg, \
|
||||
}
|
||||
|
||||
struct samsung_clock_reg_cache {
|
||||
struct list_head node;
|
||||
void __iomem *reg_base;
|
||||
|
@ -301,6 +322,9 @@ struct samsung_cmu_info {
|
|||
unsigned int nr_fixed_factor_clks;
|
||||
/* total number of clocks with IDs assigned*/
|
||||
unsigned int nr_clk_ids;
|
||||
/* list of cpu clocks and respective count */
|
||||
const struct samsung_cpu_clock *cpu_clks;
|
||||
unsigned int nr_cpu_clks;
|
||||
|
||||
/* list and number of clocks registers */
|
||||
const unsigned long *clk_regs;
|
||||
|
@ -350,6 +374,8 @@ extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
|
|||
extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
|
||||
const struct samsung_pll_clock *pll_list,
|
||||
unsigned int nr_clk, void __iomem *base);
|
||||
extern void samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
|
||||
const struct samsung_cpu_clock *list, unsigned int nr_clk);
|
||||
|
||||
extern struct samsung_clk_provider __init *samsung_cmu_register_one(
|
||||
struct device_node *,
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
/*
|
||||
* Copyright (C) 2021 Linaro Ltd.
|
||||
* Author: Sam Protsenko <semen.protsenko@linaro.org>
|
||||
*
|
||||
* Device Tree binding constants for Exynos850 clock controller.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLOCK_EXYNOS_850_H
|
||||
#define _DT_BINDINGS_CLOCK_EXYNOS_850_H
|
||||
|
||||
/* CMU_TOP */
|
||||
#define CLK_FOUT_SHARED0_PLL 1
|
||||
#define CLK_FOUT_SHARED1_PLL 2
|
||||
#define CLK_FOUT_MMC_PLL 3
|
||||
#define CLK_MOUT_SHARED0_PLL 4
|
||||
#define CLK_MOUT_SHARED1_PLL 5
|
||||
#define CLK_MOUT_MMC_PLL 6
|
||||
#define CLK_MOUT_CORE_BUS 7
|
||||
#define CLK_MOUT_CORE_CCI 8
|
||||
#define CLK_MOUT_CORE_MMC_EMBD 9
|
||||
#define CLK_MOUT_CORE_SSS 10
|
||||
#define CLK_MOUT_DPU 11
|
||||
#define CLK_MOUT_HSI_BUS 12
|
||||
#define CLK_MOUT_HSI_MMC_CARD 13
|
||||
#define CLK_MOUT_HSI_USB20DRD 14
|
||||
#define CLK_MOUT_PERI_BUS 15
|
||||
#define CLK_MOUT_PERI_UART 16
|
||||
#define CLK_MOUT_PERI_IP 17
|
||||
#define CLK_DOUT_SHARED0_DIV3 18
|
||||
#define CLK_DOUT_SHARED0_DIV2 19
|
||||
#define CLK_DOUT_SHARED1_DIV3 20
|
||||
#define CLK_DOUT_SHARED1_DIV2 21
|
||||
#define CLK_DOUT_SHARED0_DIV4 22
|
||||
#define CLK_DOUT_SHARED1_DIV4 23
|
||||
#define CLK_DOUT_CORE_BUS 24
|
||||
#define CLK_DOUT_CORE_CCI 25
|
||||
#define CLK_DOUT_CORE_MMC_EMBD 26
|
||||
#define CLK_DOUT_CORE_SSS 27
|
||||
#define CLK_DOUT_DPU 28
|
||||
#define CLK_DOUT_HSI_BUS 29
|
||||
#define CLK_DOUT_HSI_MMC_CARD 30
|
||||
#define CLK_DOUT_HSI_USB20DRD 31
|
||||
#define CLK_DOUT_PERI_BUS 32
|
||||
#define CLK_DOUT_PERI_UART 33
|
||||
#define CLK_DOUT_PERI_IP 34
|
||||
#define CLK_GOUT_CORE_BUS 35
|
||||
#define CLK_GOUT_CORE_CCI 36
|
||||
#define CLK_GOUT_CORE_MMC_EMBD 37
|
||||
#define CLK_GOUT_CORE_SSS 38
|
||||
#define CLK_GOUT_DPU 39
|
||||
#define CLK_GOUT_HSI_BUS 40
|
||||
#define CLK_GOUT_HSI_MMC_CARD 41
|
||||
#define CLK_GOUT_HSI_USB20DRD 42
|
||||
#define CLK_GOUT_PERI_BUS 43
|
||||
#define CLK_GOUT_PERI_UART 44
|
||||
#define CLK_GOUT_PERI_IP 45
|
||||
#define TOP_NR_CLK 46
|
||||
|
||||
/* CMU_HSI */
|
||||
#define CLK_MOUT_HSI_BUS_USER 1
|
||||
#define CLK_MOUT_HSI_MMC_CARD_USER 2
|
||||
#define CLK_MOUT_HSI_USB20DRD_USER 3
|
||||
#define CLK_MOUT_HSI_RTC 4
|
||||
#define CLK_GOUT_USB_RTC_CLK 5
|
||||
#define CLK_GOUT_USB_REF_CLK 6
|
||||
#define CLK_GOUT_USB_PHY_REF_CLK 7
|
||||
#define CLK_GOUT_USB_PHY_ACLK 8
|
||||
#define CLK_GOUT_USB_BUS_EARLY_CLK 9
|
||||
#define CLK_GOUT_GPIO_HSI_PCLK 10
|
||||
#define CLK_GOUT_MMC_CARD_ACLK 11
|
||||
#define CLK_GOUT_MMC_CARD_SDCLKIN 12
|
||||
#define CLK_GOUT_SYSREG_HSI_PCLK 13
|
||||
#define HSI_NR_CLK 14
|
||||
|
||||
/* CMU_PERI */
|
||||
#define CLK_MOUT_PERI_BUS_USER 1
|
||||
#define CLK_MOUT_PERI_UART_USER 2
|
||||
#define CLK_MOUT_PERI_HSI2C_USER 3
|
||||
#define CLK_MOUT_PERI_SPI_USER 4
|
||||
#define CLK_DOUT_PERI_HSI2C0 5
|
||||
#define CLK_DOUT_PERI_HSI2C1 6
|
||||
#define CLK_DOUT_PERI_HSI2C2 7
|
||||
#define CLK_DOUT_PERI_SPI0 8
|
||||
#define CLK_GOUT_PERI_HSI2C0 9
|
||||
#define CLK_GOUT_PERI_HSI2C1 10
|
||||
#define CLK_GOUT_PERI_HSI2C2 11
|
||||
#define CLK_GOUT_GPIO_PERI_PCLK 12
|
||||
#define CLK_GOUT_HSI2C0_IPCLK 13
|
||||
#define CLK_GOUT_HSI2C0_PCLK 14
|
||||
#define CLK_GOUT_HSI2C1_IPCLK 15
|
||||
#define CLK_GOUT_HSI2C1_PCLK 16
|
||||
#define CLK_GOUT_HSI2C2_IPCLK 17
|
||||
#define CLK_GOUT_HSI2C2_PCLK 18
|
||||
#define CLK_GOUT_I2C0_PCLK 19
|
||||
#define CLK_GOUT_I2C1_PCLK 20
|
||||
#define CLK_GOUT_I2C2_PCLK 21
|
||||
#define CLK_GOUT_I2C3_PCLK 22
|
||||
#define CLK_GOUT_I2C4_PCLK 23
|
||||
#define CLK_GOUT_I2C5_PCLK 24
|
||||
#define CLK_GOUT_I2C6_PCLK 25
|
||||
#define CLK_GOUT_MCT_PCLK 26
|
||||
#define CLK_GOUT_PWM_MOTOR_PCLK 27
|
||||
#define CLK_GOUT_SPI0_IPCLK 28
|
||||
#define CLK_GOUT_SPI0_PCLK 29
|
||||
#define CLK_GOUT_SYSREG_PERI_PCLK 30
|
||||
#define CLK_GOUT_UART_IPCLK 31
|
||||
#define CLK_GOUT_UART_PCLK 32
|
||||
#define CLK_GOUT_WDT0_PCLK 33
|
||||
#define CLK_GOUT_WDT1_PCLK 34
|
||||
#define PERI_NR_CLK 35
|
||||
|
||||
/* CMU_CORE */
|
||||
#define CLK_MOUT_CORE_BUS_USER 1
|
||||
#define CLK_MOUT_CORE_CCI_USER 2
|
||||
#define CLK_MOUT_CORE_MMC_EMBD_USER 3
|
||||
#define CLK_MOUT_CORE_SSS_USER 4
|
||||
#define CLK_MOUT_CORE_GIC 5
|
||||
#define CLK_DOUT_CORE_BUSP 6
|
||||
#define CLK_GOUT_CCI_ACLK 7
|
||||
#define CLK_GOUT_GIC_CLK 8
|
||||
#define CLK_GOUT_MMC_EMBD_ACLK 9
|
||||
#define CLK_GOUT_MMC_EMBD_SDCLKIN 10
|
||||
#define CLK_GOUT_SSS_ACLK 11
|
||||
#define CLK_GOUT_SSS_PCLK 12
|
||||
#define CORE_NR_CLK 13
|
||||
|
||||
/* CMU_DPU */
|
||||
#define CLK_MOUT_DPU_USER 1
|
||||
#define CLK_DOUT_DPU_BUSP 2
|
||||
#define CLK_GOUT_DPU_CMU_DPU_PCLK 3
|
||||
#define CLK_GOUT_DPU_DECON0_ACLK 4
|
||||
#define CLK_GOUT_DPU_DMA_ACLK 5
|
||||
#define CLK_GOUT_DPU_DPP_ACLK 6
|
||||
#define CLK_GOUT_DPU_PPMU_ACLK 7
|
||||
#define CLK_GOUT_DPU_PPMU_PCLK 8
|
||||
#define CLK_GOUT_DPU_SMMU_CLK 9
|
||||
#define CLK_GOUT_DPU_SYSREG_PCLK 10
|
||||
#define DPU_NR_CLK 11
|
||||
|
||||
#endif /* _DT_BINDINGS_CLOCK_EXYNOS_850_H */
|
Загрузка…
Ссылка в новой задаче