On all Exynos SoCs there is a dedicated CLKOUT pin that allows many of
internal SoC clocks to be output from the SoC. The hardware structure
of CLKOUT related clocks looks as follows:
CMU |---> clock0 ---------> | PMU |
| | |
several |---> clock1 ---------> | mux |
muxes | | + |---> CLKOUT
dividers | ... | gate |
and gates | | |
|---> clockN ---------> | |
Since the block responsible for handling the pin is PMU, not CMU,
a separate driver, that binds to PMU node is required and acquires
all input clocks by standard DT clock look-up. This way we don't need
any cross-IP block drivers and cross-driver register sharing or
nodes for fake devices.
To represent the PMU mux/gate clock, generic composite clock is registered.
Tested on Odroid U3, with HSIC/USB hub using CLKOUT as reference clock,
with some additional patches.
Changes since v1:
(http://www.spinics.net/lists/arm-kernel/msg333276.html)
- rebased onto next-20140624,
- fixed #clock-cells values in exynos5250.dtsi and exynos5420.dtsi,
- temporarily removed ISP CLKOUT clocks on Exynos4x12, until ISP clock
domain handling gets fixed in Exynos4 clock driver.
Changes since RFC v1:
(https://lkml.org/lkml/2014/5/15/506)
- rebased onto v5 of "Enable usbphy and hsotg for exynos4" series and
current HEAD of samsung-clk tree,
- added handling of suspend/resume in the driver,
- added missing CPU clocks on Exynos4,
- added CLK_SET_RATE_PARENT to CMU CLKOUT gates on Exynos4,
- fixed bit field width on Exynos4,
- added CLKOUT CMU registers of Exynos4 to save/restore list,
- added CLK_SET_RATE_PARENT and CLK_SET_RATE_NO_REPARENT to clkout clock,
- changed the binding to use 1-cell clock specifier to allow extension
with further PMU clocks in future, if needed.
Tomasz Figa (4):
clk: samsung: exynos4: Add missing CPU/DMC clock hierarchy
clk: samsung: exynos4: Add CLKOUT clock hierarchy
clk: samsung: Add driver to control CLKOUT line on Exynos SoCs
ARM: dts: exynos: Update PMU node with CLKOUT related data
.../devicetree/bindings/arm/samsung/pmu.txt | 30 ++++
arch/arm/boot/dts/exynos4210.dtsi | 10 ++
arch/arm/boot/dts/exynos4x12.dtsi | 7 +
arch/arm/boot/dts/exynos5250.dtsi | 3 +
arch/arm/boot/dts/exynos5420.dtsi | 3 +
drivers/clk/samsung/Makefile | 1 +
drivers/clk/samsung/clk-exynos-clkout.c | 153 +++++++++++++++++++
drivers/clk/samsung/clk-exynos4.c | 166 ++++++++++++++++++++-
include/dt-bindings/clock/exynos4.h | 5 +
9 files changed, 374 insertions(+), 4 deletions(-)
create mode 100644 drivers/clk/samsung/clk-exynos-clkout.c
--
1.9.3
This patch introduces a driver that handles configuration of CLKOUT pin
of Exynos SoCs that can be used to output certain clocks from inside of
the SoC to a dedicated output pin.
Signed-off-by: Tomasz Figa <[email protected]>
---
.../devicetree/bindings/arm/samsung/pmu.txt | 30 ++++
drivers/clk/samsung/Makefile | 1 +
drivers/clk/samsung/clk-exynos-clkout.c | 153 +++++++++++++++++++++
3 files changed, 184 insertions(+)
create mode 100644 drivers/clk/samsung/clk-exynos-clkout.c
diff --git a/Documentation/devicetree/bindings/arm/samsung/pmu.txt b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
index 2a4ab04..f9865e7 100644
--- a/Documentation/devicetree/bindings/arm/samsung/pmu.txt
+++ b/Documentation/devicetree/bindings/arm/samsung/pmu.txt
@@ -12,8 +12,38 @@ Properties:
- reg : offset and length of the register set.
+ - #clock-cells : must be <1>, since PMU requires once cell as clock specifier.
+ The single specifier cell is used as index to list of clocks
+ provided by PMU, which is currently:
+ 0 : SoC clock output (CLKOUT pin)
+
+ - clock-names : list of clock names for particular CLKOUT mux inputs in
+ following format:
+ "clkoutN", where N is a decimal number corresponding to
+ CLKOUT mux control bits value for given input, e.g.
+ "clkout0", "clkout7", "clkout15".
+
+ - clocks : list of phandles and specifiers to all input clocks listed in
+ clock-names property.
+
Example :
pmu_system_controller: system-controller@10040000 {
compatible = "samsung,exynos5250-pmu", "syscon";
reg = <0x10040000 0x5000>;
+ #clock-cells = <1>;
+ clock-names = "clkout0", "clkout1", "clkout2", "clkout3",
+ "clkout4", "clkout8", "clkout9";
+ clocks = <&clock CLK_OUT_DMC>, <&clock CLK_OUT_TOP>,
+ <&clock CLK_OUT_LEFTBUS>, <&clock CLK_OUT_RIGHTBUS>,
+ <&clock CLK_OUT_CPU>, <&clock CLK_XXTI>,
+ <&clock CLK_XUSBXTI>;
+};
+
+Example of clock consumer :
+
+usb3503: usb3503@08 {
+ /* ... */
+ clock-names = "refclk";
+ clocks = <&pmu_system_controller 0>;
+ /* ... */
};
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 69e8177..2949a55 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o
obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o
obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o
+obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-clkout.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
diff --git a/drivers/clk/samsung/clk-exynos-clkout.c b/drivers/clk/samsung/clk-exynos-clkout.c
new file mode 100644
index 0000000..3a7cb25
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos-clkout.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Author: Tomasz Figa <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Clock driver for Exynos clock output
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/syscore_ops.h>
+
+#define EXYNOS_CLKOUT_NR_CLKS 1
+#define EXYNOS_CLKOUT_PARENTS 32
+
+#define EXYNOS_PMU_DEBUG_REG 0xa00
+#define EXYNOS_CLKOUT_DISABLE_SHIFT 0
+#define EXYNOS_CLKOUT_MUX_SHIFT 8
+#define EXYNOS4_CLKOUT_MUX_MASK 0xf
+#define EXYNOS5_CLKOUT_MUX_MASK 0x1f
+
+struct exynos_clkout {
+ struct clk_gate gate;
+ struct clk_mux mux;
+ spinlock_t slock;
+ struct clk_onecell_data data;
+ struct clk *clk_table[EXYNOS_CLKOUT_NR_CLKS];
+ void __iomem *reg;
+ u32 pmu_debug_save;
+};
+
+static struct exynos_clkout *clkout;
+
+static int exynos_clkout_suspend(void)
+{
+ clkout->pmu_debug_save = readl(clkout->reg + EXYNOS_PMU_DEBUG_REG);
+
+ return 0;
+}
+
+static void exynos_clkout_resume(void)
+{
+ writel(clkout->pmu_debug_save, clkout->reg + EXYNOS_PMU_DEBUG_REG);
+}
+
+static struct syscore_ops exynos_clkout_syscore_ops = {
+ .suspend = exynos_clkout_suspend,
+ .resume = exynos_clkout_resume,
+};
+
+static void __init exynos_clkout_init(struct device_node *node, u32 mux_mask)
+{
+ const char *parent_names[EXYNOS_CLKOUT_PARENTS];
+ struct clk *parents[EXYNOS_CLKOUT_PARENTS];
+ int parent_count;
+ int ret;
+ int i;
+
+ clkout = kzalloc(sizeof(*clkout), GFP_KERNEL);
+ if (!clkout)
+ return;
+
+ spin_lock_init(&clkout->slock);
+
+ parent_count = 0;
+ for (i = 0; i < EXYNOS_CLKOUT_PARENTS; ++i) {
+ char name[] = "clkoutXX";
+
+ snprintf(name, sizeof(name), "clkout%d", i);
+ parents[i] = of_clk_get_by_name(node, name);
+ if (IS_ERR(parents[i])) {
+ parent_names[i] = "none";
+ continue;
+ }
+
+ parent_names[i] = __clk_get_name(parents[i]);
+ parent_count = i + 1;
+ }
+
+ if (!parent_count)
+ goto free_clkout;
+
+ clkout->reg = of_iomap(node, 0);
+ if (!clkout->reg)
+ goto clks_put;
+
+ clkout->gate.reg = clkout->reg + EXYNOS_PMU_DEBUG_REG;
+ clkout->gate.bit_idx = EXYNOS_CLKOUT_DISABLE_SHIFT;
+ clkout->gate.flags = CLK_GATE_SET_TO_DISABLE;
+ clkout->gate.lock = &clkout->slock;
+
+ clkout->mux.reg = clkout->reg + EXYNOS_PMU_DEBUG_REG;
+ clkout->mux.mask = mux_mask;
+ clkout->mux.shift = EXYNOS_CLKOUT_MUX_SHIFT;
+ clkout->mux.lock = &clkout->slock;
+
+ clkout->clk_table[0] = clk_register_composite(NULL, "clkout",
+ parent_names, parent_count, &clkout->mux.hw,
+ &clk_mux_ops, NULL, NULL, &clkout->gate.hw,
+ &clk_gate_ops, CLK_SET_RATE_PARENT
+ | CLK_SET_RATE_NO_REPARENT);
+ if (IS_ERR(clkout->clk_table[0]))
+ goto err_unmap;
+
+ clkout->data.clks = clkout->clk_table;
+ clkout->data.clk_num = EXYNOS_CLKOUT_NR_CLKS;
+ ret = of_clk_add_provider(node, of_clk_src_onecell_get, &clkout->data);
+ if (ret)
+ goto err_clk_unreg;
+
+ register_syscore_ops(&exynos_clkout_syscore_ops);
+
+ return;
+
+err_clk_unreg:
+ clk_unregister(clkout->clk_table[0]);
+err_unmap:
+ iounmap(clkout->reg);
+clks_put:
+ for (i = 0; i < EXYNOS_CLKOUT_PARENTS; ++i)
+ if (!IS_ERR(parents[i]))
+ clk_put(parents[i]);
+free_clkout:
+ kfree(clkout);
+
+ pr_err("%s: failed to register clkout clock\n", __func__);
+}
+
+static void __init exynos4_clkout_init(struct device_node *node)
+{
+ exynos_clkout_init(node, EXYNOS4_CLKOUT_MUX_MASK);
+}
+CLK_OF_DECLARE(exynos4210_clkout, "samsung,exynos4210-pmu",
+ exynos4_clkout_init);
+CLK_OF_DECLARE(exynos4212_clkout, "samsung,exynos4212-pmu",
+ exynos4_clkout_init);
+CLK_OF_DECLARE(exynos4412_clkout, "samsung,exynos4412-pmu",
+ exynos4_clkout_init);
+
+static void __init exynos5_clkout_init(struct device_node *node)
+{
+ exynos_clkout_init(node, EXYNOS5_CLKOUT_MUX_MASK);
+}
+CLK_OF_DECLARE(exynos5250_clkout, "samsung,exynos5250-pmu",
+ exynos5_clkout_init);
+CLK_OF_DECLARE(exynos5420_clkout, "samsung,exynos5420-pmu",
+ exynos5_clkout_init);
--
1.9.3
This patch extends nodes of PMU system controller on Exynos4210, 4x12,
5250 and 5420 SoCs with newly defined properties used by Exynos CLKOUT
driver.
Signed-off-by: Tomasz Figa <[email protected]>
---
arch/arm/boot/dts/exynos4210.dtsi | 10 ++++++++++
arch/arm/boot/dts/exynos4x12.dtsi | 7 +++++++
arch/arm/boot/dts/exynos5250.dtsi | 3 +++
arch/arm/boot/dts/exynos5420.dtsi | 3 +++
4 files changed, 23 insertions(+)
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index ee3001f..97ea7a9 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -31,6 +31,16 @@
pinctrl2 = &pinctrl_2;
};
+ pmu_system_controller: system-controller@10020000 {
+ clock-names = "clkout0", "clkout1", "clkout2", "clkout3",
+ "clkout4", "clkout8", "clkout9";
+ clocks = <&clock CLK_OUT_DMC>, <&clock CLK_OUT_TOP>,
+ <&clock CLK_OUT_LEFTBUS>, <&clock CLK_OUT_RIGHTBUS>,
+ <&clock CLK_OUT_CPU>, <&clock CLK_XXTI>,
+ <&clock CLK_XUSBXTI>;
+ #clock-cells = <1>;
+ };
+
sysram@02020000 {
compatible = "mmio-sram";
reg = <0x02020000 0x20000>;
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index c5a943d..de1f9c7 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -139,6 +139,13 @@
pmu_system_controller: system-controller@10020000 {
compatible = "samsung,exynos4212-pmu", "syscon";
+ clock-names = "clkout0", "clkout1", "clkout2", "clkout3",
+ "clkout4", "clkout8", "clkout9";
+ clocks = <&clock CLK_OUT_DMC>, <&clock CLK_OUT_TOP>,
+ <&clock CLK_OUT_LEFTBUS>, <&clock CLK_OUT_RIGHTBUS>,
+ <&clock CLK_OUT_CPU>, <&clock CLK_XXTI>,
+ <&clock CLK_XUSBXTI>;
+ #clock-cells = <1>;
};
g2d@10800000 {
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 834fb5a..492e1ef 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -191,6 +191,9 @@
pmu_system_controller: system-controller@10040000 {
compatible = "samsung,exynos5250-pmu", "syscon";
reg = <0x10040000 0x5000>;
+ clock-names = "clkout16";
+ clocks = <&clock CLK_FIN_PLL>;
+ #clock-cells = <1>;
};
sysreg_system_controller: syscon@10050000 {
diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index e385322..481beec 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -724,6 +724,9 @@
pmu_system_controller: system-controller@10040000 {
compatible = "samsung,exynos5420-pmu", "syscon";
reg = <0x10040000 0x5000>;
+ clock-names = "clkout16";
+ clocks = <&clock CLK_FIN_PLL>;
+ #clock-cells = <1>;
};
sysreg_system_controller: syscon@10050000 {
--
1.9.3
This patch adds definitions of clocks that are used to drive clock
output signals of particular CMU sub-blocks that are then fed to PMU and
handled by Exynos CLKOUT driver added in further patch.
Signed-off-by: Tomasz Figa <[email protected]>
---
drivers/clk/samsung/clk-exynos4.c | 116 ++++++++++++++++++++++++++++++++++--
include/dt-bindings/clock/exynos4.h | 5 ++
2 files changed, 117 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index f95ae6c..7d1fb99 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -25,10 +25,12 @@
#define DIV_LEFTBUS 0x4500
#define GATE_IP_LEFTBUS 0x4800
#define E4X12_GATE_IP_IMAGE 0x4930
+#define CLKOUT_CMU_LEFTBUS 0x4a00
#define SRC_RIGHTBUS 0x8200
#define DIV_RIGHTBUS 0x8500
#define GATE_IP_RIGHTBUS 0x8800
#define E4X12_GATE_IP_PERIR 0x8960
+#define CLKOUT_CMU_RIGHTBUS 0x8a00
#define EPLL_LOCK 0xc010
#define VPLL_LOCK 0xc020
#define EPLL_CON0 0xc110
@@ -98,6 +100,7 @@
#define GATE_IP_PERIL 0xc950
#define E4210_GATE_IP_PERIR 0xc960
#define GATE_BLOCK 0xc970
+#define CLKOUT_CMU_TOP 0xca00
#define E4X12_MPLL_LOCK 0x10008
#define E4X12_MPLL_CON0 0x10108
#define SRC_DMC 0x10200
@@ -105,6 +108,7 @@
#define DIV_DMC0 0x10500
#define DIV_DMC1 0x10504
#define GATE_IP_DMC 0x10900
+#define CLKOUT_CMU_DMC 0x10a00
#define APLL_LOCK 0x14000
#define E4210_MPLL_LOCK 0x14008
#define APLL_CON0 0x14100
@@ -114,6 +118,7 @@
#define DIV_CPU1 0x14504
#define GATE_SCLK_CPU 0x14800
#define GATE_IP_CPU 0x14900
+#define CLKOUT_CMU_CPU 0x14a00
#define E4X12_DIV_ISP0 0x18300
#define E4X12_DIV_ISP1 0x18304
#define E4X12_GATE_ISP0 0x18800
@@ -242,6 +247,11 @@ static unsigned long exynos4_clk_regs[] __initdata = {
DIV_CPU1,
GATE_SCLK_CPU,
GATE_IP_CPU,
+ CLKOUT_CMU_LEFTBUS,
+ CLKOUT_CMU_RIGHTBUS,
+ CLKOUT_CMU_TOP,
+ CLKOUT_CMU_DMC,
+ CLKOUT_CMU_CPU,
};
static const struct samsung_clk_reg_dump src_mask_suspend[] = {
@@ -400,6 +410,23 @@ PNAME(mout_dac_p4210) = { "sclk_vpll", "sclk_hdmiphy", };
PNAME(mout_pwi_p4210) = { "xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",
"sclk_usbphy1", "sclk_hdmiphy", "none",
"sclk_epll", "sclk_vpll" };
+PNAME(clkout_left_p4210) = { "sclk_mpll_div_2", "sclk_apll_div_2",
+ "div_gdl", "div_gpl" };
+PNAME(clkout_right_p4210) = { "sclk_mpll_div_2", "sclk_apll_div_2",
+ "div_gdr", "div_gpr" };
+PNAME(clkout_top_p4210) = { "fout_epll", "fout_vpll", "sclk_hdmi24m",
+ "sclk_usbphy0", "sclk_usbphy1", "sclk_hdmiphy",
+ "cdclk0", "cdclk1", "cdclk2", "spdif_extclk",
+ "aclk160", "aclk133", "aclk200", "aclk100",
+ "sclk_mfc", "sclk_g3d", "sclk_g2d",
+ "cam_a_pclk", "cam_b_pclk", "s_rxbyteclkhs0_2l",
+ "s_rxbyteclkhs0_4l" };
+PNAME(clkout_dmc_p4210) = { "div_dmcd", "div_dmcp", "div_acp_pclk", "div_dmc",
+ "div_dphy", "none", "div_pwi" };
+PNAME(clkout_cpu_p4210) = { "fout_apll_div_2", "none", "fout_mpll_div_2",
+ "none", "arm_clk_div_2", "div_corem0",
+ "div_corem1", "div_corem0", "div_atb",
+ "div_periph", "div_pclk_dbg", "div_hpm" };
/* Exynos 4x12-specific parent groups */
PNAME(mout_mpll_user_p4x12) = { "fin_pll", "sclk_mpll", };
@@ -426,6 +453,29 @@ PNAME(mout_user_aclk266_gps_p4x12) = {"fin_pll", "div_aclk266_gps", };
PNAME(mout_pwi_p4x12) = { "xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",
"none", "sclk_hdmiphy", "sclk_mpll",
"sclk_epll", "sclk_vpll" };
+PNAME(clkout_left_p4x12) = { "sclk_mpll_user_l_div_2", "sclk_apll_div_2",
+ "div_gdl", "div_gpl" };
+PNAME(clkout_right_p4x12) = { "sclk_mpll_user_r_div_2", "sclk_apll_div_2",
+ "div_gdr", "div_gpr" };
+PNAME(clkout_top_p4x12) = { "fout_epll", "fout_vpll", "sclk_hdmi24m",
+ "sclk_usbphy0", "none", "sclk_hdmiphy",
+ "cdclk0", "cdclk1", "cdclk2", "spdif_extclk",
+ "aclk160", "aclk133", "aclk200", "aclk100",
+ "sclk_mfc", "sclk_g3d", "aclk400_mcuisp",
+ "cam_a_pclk", "cam_b_pclk", "s_rxbyteclkhs0_2l",
+ "s_rxbyteclkhs0_4l", "rx_half_byte_clk_csis0",
+ "rx_half_byte_clk_csis1", "div_jpeg",
+ "sclk_pwm_isp", "sclk_spi0_isp",
+ "sclk_spi1_isp", "sclk_uart_isp",
+ "sclk_mipihsi", "sclk_hdmi", "sclk_fimd0",
+ "sclk_pcm0" };
+PNAME(clkout_dmc_p4x12) = { "div_dmcd", "div_dmcp", "aclk_acp", "div_acp_pclk",
+ "div_dmc", "div_dphy", "fout_mpll_div_2",
+ "div_pwi", "none", "div_c2c", "div_c2c_aclk" };
+PNAME(clkout_cpu_p4x12) = { "fout_apll_div_2", "none", "none", "none",
+ "arm_clk_div_2", "div_corem0", "div_corem1",
+ "div_cores", "div_atb", "div_periph",
+ "div_pclk_dbg", "div_hpm" };
/* fixed rate clocks generated outside the soc */
static struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata = {
@@ -444,6 +494,24 @@ static struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] __initdata =
FRATE(0, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000),
};
+static struct samsung_fixed_factor_clock exynos4_fixed_factor_clks[] __initdata = {
+ FFACTOR(0, "sclk_apll_div_2", "sclk_apll", 1, 2, 0),
+ FFACTOR(0, "fout_mpll_div_2", "fout_mpll", 1, 2, 0),
+ FFACTOR(0, "fout_apll_div_2", "fout_apll", 1, 2, 0),
+ FFACTOR(0, "arm_clk_div_2", "arm_clk", 1, 2, 0),
+};
+
+static struct samsung_fixed_factor_clock exynos4210_fixed_factor_clks[] __initdata = {
+ FFACTOR(0, "sclk_mpll_div_2", "sclk_mpll", 1, 2, 0),
+};
+
+static struct samsung_fixed_factor_clock exynos4x12_fixed_factor_clks[] __initdata = {
+ FFACTOR(0, "sclk_mpll_user_l_div_2", "mout_mpll_user_l", 1, 2, 0),
+ FFACTOR(0, "sclk_mpll_user_r_div_2", "mout_mpll_user_r", 1, 2, 0),
+ FFACTOR(0, "sclk_mpll_user_t_div_2", "mout_mpll_user_t", 1, 2, 0),
+ FFACTOR(0, "sclk_mpll_user_c_div_2", "mout_mpll_user_c", 1, 2, 0),
+};
+
/* list of mux clocks supported in all exynos4 soc's */
static struct samsung_mux_clock exynos4_mux_clks[] __initdata = {
MUX_FA(CLK_MOUT_APLL, "mout_apll", mout_apll_p, SRC_CPU, 0, 1,
@@ -471,8 +539,12 @@ static struct samsung_mux_clock exynos4210_mux_early[] __initdata = {
static struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
MUX(0, "mout_gdl", sclk_ampll_p4210, SRC_LEFTBUS, 0, 1),
+ MUX(0, "mout_clkout_leftbus", clkout_left_p4210,
+ CLKOUT_CMU_LEFTBUS, 0, 5),
MUX(0, "mout_gdr", sclk_ampll_p4210, SRC_RIGHTBUS, 0, 1),
+ MUX(0, "mout_clkout_rightbus", clkout_right_p4210,
+ CLKOUT_CMU_RIGHTBUS, 0, 5),
MUX(0, "mout_aclk200", sclk_ampll_p4210, SRC_TOP0, 12, 1),
MUX(0, "mout_aclk100", sclk_ampll_p4210, SRC_TOP0, 16, 1),
@@ -519,20 +591,30 @@ static struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
MUX(0, "mout_spi0", group1_p4210, SRC_PERIL1, 16, 4),
MUX(0, "mout_spi1", group1_p4210, SRC_PERIL1, 20, 4),
MUX(0, "mout_spi2", group1_p4210, SRC_PERIL1, 24, 4),
+ MUX(0, "mout_clkout_top", clkout_top_p4210, CLKOUT_CMU_TOP, 0, 5),
MUX(0, "mout_pwi", mout_pwi_p4210, SRC_DMC, 16, 4),
+ MUX(0, "mout_clkout_dmc", clkout_dmc_p4210, CLKOUT_CMU_DMC, 0, 5),
+
+ MUX(0, "mout_clkout_cpu", clkout_cpu_p4210, CLKOUT_CMU_CPU, 0, 5),
};
/* list of mux clocks supported in exynos4x12 soc */
static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
MUX(0, "mout_mpll_user_l", mout_mpll_p, SRC_LEFTBUS, 4, 1),
MUX(0, "mout_gdl", mout_gdl_p4x12, SRC_LEFTBUS, 0, 1),
+ MUX(0, "mout_clkout_leftbus", clkout_left_p4x12,
+ CLKOUT_CMU_LEFTBUS, 0, 5),
MUX(0, "mout_mpll_user_r", mout_mpll_p, SRC_RIGHTBUS, 4, 1),
MUX(0, "mout_gdr", mout_gdr_p4x12, SRC_RIGHTBUS, 0, 1),
+ MUX(0, "mout_clkout_rightbus", clkout_right_p4x12,
+ CLKOUT_CMU_RIGHTBUS, 0, 5),
MUX(CLK_MOUT_MPLL_USER_C, "mout_mpll_user_c", mout_mpll_user_p4x12,
SRC_CPU, 24, 1),
+ MUX(0, "mout_clkout_cpu", clkout_cpu_p4x12, CLKOUT_CMU_CPU, 0, 5),
+
MUX(0, "mout_aclk266_gps", aclk_p4412, SRC_TOP1, 4, 1),
MUX(0, "mout_aclk400_mcuisp", aclk_p4412, SRC_TOP1, 8, 1),
MUX(CLK_MOUT_MPLL_USER_T, "mout_mpll_user_t", mout_mpll_user_p4x12,
@@ -586,24 +668,27 @@ static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
MUX(0, "mout_spi0", group1_p4x12, SRC_PERIL1, 16, 4),
MUX(0, "mout_spi1", group1_p4x12, SRC_PERIL1, 20, 4),
MUX(0, "mout_spi2", group1_p4x12, SRC_PERIL1, 24, 4),
- MUX(0, "mout_pwm_isp", group1_p4x12, E4X12_SRC_ISP, 0, 4),
- MUX(0, "mout_spi0_isp", group1_p4x12, E4X12_SRC_ISP, 4, 4),
- MUX(0, "mout_spi1_isp", group1_p4x12, E4X12_SRC_ISP, 8, 4),
- MUX(0, "mout_uart_isp", group1_p4x12, E4X12_SRC_ISP, 12, 4),
+ MUX(0, "mout_clkout_top", clkout_top_p4x12, CLKOUT_CMU_TOP, 0, 5),
+
MUX(0, "mout_c2c", sclk_ampll_p4210, SRC_DMC, 0, 1),
MUX(0, "mout_pwi", mout_pwi_p4x12, SRC_DMC, 16, 4),
MUX(0, "mout_g2d0", sclk_ampll_p4210, SRC_DMC, 20, 1),
MUX(0, "mout_g2d1", sclk_evpll_p, SRC_DMC, 24, 1),
MUX(0, "mout_g2d", mout_g2d_p, SRC_DMC, 28, 1),
+ MUX(0, "mout_clkout_dmc", clkout_dmc_p4x12, CLKOUT_CMU_DMC, 0, 5),
};
/* list of divider clocks supported in all exynos4 soc's */
static struct samsung_div_clock exynos4_div_clks[] __initdata = {
DIV(0, "div_gdl", "mout_gdl", DIV_LEFTBUS, 0, 3),
DIV(0, "div_gpl", "div_gdl", DIV_LEFTBUS, 4, 3),
+ DIV(0, "div_clkout_leftbus", "mout_clkout_leftbus",
+ CLKOUT_CMU_LEFTBUS, 8, 6),
DIV(0, "div_gdr", "mout_gdr", DIV_RIGHTBUS, 0, 3),
DIV(0, "div_gpr", "div_gdr", DIV_RIGHTBUS, 4, 3),
+ DIV(0, "div_clkout_rightbus", "mout_clkout_rightbus",
+ CLKOUT_CMU_RIGHTBUS, 8, 6),
DIV(0, "div_core", "mout_core", DIV_CPU0, 0, 3),
DIV(0, "div_corem0", "div_core2", DIV_CPU0, 4, 3),
@@ -614,6 +699,8 @@ static struct samsung_div_clock exynos4_div_clks[] __initdata = {
DIV(0, "div_core2", "div_core", DIV_CPU0, 28, 3),
DIV(0, "div_copy", "mout_hpm", DIV_CPU1, 0, 3),
DIV(0, "div_hpm", "div_copy", DIV_CPU1, 4, 3),
+ DIV(0, "div_clkout_cpu", "mout_clkout_cpu", CLKOUT_CMU_CPU, 8, 6),
+
DIV(0, "div_fimc0", "mout_fimc0", DIV_CAM, 0, 4),
DIV(0, "div_fimc1", "mout_fimc1", DIV_CAM, 4, 4),
DIV(0, "div_fimc2", "mout_fimc2", DIV_CAM, 8, 4),
@@ -671,6 +758,7 @@ static struct samsung_div_clock exynos4_div_clks[] __initdata = {
CLK_SET_RATE_PARENT, 0),
DIV_F(0, "div_mmc_pre3", "div_mmc3", DIV_FSYS2, 24, 8,
CLK_SET_RATE_PARENT, 0),
+ DIV(0, "div_clkout_top", "mout_clkout_top", CLKOUT_CMU_TOP, 8, 6),
DIV(0, "div_acp", "mout_dmc_bus", DIV_DMC0, 0, 3),
DIV(0, "div_acp_pclk", "div_acp", DIV_DMC0, 4, 3),
@@ -679,6 +767,7 @@ static struct samsung_div_clock exynos4_div_clks[] __initdata = {
DIV(0, "div_dmcd", "div_dmc", DIV_DMC0, 16, 3),
DIV(0, "div_dmcp", "div_dmcd", DIV_DMC0, 20, 3),
DIV(0, "div_pwi", "mout_pwi", DIV_DMC1, 8, 4),
+ DIV(0, "div_clkout_dmc", "mout_clkout_dmc", CLKOUT_CMU_DMC, 8, 6),
};
/* list of divider clocks supported in exynos4210 soc */
@@ -902,6 +991,17 @@ static struct samsung_gate_clock exynos4_gate_clks[] __initdata = {
0, 0),
GATE(CLK_AC97, "ac97", "aclk100", GATE_IP_PERIL, 27,
0, 0),
+
+ GATE(CLK_OUT_LEFTBUS, "clkout_leftbus", "div_clkout_leftbus",
+ CLKOUT_CMU_LEFTBUS, 16, CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_OUT_RIGHTBUS, "clkout_rightbus", "div_clkout_rightbus",
+ CLKOUT_CMU_RIGHTBUS, 16, CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_OUT_TOP, "clkout_top", "div_clkout_top",
+ CLKOUT_CMU_TOP, 16, CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_OUT_DMC, "clkout_dmc", "div_clkout_dmc",
+ CLKOUT_CMU_DMC, 16, CLK_SET_RATE_PARENT, 0),
+ GATE(CLK_OUT_CPU, "clkout_cpu", "div_clkout_cpu",
+ CLKOUT_CMU_CPU, 16, CLK_SET_RATE_PARENT, 0),
};
/* list of gate clocks supported in exynos4210 soc */
@@ -1282,6 +1382,8 @@ static void __init exynos4_clk_init(struct device_node *np,
ARRAY_SIZE(exynos4_div_clks));
samsung_clk_register_gate(ctx, exynos4_gate_clks,
ARRAY_SIZE(exynos4_gate_clks));
+ samsung_clk_register_fixed_factor(ctx, exynos4_fixed_factor_clks,
+ ARRAY_SIZE(exynos4_fixed_factor_clks));
if (exynos4_soc == EXYNOS4210) {
samsung_clk_register_fixed_rate(ctx, exynos4210_fixed_rate_clks,
@@ -1294,6 +1396,9 @@ static void __init exynos4_clk_init(struct device_node *np,
ARRAY_SIZE(exynos4210_gate_clks));
samsung_clk_register_alias(ctx, exynos4210_aliases,
ARRAY_SIZE(exynos4210_aliases));
+ samsung_clk_register_fixed_factor(ctx,
+ exynos4210_fixed_factor_clks,
+ ARRAY_SIZE(exynos4210_fixed_factor_clks));
} else {
samsung_clk_register_mux(ctx, exynos4x12_mux_clks,
ARRAY_SIZE(exynos4x12_mux_clks));
@@ -1303,6 +1408,9 @@ static void __init exynos4_clk_init(struct device_node *np,
ARRAY_SIZE(exynos4x12_gate_clks));
samsung_clk_register_alias(ctx, exynos4x12_aliases,
ARRAY_SIZE(exynos4x12_aliases));
+ samsung_clk_register_fixed_factor(ctx,
+ exynos4x12_fixed_factor_clks,
+ ARRAY_SIZE(exynos4x12_fixed_factor_clks));
}
samsung_clk_register_alias(ctx, exynos4_aliases,
diff --git a/include/dt-bindings/clock/exynos4.h b/include/dt-bindings/clock/exynos4.h
index 1106ca5..e0c4673 100644
--- a/include/dt-bindings/clock/exynos4.h
+++ b/include/dt-bindings/clock/exynos4.h
@@ -34,6 +34,11 @@
#define CLK_MOUT_CORE 19
#define CLK_MOUT_APLL 20
#define CLK_SCLK_HDMIPHY 22
+#define CLK_OUT_DMC 23
+#define CLK_OUT_TOP 24
+#define CLK_OUT_LEFTBUS 25
+#define CLK_OUT_RIGHTBUS 26
+#define CLK_OUT_CPU 27
/* gate for special clocks (sclk) */
#define CLK_SCLK_FIMC0 128
--
1.9.3
This patch adds missing definitions of clocks from CPU and DMC clock
domains, which are necessary to properly represent CLKOUT clock hierarchy
added in further patch.
Signed-off-by: Tomasz Figa <[email protected]>
---
drivers/clk/samsung/clk-exynos4.c | 50 +++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index 4f150c9..f95ae6c 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -397,10 +397,15 @@ PNAME(mout_audio2_p4210) = { "cdclk2", "none", "sclk_hdmi24m",
"sclk_epll", "sclk_vpll", };
PNAME(mout_mixer_p4210) = { "sclk_dac", "sclk_hdmi", };
PNAME(mout_dac_p4210) = { "sclk_vpll", "sclk_hdmiphy", };
+PNAME(mout_pwi_p4210) = { "xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",
+ "sclk_usbphy1", "sclk_hdmiphy", "none",
+ "sclk_epll", "sclk_vpll" };
/* Exynos 4x12-specific parent groups */
PNAME(mout_mpll_user_p4x12) = { "fin_pll", "sclk_mpll", };
PNAME(mout_core_p4x12) = { "mout_apll", "mout_mpll_user_c", };
+PNAME(mout_gdl_p4x12) = { "mout_mpll_user_l", "sclk_apll", };
+PNAME(mout_gdr_p4x12) = { "mout_mpll_user_r", "sclk_apll", };
PNAME(sclk_ampll_p4x12) = { "mout_mpll_user_t", "sclk_apll", };
PNAME(group1_p4x12) = { "xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",
"none", "sclk_hdmiphy", "mout_mpll_user_t",
@@ -418,6 +423,9 @@ PNAME(aclk_p4412) = { "mout_mpll_user_t", "sclk_apll", };
PNAME(mout_user_aclk400_mcuisp_p4x12) = {"fin_pll", "div_aclk400_mcuisp", };
PNAME(mout_user_aclk200_p4x12) = {"fin_pll", "div_aclk200", };
PNAME(mout_user_aclk266_gps_p4x12) = {"fin_pll", "div_aclk266_gps", };
+PNAME(mout_pwi_p4x12) = { "xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0",
+ "none", "sclk_hdmiphy", "sclk_mpll",
+ "sclk_epll", "sclk_vpll" };
/* fixed rate clocks generated outside the soc */
static struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata = {
@@ -451,6 +459,9 @@ static struct samsung_mux_clock exynos4_mux_clks[] __initdata = {
MUX(0, "mout_onenand1", mout_onenand1_p, SRC_TOP0, 0, 1),
MUX(CLK_SCLK_EPLL, "sclk_epll", mout_epll_p, SRC_TOP0, 4, 1),
MUX(0, "mout_onenand", mout_onenand_p, SRC_TOP0, 28, 1),
+
+ MUX(0, "mout_dmc_bus", sclk_ampll_p4210, SRC_DMC, 4, 1),
+ MUX(0, "mout_dphy", sclk_ampll_p4210, SRC_DMC, 8, 1),
};
/* list of mux clocks supported in exynos4210 soc */
@@ -459,6 +470,10 @@ static struct samsung_mux_clock exynos4210_mux_early[] __initdata = {
};
static struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
+ MUX(0, "mout_gdl", sclk_ampll_p4210, SRC_LEFTBUS, 0, 1),
+
+ MUX(0, "mout_gdr", sclk_ampll_p4210, SRC_RIGHTBUS, 0, 1),
+
MUX(0, "mout_aclk200", sclk_ampll_p4210, SRC_TOP0, 12, 1),
MUX(0, "mout_aclk100", sclk_ampll_p4210, SRC_TOP0, 16, 1),
MUX(0, "mout_aclk160", sclk_ampll_p4210, SRC_TOP0, 20, 1),
@@ -472,6 +487,7 @@ static struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
MUX(0, "mout_mipi1", group1_p4210, E4210_SRC_LCD1, 12, 4),
MUX(CLK_SCLK_MPLL, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1),
MUX(CLK_MOUT_CORE, "mout_core", mout_core_p4210, SRC_CPU, 16, 1),
+ MUX(0, "mout_hpm", mout_core_p4210, SRC_CPU, 20, 1),
MUX(CLK_SCLK_VPLL, "sclk_vpll", sclk_vpll_p4210, SRC_TOP0, 8, 1),
MUX(CLK_MOUT_FIMC0, "mout_fimc0", group1_p4210, SRC_CAM, 0, 4),
MUX(CLK_MOUT_FIMC1, "mout_fimc1", group1_p4210, SRC_CAM, 4, 4),
@@ -503,10 +519,18 @@ static struct samsung_mux_clock exynos4210_mux_clks[] __initdata = {
MUX(0, "mout_spi0", group1_p4210, SRC_PERIL1, 16, 4),
MUX(0, "mout_spi1", group1_p4210, SRC_PERIL1, 20, 4),
MUX(0, "mout_spi2", group1_p4210, SRC_PERIL1, 24, 4),
+
+ MUX(0, "mout_pwi", mout_pwi_p4210, SRC_DMC, 16, 4),
};
/* list of mux clocks supported in exynos4x12 soc */
static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
+ MUX(0, "mout_mpll_user_l", mout_mpll_p, SRC_LEFTBUS, 4, 1),
+ MUX(0, "mout_gdl", mout_gdl_p4x12, SRC_LEFTBUS, 0, 1),
+
+ MUX(0, "mout_mpll_user_r", mout_mpll_p, SRC_RIGHTBUS, 4, 1),
+ MUX(0, "mout_gdr", mout_gdr_p4x12, SRC_RIGHTBUS, 0, 1),
+
MUX(CLK_MOUT_MPLL_USER_C, "mout_mpll_user_c", mout_mpll_user_p4x12,
SRC_CPU, 24, 1),
MUX(0, "mout_aclk266_gps", aclk_p4412, SRC_TOP1, 4, 1),
@@ -531,6 +555,7 @@ static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
MUX(CLK_SCLK_MPLL, "sclk_mpll", mout_mpll_p, SRC_DMC, 12, 1),
MUX(CLK_SCLK_VPLL, "sclk_vpll", mout_vpll_p, SRC_TOP0, 8, 1),
MUX(CLK_MOUT_CORE, "mout_core", mout_core_p4x12, SRC_CPU, 16, 1),
+ MUX(0, "mout_hpm", mout_core_p4x12, SRC_CPU, 20, 1),
MUX(CLK_MOUT_FIMC0, "mout_fimc0", group1_p4x12, SRC_CAM, 0, 4),
MUX(CLK_MOUT_FIMC1, "mout_fimc1", group1_p4x12, SRC_CAM, 4, 4),
MUX(CLK_MOUT_FIMC2, "mout_fimc2", group1_p4x12, SRC_CAM, 8, 4),
@@ -565,6 +590,8 @@ static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
MUX(0, "mout_spi0_isp", group1_p4x12, E4X12_SRC_ISP, 4, 4),
MUX(0, "mout_spi1_isp", group1_p4x12, E4X12_SRC_ISP, 8, 4),
MUX(0, "mout_uart_isp", group1_p4x12, E4X12_SRC_ISP, 12, 4),
+ MUX(0, "mout_c2c", sclk_ampll_p4210, SRC_DMC, 0, 1),
+ MUX(0, "mout_pwi", mout_pwi_p4x12, SRC_DMC, 16, 4),
MUX(0, "mout_g2d0", sclk_ampll_p4210, SRC_DMC, 20, 1),
MUX(0, "mout_g2d1", sclk_evpll_p, SRC_DMC, 24, 1),
MUX(0, "mout_g2d", mout_g2d_p, SRC_DMC, 28, 1),
@@ -572,8 +599,21 @@ static struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = {
/* list of divider clocks supported in all exynos4 soc's */
static struct samsung_div_clock exynos4_div_clks[] __initdata = {
+ DIV(0, "div_gdl", "mout_gdl", DIV_LEFTBUS, 0, 3),
+ DIV(0, "div_gpl", "div_gdl", DIV_LEFTBUS, 4, 3),
+
+ DIV(0, "div_gdr", "mout_gdr", DIV_RIGHTBUS, 0, 3),
+ DIV(0, "div_gpr", "div_gdr", DIV_RIGHTBUS, 4, 3),
+
DIV(0, "div_core", "mout_core", DIV_CPU0, 0, 3),
+ DIV(0, "div_corem0", "div_core2", DIV_CPU0, 4, 3),
+ DIV(0, "div_corem1", "div_core2", DIV_CPU0, 8, 3),
+ DIV(0, "div_periph", "div_core2", DIV_CPU0, 12, 3),
+ DIV(0, "div_atb", "mout_core", DIV_CPU0, 16, 3),
+ DIV(0, "div_pclk_dbg", "div_atb", DIV_CPU0, 20, 3),
DIV(0, "div_core2", "div_core", DIV_CPU0, 28, 3),
+ DIV(0, "div_copy", "mout_hpm", DIV_CPU1, 0, 3),
+ DIV(0, "div_hpm", "div_copy", DIV_CPU1, 4, 3),
DIV(0, "div_fimc0", "mout_fimc0", DIV_CAM, 0, 4),
DIV(0, "div_fimc1", "mout_fimc1", DIV_CAM, 4, 4),
DIV(0, "div_fimc2", "mout_fimc2", DIV_CAM, 8, 4),
@@ -631,6 +671,14 @@ static struct samsung_div_clock exynos4_div_clks[] __initdata = {
CLK_SET_RATE_PARENT, 0),
DIV_F(0, "div_mmc_pre3", "div_mmc3", DIV_FSYS2, 24, 8,
CLK_SET_RATE_PARENT, 0),
+
+ DIV(0, "div_acp", "mout_dmc_bus", DIV_DMC0, 0, 3),
+ DIV(0, "div_acp_pclk", "div_acp", DIV_DMC0, 4, 3),
+ DIV(0, "div_dphy", "mout_dphy", DIV_DMC0, 8, 3),
+ DIV(0, "div_dmc", "mout_dmc_bus", DIV_DMC0, 12, 3),
+ DIV(0, "div_dmcd", "div_dmc", DIV_DMC0, 16, 3),
+ DIV(0, "div_dmcp", "div_dmcd", DIV_DMC0, 20, 3),
+ DIV(0, "div_pwi", "mout_pwi", DIV_DMC1, 8, 4),
};
/* list of divider clocks supported in exynos4210 soc */
@@ -671,6 +719,8 @@ static struct samsung_div_clock exynos4x12_div_clks[] __initdata = {
DIV_F(CLK_DIV_MCUISP1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1,
8, 3, CLK_GET_RATE_NOCACHE, 0),
DIV(CLK_SCLK_FIMG2D, "sclk_fimg2d", "mout_g2d", DIV_DMC1, 0, 4),
+ DIV(0, "div_c2c", "mout_c2c", DIV_DMC1, 4, 3),
+ DIV(0, "div_c2c_aclk", "div_c2c", DIV_DMC1, 12, 3),
};
/* list of gate clocks supported in all exynos4 soc's */
--
1.9.3
Hi,
On Tue, Jun 24, 2014 at 5:08 PM, Tomasz Figa <[email protected]> wrote:
> Tested on Odroid U3, with HSIC/USB hub using CLKOUT as reference clock,
> with some additional patches.
for all the patches:
Tested-by: Daniel Drake <[email protected]>
Tested on ODROID-U2 alongside
phy: phy-samsung-usb2: Change phy power on/power off sequence
now USB is working fine.
Thanks!
Daniel
Tomasz Figa wrote:
>
Hi Tomasz,
> On all Exynos SoCs there is a dedicated CLKOUT pin that allows many of
> internal SoC clocks to be output from the SoC. The hardware structure
Yeah, because the CLKOUT pin is used for measure of the clock for debug on all
of exynos SoCs commonly.
> of CLKOUT related clocks looks as follows:
>
> CMU |---> clock0 ---------> | PMU |
> | | |
> several |---> clock1 ---------> | mux |
> muxes | | + |---> CLKOUT
> dividers | ... | gate |
> and gates | | |
> |---> clockN ---------> | |
>
> Since the block responsible for handling the pin is PMU, not CMU,
> a separate driver, that binds to PMU node is required and acquires
> all input clocks by standard DT clock look-up. This way we don't need
> any cross-IP block drivers and cross-driver register sharing or
> nodes for fake devices.
>
BTW, upcoming exynos5 SoCs have two muxs for CLKOUT and each mux is controlled
by CMU and PMU, so
The mux1 for CLKOUT in CMU is used to decide which clock in each sub-domain
will be out and the mux2 in PMU is used to decide which sub-domain will be out
via CLKOUT. So I want you to consider of all of exynos SoCs including upcoming
SoCs.
Thanks,
Kukjin
> To represent the PMU mux/gate clock, generic composite clock is registered.
>
> Tested on Odroid U3, with HSIC/USB hub using CLKOUT as reference clock,
> with some additional patches.
>
> Changes since v1:
> (http://www.spinics.net/lists/arm-kernel/msg333276.html)
> - rebased onto next-20140624,
> - fixed #clock-cells values in exynos5250.dtsi and exynos5420.dtsi,
> - temporarily removed ISP CLKOUT clocks on Exynos4x12, until ISP clock
> domain handling gets fixed in Exynos4 clock driver.
> Changes since RFC v1:
> (https://lkml.org/lkml/2014/5/15/506)
> - rebased onto v5 of "Enable usbphy and hsotg for exynos4" series and
> current HEAD of samsung-clk tree,
> - added handling of suspend/resume in the driver,
> - added missing CPU clocks on Exynos4,
> - added CLK_SET_RATE_PARENT to CMU CLKOUT gates on Exynos4,
> - fixed bit field width on Exynos4,
> - added CLKOUT CMU registers of Exynos4 to save/restore list,
> - added CLK_SET_RATE_PARENT and CLK_SET_RATE_NO_REPARENT to clkout clock,
> - changed the binding to use 1-cell clock specifier to allow extension
> with further PMU clocks in future, if needed.
>
> Tomasz Figa (4):
> clk: samsung: exynos4: Add missing CPU/DMC clock hierarchy
> clk: samsung: exynos4: Add CLKOUT clock hierarchy
> clk: samsung: Add driver to control CLKOUT line on Exynos SoCs
> ARM: dts: exynos: Update PMU node with CLKOUT related data
>
> .../devicetree/bindings/arm/samsung/pmu.txt | 30 ++++
> arch/arm/boot/dts/exynos4210.dtsi | 10 ++
> arch/arm/boot/dts/exynos4x12.dtsi | 7 +
> arch/arm/boot/dts/exynos5250.dtsi | 3 +
> arch/arm/boot/dts/exynos5420.dtsi | 3 +
> drivers/clk/samsung/Makefile | 1 +
> drivers/clk/samsung/clk-exynos-clkout.c | 153 +++++++++++++++++++
> drivers/clk/samsung/clk-exynos4.c | 166
++++++++++++++++++++-
> include/dt-bindings/clock/exynos4.h | 5 +
> 9 files changed, 374 insertions(+), 4 deletions(-)
> create mode 100644 drivers/clk/samsung/clk-exynos-clkout.c
>
> --
> 1.9.3
Hi Kukjin,
On 25.06.2014 12:36, Kukjin Kim wrote:
> Tomasz Figa wrote:
>>
> Hi Tomasz,
>
>> On all Exynos SoCs there is a dedicated CLKOUT pin that allows many of
>> internal SoC clocks to be output from the SoC. The hardware structure
>
> Yeah, because the CLKOUT pin is used for measure of the clock for debug on all
> of exynos SoCs commonly.
>
>> of CLKOUT related clocks looks as follows:
>>
>> CMU |---> clock0 ---------> | PMU |
>> | | |
>> several |---> clock1 ---------> | mux |
>> muxes | | + |---> CLKOUT
>> dividers | ... | gate |
>> and gates | | |
>> |---> clockN ---------> | |
>>
>> Since the block responsible for handling the pin is PMU, not CMU,
>> a separate driver, that binds to PMU node is required and acquires
>> all input clocks by standard DT clock look-up. This way we don't need
>> any cross-IP block drivers and cross-driver register sharing or
>> nodes for fake devices.
>>
> BTW, upcoming exynos5 SoCs have two muxs for CLKOUT and each mux is controlled
> by CMU and PMU, so
>
> The mux1 for CLKOUT in CMU is used to decide which clock in each sub-domain
> will be out and the mux2 in PMU is used to decide which sub-domain will be out
> via CLKOUT. So I want you to consider of all of exynos SoCs including upcoming
> SoCs.
Is it something similar to what I implemented for Exynos4 in patch 2/4?
The same has to be done for other Exynos SoCs as well, but i don't have
any board on which I could test this, so I just added a subset of
available inputs of PMU mux in current implementation.
Anyway, anything in CMU can be handled in normal SoC clock driver, so I
don't think this poses any problem for this series.
Best regards,
Tomasz
Quoting Kukjin Kim (2014-06-25 03:36:51)
> Tomasz Figa wrote:
> >
> Hi Tomasz,
>
> > On all Exynos SoCs there is a dedicated CLKOUT pin that allows many of
> > internal SoC clocks to be output from the SoC. The hardware structure
>
> Yeah, because the CLKOUT pin is used for measure of the clock for debug on all
> of exynos SoCs commonly.
>
> > of CLKOUT related clocks looks as follows:
> >
> > CMU |---> clock0 ---------> | PMU |
> > | | |
> > several |---> clock1 ---------> | mux |
> > muxes | | + |---> CLKOUT
> > dividers | ... | gate |
> > and gates | | |
> > |---> clockN ---------> | |
> >
> > Since the block responsible for handling the pin is PMU, not CMU,
> > a separate driver, that binds to PMU node is required and acquires
> > all input clocks by standard DT clock look-up. This way we don't need
> > any cross-IP block drivers and cross-driver register sharing or
> > nodes for fake devices.
> >
> BTW, upcoming exynos5 SoCs have two muxs for CLKOUT and each mux is controlled
> by CMU and PMU, so
>
> The mux1 for CLKOUT in CMU is used to decide which clock in each sub-domain
> will be out and the mux2 in PMU is used to decide which sub-domain will be out
> via CLKOUT. So I want you to consider of all of exynos SoCs including upcoming
> SoCs.
clkout for debug is very useful indeed. For SoCs with high speed clocks
that I have worked with, I have often observed that the clkout logic
introduces buffers or dividers. This is needed so that you can get a
(relatively) clean clock signal on your oscilloscope. Otherwise that
2GHz ARM clk is just going to be noise ;-)
These divider values can modeled in the clk framework. Do you know if
you have such stuff on your chip?
Regards,
Mike
>
> Thanks,
> Kukjin
>
> > To represent the PMU mux/gate clock, generic composite clock is registered.
> >
> > Tested on Odroid U3, with HSIC/USB hub using CLKOUT as reference clock,
> > with some additional patches.
> >
> > Changes since v1:
> > (http://www.spinics.net/lists/arm-kernel/msg333276.html)
> > - rebased onto next-20140624,
> > - fixed #clock-cells values in exynos5250.dtsi and exynos5420.dtsi,
> > - temporarily removed ISP CLKOUT clocks on Exynos4x12, until ISP clock
> > domain handling gets fixed in Exynos4 clock driver.
> > Changes since RFC v1:
> > (https://lkml.org/lkml/2014/5/15/506)
> > - rebased onto v5 of "Enable usbphy and hsotg for exynos4" series and
> > current HEAD of samsung-clk tree,
> > - added handling of suspend/resume in the driver,
> > - added missing CPU clocks on Exynos4,
> > - added CLK_SET_RATE_PARENT to CMU CLKOUT gates on Exynos4,
> > - fixed bit field width on Exynos4,
> > - added CLKOUT CMU registers of Exynos4 to save/restore list,
> > - added CLK_SET_RATE_PARENT and CLK_SET_RATE_NO_REPARENT to clkout clock,
> > - changed the binding to use 1-cell clock specifier to allow extension
> > with further PMU clocks in future, if needed.
> >
> > Tomasz Figa (4):
> > clk: samsung: exynos4: Add missing CPU/DMC clock hierarchy
> > clk: samsung: exynos4: Add CLKOUT clock hierarchy
> > clk: samsung: Add driver to control CLKOUT line on Exynos SoCs
> > ARM: dts: exynos: Update PMU node with CLKOUT related data
> >
> > .../devicetree/bindings/arm/samsung/pmu.txt | 30 ++++
> > arch/arm/boot/dts/exynos4210.dtsi | 10 ++
> > arch/arm/boot/dts/exynos4x12.dtsi | 7 +
> > arch/arm/boot/dts/exynos5250.dtsi | 3 +
> > arch/arm/boot/dts/exynos5420.dtsi | 3 +
> > drivers/clk/samsung/Makefile | 1 +
> > drivers/clk/samsung/clk-exynos-clkout.c | 153 +++++++++++++++++++
> > drivers/clk/samsung/clk-exynos4.c | 166
> ++++++++++++++++++++-
> > include/dt-bindings/clock/exynos4.h | 5 +
> > 9 files changed, 374 insertions(+), 4 deletions(-)
> > create mode 100644 drivers/clk/samsung/clk-exynos-clkout.c
> >
> > --
> > 1.9.3
>
On 03.07.2014 02:14, Mike Turquette wrote:
> Quoting Kukjin Kim (2014-06-25 03:36:51)
>> Tomasz Figa wrote:
>>>
>> Hi Tomasz,
>>
>>> On all Exynos SoCs there is a dedicated CLKOUT pin that allows many of
>>> internal SoC clocks to be output from the SoC. The hardware structure
>>
>> Yeah, because the CLKOUT pin is used for measure of the clock for debug on all
>> of exynos SoCs commonly.
>>
>>> of CLKOUT related clocks looks as follows:
>>>
>>> CMU |---> clock0 ---------> | PMU |
>>> | | |
>>> several |---> clock1 ---------> | mux |
>>> muxes | | + |---> CLKOUT
>>> dividers | ... | gate |
>>> and gates | | |
>>> |---> clockN ---------> | |
>>>
>>> Since the block responsible for handling the pin is PMU, not CMU,
>>> a separate driver, that binds to PMU node is required and acquires
>>> all input clocks by standard DT clock look-up. This way we don't need
>>> any cross-IP block drivers and cross-driver register sharing or
>>> nodes for fake devices.
>>>
>> BTW, upcoming exynos5 SoCs have two muxs for CLKOUT and each mux is controlled
>> by CMU and PMU, so
>>
>> The mux1 for CLKOUT in CMU is used to decide which clock in each sub-domain
>> will be out and the mux2 in PMU is used to decide which sub-domain will be out
>> via CLKOUT. So I want you to consider of all of exynos SoCs including upcoming
>> SoCs.
>
> clkout for debug is very useful indeed. For SoCs with high speed clocks
> that I have worked with, I have often observed that the clkout logic
> introduces buffers or dividers. This is needed so that you can get a
> (relatively) clean clock signal on your oscilloscope. Otherwise that
> 2GHz ARM clk is just going to be noise ;-)
>
> These divider values can modeled in the clk framework. Do you know if
> you have such stuff on your chip?
I believe this is what I have already implemented in my series.
The final CLKOUT mux and gates are implemented by separate driver,
because they reside in another IP block, while per-domain CLKOUT
dividers along with muxes and gates are registered by normal SoC clock
driver, because they are part of the clock controller. See patch 2/4
adding the whole hierarchy for Exynos4 SoCs.
I don't have boards to test CLKOUT on Exynos5 SoCs, so they are up to
interested people.
Best regards,
Tomasz
Kukjin,
On 24.06.2014 18:08, Tomasz Figa wrote:
> On all Exynos SoCs there is a dedicated CLKOUT pin that allows many of
> internal SoC clocks to be output from the SoC. The hardware structure
> of CLKOUT related clocks looks as follows:
>
> CMU |---> clock0 ---------> | PMU |
> | | |
> several |---> clock1 ---------> | mux |
> muxes | | + |---> CLKOUT
> dividers | ... | gate |
> and gates | | |
> |---> clockN ---------> | |
>
> Since the block responsible for handling the pin is PMU, not CMU,
> a separate driver, that binds to PMU node is required and acquires
> all input clocks by standard DT clock look-up. This way we don't need
> any cross-IP block drivers and cross-driver register sharing or
> nodes for fake devices.
>
> To represent the PMU mux/gate clock, generic composite clock is registered.
>
> Tested on Odroid U3, with HSIC/USB hub using CLKOUT as reference clock,
> with some additional patches.
>
> Changes since v1:
> (http://www.spinics.net/lists/arm-kernel/msg333276.html)
> - rebased onto next-20140624,
> - fixed #clock-cells values in exynos5250.dtsi and exynos5420.dtsi,
> - temporarily removed ISP CLKOUT clocks on Exynos4x12, until ISP clock
> domain handling gets fixed in Exynos4 clock driver.
> Changes since RFC v1:
> (https://lkml.org/lkml/2014/5/15/506)
> - rebased onto v5 of "Enable usbphy and hsotg for exynos4" series and
> current HEAD of samsung-clk tree,
> - added handling of suspend/resume in the driver,
> - added missing CPU clocks on Exynos4,
> - added CLK_SET_RATE_PARENT to CMU CLKOUT gates on Exynos4,
> - fixed bit field width on Exynos4,
> - added CLKOUT CMU registers of Exynos4 to save/restore list,
> - added CLK_SET_RATE_PARENT and CLK_SET_RATE_NO_REPARENT to clkout clock,
> - changed the binding to use 1-cell clock specifier to allow extension
> with further PMU clocks in future, if needed.
>
> Tomasz Figa (4):
> clk: samsung: exynos4: Add missing CPU/DMC clock hierarchy
> clk: samsung: exynos4: Add CLKOUT clock hierarchy
> clk: samsung: Add driver to control CLKOUT line on Exynos SoCs
> ARM: dts: exynos: Update PMU node with CLKOUT related data
>
> .../devicetree/bindings/arm/samsung/pmu.txt | 30 ++++
> arch/arm/boot/dts/exynos4210.dtsi | 10 ++
> arch/arm/boot/dts/exynos4x12.dtsi | 7 +
> arch/arm/boot/dts/exynos5250.dtsi | 3 +
> arch/arm/boot/dts/exynos5420.dtsi | 3 +
> drivers/clk/samsung/Makefile | 1 +
> drivers/clk/samsung/clk-exynos-clkout.c | 153 +++++++++++++++++++
> drivers/clk/samsung/clk-exynos4.c | 166 ++++++++++++++++++++-
> include/dt-bindings/clock/exynos4.h | 5 +
> 9 files changed, 374 insertions(+), 4 deletions(-)
> create mode 100644 drivers/clk/samsung/clk-exynos-clkout.c
>
Is there any progress with consulting this with hardware guys? Could I
have your Ack for this series, so I could put it in my tree and let
other patches base on it (especially on patches 1 and 2)? Thanks in advance.
Best regards,
Tomasz