Commit 4e44a0ba authored by Stephen Boyd's avatar Stephen Boyd

Merge tag 'clk-v5.16-samsung' of...

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()
parents 6880fa6c 9fe667af
# 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 @@ int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
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 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);
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),
};
samsung_clk_sleep_init(reg_base, atlas_clk_regs,
ARRAY_SIZE(atlas_clk_regs));
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),
};
samsung_clk_of_add_provider(np, ctx);
static void __init exynos5433_cmu_atlas_init(struct device_node *np)
{
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);
......
// 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 *,
......
/* 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 */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment