Merge branches 'clk-composite-determine-fix', 'clk-allwinner', 'clk-amlogic' and 'clk-samsung' into clk-next
* clk-composite-determine-fix: clk: composite: Use rate_ops.determine_rate when also a mux is available clk: composite: Also consider .determine_rate for rate + mux composites * clk-allwinner: clk: sunxi: sun8i-apb0: Make use of the helper function devm_platform_ioremap_resource() clk: sunxi: sun6i-ar100: Make use of the helper function devm_platform_ioremap_resource() clk: sunxi: sun6i-apb0-gates: Make use of the helper function devm_platform_ioremap_resource() clk: sunxi: sun6i-apb0: Make use of the helper function devm_platform_ioremap_resource() clk: sunxi-ng: ccu-sun9i-a80-usb: Make use of the helper function devm_platform_ioremap_resource() clk: sunxi-ng: ccu-sun9i-a80-de: Make use of the helper function devm_platform_ioremap_resource() clk: sunxi-ng: ccu-sun9i-a80: Make use of the helper function devm_platform_ioremap_resource() clk: sunxi-ng: ccu-sun8i-r40: Make use of the helper function devm_platform_ioremap_resource() clk: sunxi-ng: ccu-sun8i-de2: Make use of the helper function devm_platform_ioremap_resource() clk: sunxi-ng: ccu-sun8i-a83t: Make use of the helper function devm_platform_ioremap_resource() clk: sunxi-ng: ccu-sun50i-h6: Make use of the helper function devm_platform_ioremap_resource() clk: sunxi-ng: ccu-sun50i-a64: Make use of the helper function devm_platform_ioremap_resource() clk: sunxi: clk-mod0: Make use of the helper function devm_platform_ioremap_resource() dt-bindings: clocks: Fix typo in the H6 compatible clk: sunxi-ng: Use a separate lock for each CCU instance clk: sunxi-ng: Prevent unbinding CCUs via sysfs clk: sunxi-ng: Unregister clocks/resets when unbinding clk: sunxi-ng: Add machine dependency to A83T CCU clk: sunxi-ng: mux: Remove unused 'reg' field * clk-amlogic: clk: meson: meson8b: Make the video clock trees mutable clk: meson: meson8b: Initialize the HDMI PLL registers clk: meson: meson8b: Add the HDMI PLL M/N parameters clk: meson: meson8b: Add the vid_pll_lvds_en gate clock clk: meson: meson8b: Use CLK_SET_RATE_NO_REPARENT for vclk{,2}_in_sel clk: meson: meson8b: Export the video clocks * clk-samsung: clk: samsung: describe drivers in Kconfig clk: samsung: exynos5433: update apollo and atlas clock probing clk: samsung: add support for CPU clocks clk: samsung: Introduce Exynos850 clock driver dt-bindings: clock: Document Exynos850 CMU bindings dt-bindings: clock: Add bindings definitions for Exynos850 CMU clk: samsung: clk-pll: Implement pll0831x PLL type clk: samsung: clk-pll: Implement pll0822x PLL type clk: samsung: s5pv210-audss: Make use of devm_platform_ioremap_resource() clk: samsung: exynos5433: Make use of devm_platform_ioremap_resource() clk: samsung: exynos4412-isp: Make use of devm_platform_ioremap_resource() clk: samsung: exynos-audss: Make use of devm_platform_ioremap_resource()
This commit is contained in:
commit
e2ceaa867d
@ -24,7 +24,7 @@ properties:
|
||||
- const: allwinner,sun8i-v3s-de2-clk
|
||||
- const: allwinner,sun50i-a64-de2-clk
|
||||
- const: allwinner,sun50i-h5-de2-clk
|
||||
- const: allwinner,sun50i-h6-de2-clk
|
||||
- const: allwinner,sun50i-h6-de3-clk
|
||||
- items:
|
||||
- const: allwinner,sun8i-r40-de2-clk
|
||||
- const: allwinner,sun8i-h3-de2-clk
|
||||
|
@ -0,0 +1,185 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/samsung,exynos850-clock.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Samsung Exynos850 SoC clock controller
|
||||
|
||||
maintainers:
|
||||
- Sam Protsenko <semen.protsenko@linaro.org>
|
||||
- Chanwoo Choi <cw00.choi@samsung.com>
|
||||
- Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>
|
||||
- Sylwester Nawrocki <s.nawrocki@samsung.com>
|
||||
- Tomasz Figa <tomasz.figa@gmail.com>
|
||||
|
||||
description: |
|
||||
Exynos850 clock controller is comprised of several CMU units, generating
|
||||
clocks for different domains. Those CMU units are modeled as separate device
|
||||
tree nodes, and might depend on each other. Root clocks in that clock tree are
|
||||
two external clocks:: OSCCLK (26 MHz) and RTCCLK (32768 Hz). Those external
|
||||
clocks must be defined as fixed-rate clocks in dts.
|
||||
|
||||
CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and
|
||||
dividers; all other leaf clocks (other CMUs) are usually derived from CMU_TOP.
|
||||
|
||||
Each clock is assigned an identifier and client nodes can use this identifier
|
||||
to specify the clock which they consume. All clocks available for usage
|
||||
in clock consumer nodes are defined as preprocessor macros in
|
||||
'dt-bindings/clock/exynos850.h' header.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- samsung,exynos850-cmu-top
|
||||
- samsung,exynos850-cmu-core
|
||||
- samsung,exynos850-cmu-dpu
|
||||
- samsung,exynos850-cmu-hsi
|
||||
- samsung,exynos850-cmu-peri
|
||||
|
||||
clocks:
|
||||
minItems: 1
|
||||
maxItems: 5
|
||||
|
||||
clock-names:
|
||||
minItems: 1
|
||||
maxItems: 5
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: samsung,exynos850-cmu-top
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: External reference clock (26 MHz)
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: oscclk
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: samsung,exynos850-cmu-core
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: External reference clock (26 MHz)
|
||||
- description: CMU_CORE bus clock (from CMU_TOP)
|
||||
- description: CCI clock (from CMU_TOP)
|
||||
- description: eMMC clock (from CMU_TOP)
|
||||
- description: SSS clock (from CMU_TOP)
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: oscclk
|
||||
- const: dout_core_bus
|
||||
- const: dout_core_cci
|
||||
- const: dout_core_mmc_embd
|
||||
- const: dout_core_sss
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: samsung,exynos850-cmu-dpu
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: External reference clock (26 MHz)
|
||||
- description: DPU clock (from CMU_TOP)
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: oscclk
|
||||
- const: dout_dpu
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: samsung,exynos850-cmu-hsi
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: External reference clock (26 MHz)
|
||||
- description: External RTC clock (32768 Hz)
|
||||
- description: CMU_HSI bus clock (from CMU_TOP)
|
||||
- description: SD card clock (from CMU_TOP)
|
||||
- description: "USB 2.0 DRD clock (from CMU_TOP)"
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: oscclk
|
||||
- const: rtcclk
|
||||
- const: dout_hsi_bus
|
||||
- const: dout_hsi_mmc_card
|
||||
- const: dout_hsi_usb20drd
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: samsung,exynos850-cmu-peri
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: External reference clock (26 MHz)
|
||||
- description: CMU_PERI bus clock (from CMU_TOP)
|
||||
- description: UART clock (from CMU_TOP)
|
||||
- description: Parent clock for HSI2C and SPI (from CMU_TOP)
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: oscclk
|
||||
- const: dout_peri_bus
|
||||
- const: dout_peri_uart
|
||||
- const: dout_peri_ip
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#clock-cells"
|
||||
- clocks
|
||||
- clock-names
|
||||
- reg
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
# Clock controller node for CMU_PERI
|
||||
- |
|
||||
#include <dt-bindings/clock/exynos850.h>
|
||||
|
||||
cmu_peri: clock-controller@10030000 {
|
||||
compatible = "samsung,exynos850-cmu-peri";
|
||||
reg = <0x10030000 0x8000>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
clocks = <&oscclk>, <&cmu_top CLK_DOUT_PERI_BUS>,
|
||||
<&cmu_top CLK_DOUT_PERI_UART>,
|
||||
<&cmu_top CLK_DOUT_PERI_IP>;
|
||||
clock-names = "oscclk", "dout_peri_bus",
|
||||
"dout_peri_uart", "dout_peri_ip";
|
||||
};
|
||||
|
||||
...
|
@ -42,6 +42,29 @@ static unsigned long clk_composite_recalc_rate(struct clk_hw *hw,
|
||||
return rate_ops->recalc_rate(rate_hw, parent_rate);
|
||||
}
|
||||
|
||||
static int clk_composite_determine_rate_for_parent(struct clk_hw *rate_hw,
|
||||
struct clk_rate_request *req,
|
||||
struct clk_hw *parent_hw,
|
||||
const struct clk_ops *rate_ops)
|
||||
{
|
||||
long rate;
|
||||
|
||||
req->best_parent_hw = parent_hw;
|
||||
req->best_parent_rate = clk_hw_get_rate(parent_hw);
|
||||
|
||||
if (rate_ops->determine_rate)
|
||||
return rate_ops->determine_rate(rate_hw, req);
|
||||
|
||||
rate = rate_ops->round_rate(rate_hw, req->rate,
|
||||
&req->best_parent_rate);
|
||||
if (rate < 0)
|
||||
return rate;
|
||||
|
||||
req->rate = rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clk_composite_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
@ -51,54 +74,56 @@ static int clk_composite_determine_rate(struct clk_hw *hw,
|
||||
struct clk_hw *rate_hw = composite->rate_hw;
|
||||
struct clk_hw *mux_hw = composite->mux_hw;
|
||||
struct clk_hw *parent;
|
||||
unsigned long parent_rate;
|
||||
long tmp_rate, best_rate = 0;
|
||||
unsigned long rate_diff;
|
||||
unsigned long best_rate_diff = ULONG_MAX;
|
||||
long rate;
|
||||
int i;
|
||||
unsigned long best_rate = 0;
|
||||
int i, ret;
|
||||
|
||||
if (rate_hw && rate_ops && rate_ops->determine_rate) {
|
||||
__clk_hw_set_clk(rate_hw, hw);
|
||||
return rate_ops->determine_rate(rate_hw, req);
|
||||
} else if (rate_hw && rate_ops && rate_ops->round_rate &&
|
||||
mux_hw && mux_ops && mux_ops->set_parent) {
|
||||
if (rate_hw && rate_ops &&
|
||||
(rate_ops->determine_rate || rate_ops->round_rate) &&
|
||||
mux_hw && mux_ops && mux_ops->set_parent) {
|
||||
req->best_parent_hw = NULL;
|
||||
|
||||
if (clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT) {
|
||||
struct clk_rate_request tmp_req = *req;
|
||||
|
||||
parent = clk_hw_get_parent(mux_hw);
|
||||
req->best_parent_hw = parent;
|
||||
req->best_parent_rate = clk_hw_get_rate(parent);
|
||||
|
||||
rate = rate_ops->round_rate(rate_hw, req->rate,
|
||||
&req->best_parent_rate);
|
||||
if (rate < 0)
|
||||
return rate;
|
||||
ret = clk_composite_determine_rate_for_parent(rate_hw,
|
||||
&tmp_req,
|
||||
parent,
|
||||
rate_ops);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
req->rate = tmp_req.rate;
|
||||
req->best_parent_rate = tmp_req.best_parent_rate;
|
||||
|
||||
req->rate = rate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < clk_hw_get_num_parents(mux_hw); i++) {
|
||||
struct clk_rate_request tmp_req = *req;
|
||||
|
||||
parent = clk_hw_get_parent_by_index(mux_hw, i);
|
||||
if (!parent)
|
||||
continue;
|
||||
|
||||
parent_rate = clk_hw_get_rate(parent);
|
||||
|
||||
tmp_rate = rate_ops->round_rate(rate_hw, req->rate,
|
||||
&parent_rate);
|
||||
if (tmp_rate < 0)
|
||||
ret = clk_composite_determine_rate_for_parent(rate_hw,
|
||||
&tmp_req,
|
||||
parent,
|
||||
rate_ops);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
rate_diff = abs(req->rate - tmp_rate);
|
||||
rate_diff = abs(req->rate - tmp_req.rate);
|
||||
|
||||
if (!rate_diff || !req->best_parent_hw
|
||||
|| best_rate_diff > rate_diff) {
|
||||
req->best_parent_hw = parent;
|
||||
req->best_parent_rate = parent_rate;
|
||||
req->best_parent_rate = tmp_req.best_parent_rate;
|
||||
best_rate_diff = rate_diff;
|
||||
best_rate = tmp_rate;
|
||||
best_rate = tmp_req.rate;
|
||||
}
|
||||
|
||||
if (!rate_diff)
|
||||
@ -107,6 +132,9 @@ static int clk_composite_determine_rate(struct clk_hw *hw,
|
||||
|
||||
req->rate = best_rate;
|
||||
return 0;
|
||||
} else if (rate_hw && rate_ops && rate_ops->determine_rate) {
|
||||
__clk_hw_set_clk(rate_hw, hw);
|
||||
return rate_ops->determine_rate(rate_hw, req);
|
||||
} else if (mux_hw && mux_ops && mux_ops->determine_rate) {
|
||||
__clk_hw_set_clk(mux_hw, hw);
|
||||
return mux_ops->determine_rate(mux_hw, req);
|
||||
|
@ -118,6 +118,56 @@ static struct clk_regmap meson8b_fixed_pll = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_fixed_factor hdmi_pll_dco_in = {
|
||||
.mult = 2,
|
||||
.div = 1,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hdmi_pll_dco_in",
|
||||
.ops = &clk_fixed_factor_ops,
|
||||
.parent_data = &(const struct clk_parent_data) {
|
||||
.fw_name = "xtal",
|
||||
.index = -1,
|
||||
},
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* Taken from the vendor driver for the 2970/2975MHz (both only differ in the
|
||||
* FRAC part in HHI_VID_PLL_CNTL2) where these values are identical for Meson8,
|
||||
* Meson8b and Meson8m2. This doubles the input (or output - it's not clear
|
||||
* which one but the result is the same) clock. The vendor driver additionally
|
||||
* has the following comment about: "optimise HPLL VCO 2.97GHz performance".
|
||||
*/
|
||||
static const struct reg_sequence meson8b_hdmi_pll_init_regs[] = {
|
||||
{ .reg = HHI_VID_PLL_CNTL2, .def = 0x69c84000 },
|
||||
{ .reg = HHI_VID_PLL_CNTL3, .def = 0x8a46c023 },
|
||||
{ .reg = HHI_VID_PLL_CNTL4, .def = 0x4123b100 },
|
||||
{ .reg = HHI_VID_PLL_CNTL5, .def = 0x00012385 },
|
||||
{ .reg = HHI_VID2_PLL_CNTL2, .def = 0x0430a800 },
|
||||
};
|
||||
|
||||
static const struct pll_params_table hdmi_pll_params_table[] = {
|
||||
PLL_PARAMS(40, 1),
|
||||
PLL_PARAMS(42, 1),
|
||||
PLL_PARAMS(44, 1),
|
||||
PLL_PARAMS(45, 1),
|
||||
PLL_PARAMS(49, 1),
|
||||
PLL_PARAMS(52, 1),
|
||||
PLL_PARAMS(54, 1),
|
||||
PLL_PARAMS(56, 1),
|
||||
PLL_PARAMS(59, 1),
|
||||
PLL_PARAMS(60, 1),
|
||||
PLL_PARAMS(61, 1),
|
||||
PLL_PARAMS(62, 1),
|
||||
PLL_PARAMS(64, 1),
|
||||
PLL_PARAMS(66, 1),
|
||||
PLL_PARAMS(68, 1),
|
||||
PLL_PARAMS(71, 1),
|
||||
PLL_PARAMS(82, 1),
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct clk_regmap meson8b_hdmi_pll_dco = {
|
||||
.data = &(struct meson_clk_pll_data){
|
||||
.en = {
|
||||
@ -150,15 +200,16 @@ static struct clk_regmap meson8b_hdmi_pll_dco = {
|
||||
.shift = 29,
|
||||
.width = 1,
|
||||
},
|
||||
.table = hdmi_pll_params_table,
|
||||
.init_regs = meson8b_hdmi_pll_init_regs,
|
||||
.init_count = ARRAY_SIZE(meson8b_hdmi_pll_init_regs),
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
/* sometimes also called "HPLL" or "HPLL PLL" */
|
||||
.name = "hdmi_pll_dco",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.parent_data = &(const struct clk_parent_data) {
|
||||
.fw_name = "xtal",
|
||||
.name = "xtal",
|
||||
.index = -1,
|
||||
.ops = &meson_clk_pll_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&hdmi_pll_dco_in.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
},
|
||||
@ -173,7 +224,7 @@ static struct clk_regmap meson8b_hdmi_pll_lvds_out = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hdmi_pll_lvds_out",
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.ops = &clk_regmap_divider_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_hdmi_pll_dco.hw
|
||||
},
|
||||
@ -191,7 +242,7 @@ static struct clk_regmap meson8b_hdmi_pll_hdmi_out = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hdmi_pll_hdmi_out",
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.ops = &clk_regmap_divider_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_hdmi_pll_dco.hw
|
||||
},
|
||||
@ -1045,6 +1096,23 @@ static struct clk_regmap meson8b_l2_dram_clk_gate = {
|
||||
},
|
||||
};
|
||||
|
||||
/* also called LVDS_CLK_EN */
|
||||
static struct clk_regmap meson8b_vid_pll_lvds_en = {
|
||||
.data = &(struct clk_regmap_gate_data){
|
||||
.offset = HHI_VID_DIVIDER_CNTL,
|
||||
.bit_idx = 11,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vid_pll_lvds_en",
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_hdmi_pll_lvds_out.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap meson8b_vid_pll_in_sel = {
|
||||
.data = &(struct clk_regmap_mux_data){
|
||||
.offset = HHI_VID_DIVIDER_CNTL,
|
||||
@ -1053,7 +1121,7 @@ static struct clk_regmap meson8b_vid_pll_in_sel = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vid_pll_in_sel",
|
||||
.ops = &clk_regmap_mux_ro_ops,
|
||||
.ops = &clk_regmap_mux_ops,
|
||||
/*
|
||||
* TODO: depending on the SoC there is also a second parent:
|
||||
* Meson8: unknown
|
||||
@ -1061,7 +1129,7 @@ static struct clk_regmap meson8b_vid_pll_in_sel = {
|
||||
* Meson8m2: vid2_pll
|
||||
*/
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_hdmi_pll_lvds_out.hw
|
||||
&meson8b_vid_pll_lvds_en.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
@ -1075,7 +1143,7 @@ static struct clk_regmap meson8b_vid_pll_in_en = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vid_pll_in_en",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vid_pll_in_sel.hw
|
||||
},
|
||||
@ -1092,7 +1160,7 @@ static struct clk_regmap meson8b_vid_pll_pre_div = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vid_pll_pre_div",
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.ops = &clk_regmap_divider_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vid_pll_in_en.hw
|
||||
},
|
||||
@ -1109,7 +1177,7 @@ static struct clk_regmap meson8b_vid_pll_post_div = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vid_pll_post_div",
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.ops = &clk_regmap_divider_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vid_pll_pre_div.hw
|
||||
},
|
||||
@ -1126,7 +1194,7 @@ static struct clk_regmap meson8b_vid_pll = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vid_pll",
|
||||
.ops = &clk_regmap_mux_ro_ops,
|
||||
.ops = &clk_regmap_mux_ops,
|
||||
/* TODO: parent 0x2 is vid_pll_pre_div_mult7_div2 */
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vid_pll_pre_div.hw,
|
||||
@ -1145,7 +1213,7 @@ static struct clk_regmap meson8b_vid_pll_final_div = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vid_pll_final_div",
|
||||
.ops = &clk_regmap_divider_ro_ops,
|
||||
.ops = &clk_regmap_divider_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vid_pll.hw
|
||||
},
|
||||
@ -1172,10 +1240,10 @@ static struct clk_regmap meson8b_vclk_in_sel = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vclk_in_sel",
|
||||
.ops = &clk_regmap_mux_ro_ops,
|
||||
.ops = &clk_regmap_mux_ops,
|
||||
.parent_hws = meson8b_vclk_mux_parent_hws,
|
||||
.num_parents = ARRAY_SIZE(meson8b_vclk_mux_parent_hws),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
},
|
||||
};
|
||||
|
||||
@ -1186,7 +1254,7 @@ static struct clk_regmap meson8b_vclk_in_en = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vclk_in_en",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vclk_in_sel.hw
|
||||
},
|
||||
@ -1202,7 +1270,7 @@ static struct clk_regmap meson8b_vclk_en = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vclk_en",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vclk_in_en.hw
|
||||
},
|
||||
@ -1218,7 +1286,7 @@ static struct clk_regmap meson8b_vclk_div1_gate = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vclk_div1_en",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vclk_en.hw
|
||||
},
|
||||
@ -1248,7 +1316,7 @@ static struct clk_regmap meson8b_vclk_div2_div_gate = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vclk_div2_en",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vclk_div2_div.hw
|
||||
},
|
||||
@ -1278,7 +1346,7 @@ static struct clk_regmap meson8b_vclk_div4_div_gate = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vclk_div4_en",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vclk_div4_div.hw
|
||||
},
|
||||
@ -1308,7 +1376,7 @@ static struct clk_regmap meson8b_vclk_div6_div_gate = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vclk_div6_en",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vclk_div6_div.hw
|
||||
},
|
||||
@ -1338,7 +1406,7 @@ static struct clk_regmap meson8b_vclk_div12_div_gate = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vclk_div12_en",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vclk_div12_div.hw
|
||||
},
|
||||
@ -1355,10 +1423,10 @@ static struct clk_regmap meson8b_vclk2_in_sel = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vclk2_in_sel",
|
||||
.ops = &clk_regmap_mux_ro_ops,
|
||||
.ops = &clk_regmap_mux_ops,
|
||||
.parent_hws = meson8b_vclk_mux_parent_hws,
|
||||
.num_parents = ARRAY_SIZE(meson8b_vclk_mux_parent_hws),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT,
|
||||
},
|
||||
};
|
||||
|
||||
@ -1369,7 +1437,7 @@ static struct clk_regmap meson8b_vclk2_clk_in_en = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vclk2_in_en",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vclk2_in_sel.hw
|
||||
},
|
||||
@ -1385,7 +1453,7 @@ static struct clk_regmap meson8b_vclk2_clk_en = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vclk2_en",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vclk2_clk_in_en.hw
|
||||
},
|
||||
@ -1401,7 +1469,7 @@ static struct clk_regmap meson8b_vclk2_div1_gate = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vclk2_div1_en",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vclk2_clk_en.hw
|
||||
},
|
||||
@ -1431,7 +1499,7 @@ static struct clk_regmap meson8b_vclk2_div2_div_gate = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vclk2_div2_en",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vclk2_div2_div.hw
|
||||
},
|
||||
@ -1461,7 +1529,7 @@ static struct clk_regmap meson8b_vclk2_div4_div_gate = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vclk2_div4_en",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vclk2_div4_div.hw
|
||||
},
|
||||
@ -1491,7 +1559,7 @@ static struct clk_regmap meson8b_vclk2_div6_div_gate = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vclk2_div6_en",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vclk2_div6_div.hw
|
||||
},
|
||||
@ -1521,7 +1589,7 @@ static struct clk_regmap meson8b_vclk2_div12_div_gate = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "vclk2_div12_en",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_vclk2_div12_div.hw
|
||||
},
|
||||
@ -1546,7 +1614,7 @@ static struct clk_regmap meson8b_cts_enct_sel = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cts_enct_sel",
|
||||
.ops = &clk_regmap_mux_ro_ops,
|
||||
.ops = &clk_regmap_mux_ops,
|
||||
.parent_hws = meson8b_vclk_enc_mux_parent_hws,
|
||||
.num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
@ -1560,7 +1628,7 @@ static struct clk_regmap meson8b_cts_enct = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cts_enct",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_cts_enct_sel.hw
|
||||
},
|
||||
@ -1577,7 +1645,7 @@ static struct clk_regmap meson8b_cts_encp_sel = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cts_encp_sel",
|
||||
.ops = &clk_regmap_mux_ro_ops,
|
||||
.ops = &clk_regmap_mux_ops,
|
||||
.parent_hws = meson8b_vclk_enc_mux_parent_hws,
|
||||
.num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
@ -1591,7 +1659,7 @@ static struct clk_regmap meson8b_cts_encp = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cts_encp",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_cts_encp_sel.hw
|
||||
},
|
||||
@ -1608,7 +1676,7 @@ static struct clk_regmap meson8b_cts_enci_sel = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cts_enci_sel",
|
||||
.ops = &clk_regmap_mux_ro_ops,
|
||||
.ops = &clk_regmap_mux_ops,
|
||||
.parent_hws = meson8b_vclk_enc_mux_parent_hws,
|
||||
.num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
@ -1622,7 +1690,7 @@ static struct clk_regmap meson8b_cts_enci = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cts_enci",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_cts_enci_sel.hw
|
||||
},
|
||||
@ -1639,7 +1707,7 @@ static struct clk_regmap meson8b_hdmi_tx_pixel_sel = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hdmi_tx_pixel_sel",
|
||||
.ops = &clk_regmap_mux_ro_ops,
|
||||
.ops = &clk_regmap_mux_ops,
|
||||
.parent_hws = meson8b_vclk_enc_mux_parent_hws,
|
||||
.num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
@ -1653,7 +1721,7 @@ static struct clk_regmap meson8b_hdmi_tx_pixel = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hdmi_tx_pixel",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_hdmi_tx_pixel_sel.hw
|
||||
},
|
||||
@ -1678,7 +1746,7 @@ static struct clk_regmap meson8b_cts_encl_sel = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cts_encl_sel",
|
||||
.ops = &clk_regmap_mux_ro_ops,
|
||||
.ops = &clk_regmap_mux_ops,
|
||||
.parent_hws = meson8b_vclk2_enc_mux_parent_hws,
|
||||
.num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parent_hws),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
@ -1692,7 +1760,7 @@ static struct clk_regmap meson8b_cts_encl = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cts_encl",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_cts_encl_sel.hw
|
||||
},
|
||||
@ -1709,7 +1777,7 @@ static struct clk_regmap meson8b_cts_vdac0_sel = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cts_vdac0_sel",
|
||||
.ops = &clk_regmap_mux_ro_ops,
|
||||
.ops = &clk_regmap_mux_ops,
|
||||
.parent_hws = meson8b_vclk2_enc_mux_parent_hws,
|
||||
.num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parent_hws),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
@ -1723,7 +1791,7 @@ static struct clk_regmap meson8b_cts_vdac0 = {
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cts_vdac0",
|
||||
.ops = &clk_regmap_gate_ro_ops,
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&meson8b_cts_vdac0_sel.hw
|
||||
},
|
||||
@ -2905,6 +2973,8 @@ static struct clk_hw_onecell_data meson8_hw_onecell_data = {
|
||||
[CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw,
|
||||
[CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw,
|
||||
[CLKID_CTS_I958] = &meson8b_cts_i958.hw,
|
||||
[CLKID_VID_PLL_LVDS_EN] = &meson8b_vid_pll_lvds_en.hw,
|
||||
[CLKID_HDMI_PLL_DCO_IN] = &hdmi_pll_dco_in.hw,
|
||||
[CLK_NR_CLKS] = NULL,
|
||||
},
|
||||
.num = CLK_NR_CLKS,
|
||||
@ -3122,6 +3192,8 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
|
||||
[CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw,
|
||||
[CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw,
|
||||
[CLKID_CTS_I958] = &meson8b_cts_i958.hw,
|
||||
[CLKID_VID_PLL_LVDS_EN] = &meson8b_vid_pll_lvds_en.hw,
|
||||
[CLKID_HDMI_PLL_DCO_IN] = &hdmi_pll_dco_in.hw,
|
||||
[CLK_NR_CLKS] = NULL,
|
||||
},
|
||||
.num = CLK_NR_CLKS,
|
||||
@ -3341,6 +3413,8 @@ static struct clk_hw_onecell_data meson8m2_hw_onecell_data = {
|
||||
[CLKID_CTS_MCLK_I958_DIV] = &meson8b_cts_mclk_i958_div.hw,
|
||||
[CLKID_CTS_MCLK_I958] = &meson8b_cts_mclk_i958.hw,
|
||||
[CLKID_CTS_I958] = &meson8b_cts_i958.hw,
|
||||
[CLKID_VID_PLL_LVDS_EN] = &meson8b_vid_pll_lvds_en.hw,
|
||||
[CLKID_HDMI_PLL_DCO_IN] = &hdmi_pll_dco_in.hw,
|
||||
[CLK_NR_CLKS] = NULL,
|
||||
},
|
||||
.num = CLK_NR_CLKS,
|
||||
@ -3539,6 +3613,7 @@ static struct clk_regmap *const meson8b_clk_regmaps[] = {
|
||||
&meson8b_cts_mclk_i958_div,
|
||||
&meson8b_cts_mclk_i958,
|
||||
&meson8b_cts_i958,
|
||||
&meson8b_vid_pll_lvds_en,
|
||||
};
|
||||
|
||||
static const struct meson8b_clk_reset_line {
|
||||
|
@ -51,6 +51,16 @@
|
||||
#define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */
|
||||
#define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */
|
||||
#define HHI_VID_PLL_CNTL2 0x324 /* 0xc9 offset in data sheet */
|
||||
#define HHI_VID_PLL_CNTL3 0x328 /* 0xca offset in data sheet */
|
||||
#define HHI_VID_PLL_CNTL4 0x32c /* 0xcb offset in data sheet */
|
||||
#define HHI_VID_PLL_CNTL5 0x330 /* 0xcc offset in data sheet */
|
||||
#define HHI_VID_PLL_CNTL6 0x334 /* 0xcd offset in data sheet */
|
||||
#define HHI_VID2_PLL_CNTL 0x380 /* 0xe0 offset in data sheet */
|
||||
#define HHI_VID2_PLL_CNTL2 0x384 /* 0xe1 offset in data sheet */
|
||||
#define HHI_VID2_PLL_CNTL3 0x388 /* 0xe2 offset in data sheet */
|
||||
#define HHI_VID2_PLL_CNTL4 0x38c /* 0xe3 offset in data sheet */
|
||||
#define HHI_VID2_PLL_CNTL5 0x390 /* 0xe4 offset in data sheet */
|
||||
#define HHI_VID2_PLL_CNTL6 0x394 /* 0xe5 offset in data sheet */
|
||||
|
||||
/*
|
||||
* MPLL register offeset taken from the S905 datasheet. Vendor kernel source
|
||||
@ -107,14 +117,11 @@
|
||||
#define CLKID_PERIPH_SEL 125
|
||||
#define CLKID_AXI_SEL 127
|
||||
#define CLKID_L2_DRAM_SEL 129
|
||||
#define CLKID_HDMI_PLL_LVDS_OUT 131
|
||||
#define CLKID_HDMI_PLL_HDMI_OUT 132
|
||||
#define CLKID_HDMI_PLL_LVDS_OUT 131
|
||||
#define CLKID_VID_PLL_IN_SEL 133
|
||||
#define CLKID_VID_PLL_IN_EN 134
|
||||
#define CLKID_VID_PLL_PRE_DIV 135
|
||||
#define CLKID_VID_PLL_POST_DIV 136
|
||||
#define CLKID_VID_PLL_FINAL_DIV 137
|
||||
#define CLKID_VCLK_IN_SEL 138
|
||||
#define CLKID_VCLK_IN_EN 139
|
||||
#define CLKID_VCLK_DIV1 140
|
||||
#define CLKID_VCLK_DIV2_DIV 141
|
||||
@ -125,7 +132,6 @@
|
||||
#define CLKID_VCLK_DIV6 146
|
||||
#define CLKID_VCLK_DIV12_DIV 147
|
||||
#define CLKID_VCLK_DIV12 148
|
||||
#define CLKID_VCLK2_IN_SEL 149
|
||||
#define CLKID_VCLK2_IN_EN 150
|
||||
#define CLKID_VCLK2_DIV1 151
|
||||
#define CLKID_VCLK2_DIV2_DIV 152
|
||||
@ -137,17 +143,11 @@
|
||||
#define CLKID_VCLK2_DIV12_DIV 158
|
||||
#define CLKID_VCLK2_DIV12 159
|
||||
#define CLKID_CTS_ENCT_SEL 160
|
||||
#define CLKID_CTS_ENCT 161
|
||||
#define CLKID_CTS_ENCP_SEL 162
|
||||
#define CLKID_CTS_ENCP 163
|
||||
#define CLKID_CTS_ENCI_SEL 164
|
||||
#define CLKID_CTS_ENCI 165
|
||||
#define CLKID_HDMI_TX_PIXEL_SEL 166
|
||||
#define CLKID_HDMI_TX_PIXEL 167
|
||||
#define CLKID_CTS_ENCL_SEL 168
|
||||
#define CLKID_CTS_ENCL 169
|
||||
#define CLKID_CTS_VDAC0_SEL 170
|
||||
#define CLKID_CTS_VDAC0 171
|
||||
#define CLKID_HDMI_SYS_SEL 172
|
||||
#define CLKID_HDMI_SYS_DIV 173
|
||||
#define CLKID_MALI_0_SEL 175
|
||||
@ -182,8 +182,10 @@
|
||||
#define CLKID_CTS_MCLK_I958_DIV 211
|
||||
#define CLKID_VCLK_EN 214
|
||||
#define CLKID_VCLK2_EN 215
|
||||
#define CLKID_VID_PLL_LVDS_EN 216
|
||||
#define CLKID_HDMI_PLL_DCO_IN 217
|
||||
|
||||
#define CLK_NR_CLKS 216
|
||||
#define CLK_NR_CLKS 218
|
||||
|
||||
/*
|
||||
* include the CLKID and RESETID that have
|
||||
|
@ -67,7 +67,8 @@ config EXYNOS_5420_COMMON_CLK
|
||||
depends on COMMON_CLK_SAMSUNG
|
||||
help
|
||||
Support for the clock controller present on the Samsung
|
||||
Exynos5420 SoCs. Choose Y here only if you build for this SoC.
|
||||
Exynos5420/Exynos5422/Exynos5800 SoCs. Choose Y here only if you
|
||||
build for this SoC.
|
||||
|
||||
config EXYNOS_ARM64_COMMON_CLK
|
||||
bool "Samsung Exynos ARMv8-family clock controller support" if COMPILE_TEST
|
||||
@ -79,38 +80,47 @@ config EXYNOS_AUDSS_CLK_CON
|
||||
default y if ARCH_EXYNOS
|
||||
help
|
||||
Support for the Audio Subsystem CLKCON clock controller present
|
||||
on some Exynos SoC variants. Choose M or Y here if you want to
|
||||
use audio devices such as I2S, PCM, etc.
|
||||
on some Samsung Exynos SoC variants. Choose M or Y here if you want
|
||||
to use audio devices such as I2S, PCM, etc.
|
||||
|
||||
config EXYNOS_CLKOUT
|
||||
tristate "Samsung Exynos clock output driver"
|
||||
depends on COMMON_CLK_SAMSUNG
|
||||
default y if ARCH_EXYNOS
|
||||
help
|
||||
Support for the clock output (XCLKOUT) present on some of Exynos SoC
|
||||
variants. Usually the XCLKOUT is used to monitor the status of the
|
||||
certains clocks from SoC, but it could also be tied to other devices
|
||||
as an input clock.
|
||||
Support for the clock output (XCLKOUT) present on some of Samsung
|
||||
Exynos SoC variants. Usually the XCLKOUT is used to monitor the
|
||||
status of the certains clocks from SoC, but it could also be tied to
|
||||
other devices as an input clock.
|
||||
|
||||
# For S3C24XX platforms, select following symbols:
|
||||
config S3C2410_COMMON_CLK
|
||||
bool "Samsung S3C2410 clock controller support" if COMPILE_TEST
|
||||
select COMMON_CLK_SAMSUNG
|
||||
help
|
||||
Build the s3c2410 clock driver based on the common clock framework.
|
||||
Support for the clock controller present on the Samsung
|
||||
S3C2410/S3C2440/S3C2442 SoCs. Choose Y here only if you build for
|
||||
this SoC.
|
||||
|
||||
config S3C2410_COMMON_DCLK
|
||||
bool
|
||||
select COMMON_CLK_SAMSUNG
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
Temporary symbol to build the dclk driver based on the common clock
|
||||
framework.
|
||||
Support for the dclk clock controller present on the Samsung
|
||||
S3C2410/S3C2412/S3C2440/S3C2443 SoCs. Choose Y here only if you build
|
||||
for this SoC.
|
||||
|
||||
config S3C2412_COMMON_CLK
|
||||
bool "Samsung S3C2412 clock controller support" if COMPILE_TEST
|
||||
select COMMON_CLK_SAMSUNG
|
||||
help
|
||||
Support for the clock controller present on the Samsung S3C2412 SoCs.
|
||||
Choose Y here only if you build for this SoC.
|
||||
|
||||
config S3C2443_COMMON_CLK
|
||||
bool "Samsung S3C2443 clock controller support" if COMPILE_TEST
|
||||
select COMMON_CLK_SAMSUNG
|
||||
help
|
||||
Support for the clock controller present on the Samsung
|
||||
S3C2416/S3C2443 SoCs. Choose Y here only if you build for this SoC.
|
||||
|
@ -17,6 +17,7 @@ obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o
|
||||
obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
|
||||
obj-$(CONFIG_EXYNOS_CLKOUT) += clk-exynos-clkout.o
|
||||
obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos7.o
|
||||
obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos850.o
|
||||
obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
|
||||
obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
|
||||
obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
|
||||
|
@ -469,3 +469,21 @@ free_cpuclk:
|
||||
kfree(cpuclk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __init samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
|
||||
const struct samsung_cpu_clock *list, unsigned int nr_clk)
|
||||
{
|
||||
unsigned int idx;
|
||||
unsigned int num_cfgs;
|
||||
struct clk_hw **hws = ctx->clk_data.hws;
|
||||
|
||||
for (idx = 0; idx < nr_clk; idx++, list++) {
|
||||
/* find count of configuration rates in cfg */
|
||||
for (num_cfgs = 0; list->cfg[num_cfgs].prate != 0; )
|
||||
num_cfgs++;
|
||||
|
||||
exynos_register_cpu_clock(ctx, list->id, list->name, hws[list->parent_id],
|
||||
hws[list->alt_parent_id], list->offset, list->cfg, num_cfgs,
|
||||
list->flags);
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +129,6 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
|
||||
struct clk *pll_ref, *pll_in, *cdclk, *sclk_audio, *sclk_pcm_in;
|
||||
const struct exynos_audss_clk_drvdata *variant;
|
||||
struct clk_hw **clk_table;
|
||||
struct resource *res;
|
||||
struct device *dev = &pdev->dev;
|
||||
int i, ret = 0;
|
||||
|
||||
@ -137,8 +136,7 @@ static int exynos_audss_clk_probe(struct platform_device *pdev)
|
||||
if (!variant)
|
||||
return -EINVAL;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg_base = devm_ioremap_resource(dev, res);
|
||||
reg_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg_base))
|
||||
return PTR_ERR(reg_base);
|
||||
|
||||
|
@ -110,11 +110,9 @@ static int __init exynos4x12_isp_clk_probe(struct platform_device *pdev)
|
||||
struct samsung_clk_provider *ctx;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
struct resource *res;
|
||||
void __iomem *reg_base;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg_base = devm_ioremap_resource(dev, res);
|
||||
reg_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg_base))
|
||||
return PTR_ERR(reg_base);
|
||||
|
||||
|
@ -3675,44 +3675,32 @@ static const struct exynos_cpuclk_cfg_data exynos5433_apolloclk_d[] __initconst
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
static const struct samsung_cpu_clock apollo_cpu_clks[] __initconst = {
|
||||
CPU_CLK(CLK_SCLK_APOLLO, "apolloclk", CLK_MOUT_APOLLO_PLL,
|
||||
CLK_MOUT_BUS_PLL_APOLLO_USER,
|
||||
CLK_CPU_HAS_E5433_REGS_LAYOUT, 0x200,
|
||||
exynos5433_apolloclk_d),
|
||||
};
|
||||
|
||||
static const struct samsung_cmu_info apollo_cmu_info __initconst = {
|
||||
.pll_clks = apollo_pll_clks,
|
||||
.nr_pll_clks = ARRAY_SIZE(apollo_pll_clks),
|
||||
.mux_clks = apollo_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(apollo_mux_clks),
|
||||
.div_clks = apollo_div_clks,
|
||||
.nr_div_clks = ARRAY_SIZE(apollo_div_clks),
|
||||
.gate_clks = apollo_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(apollo_gate_clks),
|
||||
.cpu_clks = apollo_cpu_clks,
|
||||
.nr_cpu_clks = ARRAY_SIZE(apollo_cpu_clks),
|
||||
.nr_clk_ids = APOLLO_NR_CLK,
|
||||
.clk_regs = apollo_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(apollo_clk_regs),
|
||||
};
|
||||
|
||||
static void __init exynos5433_cmu_apollo_init(struct device_node *np)
|
||||
{
|
||||
void __iomem *reg_base;
|
||||
struct samsung_clk_provider *ctx;
|
||||
struct clk_hw **hws;
|
||||
|
||||
reg_base = of_iomap(np, 0);
|
||||
if (!reg_base) {
|
||||
panic("%s: failed to map registers\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx = samsung_clk_init(np, reg_base, APOLLO_NR_CLK);
|
||||
if (!ctx) {
|
||||
panic("%s: unable to allocate ctx\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
samsung_clk_register_pll(ctx, apollo_pll_clks,
|
||||
ARRAY_SIZE(apollo_pll_clks), reg_base);
|
||||
samsung_clk_register_mux(ctx, apollo_mux_clks,
|
||||
ARRAY_SIZE(apollo_mux_clks));
|
||||
samsung_clk_register_div(ctx, apollo_div_clks,
|
||||
ARRAY_SIZE(apollo_div_clks));
|
||||
samsung_clk_register_gate(ctx, apollo_gate_clks,
|
||||
ARRAY_SIZE(apollo_gate_clks));
|
||||
|
||||
hws = ctx->clk_data.hws;
|
||||
|
||||
exynos_register_cpu_clock(ctx, CLK_SCLK_APOLLO, "apolloclk",
|
||||
hws[CLK_MOUT_APOLLO_PLL], hws[CLK_MOUT_BUS_PLL_APOLLO_USER], 0x200,
|
||||
exynos5433_apolloclk_d, ARRAY_SIZE(exynos5433_apolloclk_d),
|
||||
CLK_CPU_HAS_E5433_REGS_LAYOUT);
|
||||
|
||||
samsung_clk_sleep_init(reg_base, apollo_clk_regs,
|
||||
ARRAY_SIZE(apollo_clk_regs));
|
||||
|
||||
samsung_clk_of_add_provider(np, ctx);
|
||||
samsung_cmu_register_one(np, &apollo_cmu_info);
|
||||
}
|
||||
CLK_OF_DECLARE(exynos5433_cmu_apollo, "samsung,exynos5433-cmu-apollo",
|
||||
exynos5433_cmu_apollo_init);
|
||||
@ -3932,44 +3920,32 @@ static const struct exynos_cpuclk_cfg_data exynos5433_atlasclk_d[] __initconst =
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
static const struct samsung_cpu_clock atlas_cpu_clks[] __initconst = {
|
||||
CPU_CLK(CLK_SCLK_ATLAS, "atlasclk", CLK_MOUT_ATLAS_PLL,
|
||||
CLK_MOUT_BUS_PLL_ATLAS_USER,
|
||||
CLK_CPU_HAS_E5433_REGS_LAYOUT, 0x200,
|
||||
exynos5433_atlasclk_d),
|
||||
};
|
||||
|
||||
static const struct samsung_cmu_info atlas_cmu_info __initconst = {
|
||||
.pll_clks = atlas_pll_clks,
|
||||
.nr_pll_clks = ARRAY_SIZE(atlas_pll_clks),
|
||||
.mux_clks = atlas_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(atlas_mux_clks),
|
||||
.div_clks = atlas_div_clks,
|
||||
.nr_div_clks = ARRAY_SIZE(atlas_div_clks),
|
||||
.gate_clks = atlas_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(atlas_gate_clks),
|
||||
.cpu_clks = atlas_cpu_clks,
|
||||
.nr_cpu_clks = ARRAY_SIZE(atlas_cpu_clks),
|
||||
.nr_clk_ids = ATLAS_NR_CLK,
|
||||
.clk_regs = atlas_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(atlas_clk_regs),
|
||||
};
|
||||
|
||||
static void __init exynos5433_cmu_atlas_init(struct device_node *np)
|
||||
{
|
||||
void __iomem *reg_base;
|
||||
struct samsung_clk_provider *ctx;
|
||||
struct clk_hw **hws;
|
||||
|
||||
reg_base = of_iomap(np, 0);
|
||||
if (!reg_base) {
|
||||
panic("%s: failed to map registers\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx = samsung_clk_init(np, reg_base, ATLAS_NR_CLK);
|
||||
if (!ctx) {
|
||||
panic("%s: unable to allocate ctx\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
samsung_clk_register_pll(ctx, atlas_pll_clks,
|
||||
ARRAY_SIZE(atlas_pll_clks), reg_base);
|
||||
samsung_clk_register_mux(ctx, atlas_mux_clks,
|
||||
ARRAY_SIZE(atlas_mux_clks));
|
||||
samsung_clk_register_div(ctx, atlas_div_clks,
|
||||
ARRAY_SIZE(atlas_div_clks));
|
||||
samsung_clk_register_gate(ctx, atlas_gate_clks,
|
||||
ARRAY_SIZE(atlas_gate_clks));
|
||||
|
||||
hws = ctx->clk_data.hws;
|
||||
|
||||
exynos_register_cpu_clock(ctx, CLK_SCLK_ATLAS, "atlasclk",
|
||||
hws[CLK_MOUT_ATLAS_PLL], hws[CLK_MOUT_BUS_PLL_ATLAS_USER], 0x200,
|
||||
exynos5433_atlasclk_d, ARRAY_SIZE(exynos5433_atlasclk_d),
|
||||
CLK_CPU_HAS_E5433_REGS_LAYOUT);
|
||||
|
||||
samsung_clk_sleep_init(reg_base, atlas_clk_regs,
|
||||
ARRAY_SIZE(atlas_clk_regs));
|
||||
|
||||
samsung_clk_of_add_provider(np, ctx);
|
||||
samsung_cmu_register_one(np, &atlas_cmu_info);
|
||||
}
|
||||
CLK_OF_DECLARE(exynos5433_cmu_atlas, "samsung,exynos5433-cmu-atlas",
|
||||
exynos5433_cmu_atlas_init);
|
||||
@ -5564,7 +5540,6 @@ static int __init exynos5433_cmu_probe(struct platform_device *pdev)
|
||||
struct exynos5433_cmu_data *data;
|
||||
struct samsung_clk_provider *ctx;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
void __iomem *reg_base;
|
||||
int i;
|
||||
|
||||
@ -5577,8 +5552,7 @@ static int __init exynos5433_cmu_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
ctx = &data->ctx;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg_base = devm_ioremap_resource(dev, res);
|
||||
reg_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg_base))
|
||||
return PTR_ERR(reg_base);
|
||||
|
||||
|
835
drivers/clk/samsung/clk-exynos850.c
Normal file
835
drivers/clk/samsung/clk-exynos850.c
Normal file
@ -0,0 +1,835 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (C) 2021 Linaro Ltd.
|
||||
* Author: Sam Protsenko <semen.protsenko@linaro.org>
|
||||
*
|
||||
* Common Clock Framework support for Exynos850 SoC.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <dt-bindings/clock/exynos850.h>
|
||||
|
||||
#include "clk.h"
|
||||
|
||||
/* Gate register bits */
|
||||
#define GATE_MANUAL BIT(20)
|
||||
#define GATE_ENABLE_HWACG BIT(28)
|
||||
|
||||
/* Gate register offsets range */
|
||||
#define GATE_OFF_START 0x2000
|
||||
#define GATE_OFF_END 0x2fff
|
||||
|
||||
/**
|
||||
* exynos850_init_clocks - Set clocks initial configuration
|
||||
* @np: CMU device tree node with "reg" property (CMU addr)
|
||||
* @reg_offs: Register offsets array for clocks to init
|
||||
* @reg_offs_len: Number of register offsets in reg_offs array
|
||||
*
|
||||
* Set manual control mode for all gate clocks.
|
||||
*/
|
||||
static void __init exynos850_init_clocks(struct device_node *np,
|
||||
const unsigned long *reg_offs, size_t reg_offs_len)
|
||||
{
|
||||
void __iomem *reg_base;
|
||||
size_t i;
|
||||
|
||||
reg_base = of_iomap(np, 0);
|
||||
if (!reg_base)
|
||||
panic("%s: failed to map registers\n", __func__);
|
||||
|
||||
for (i = 0; i < reg_offs_len; ++i) {
|
||||
void __iomem *reg = reg_base + reg_offs[i];
|
||||
u32 val;
|
||||
|
||||
/* Modify only gate clock registers */
|
||||
if (reg_offs[i] < GATE_OFF_START || reg_offs[i] > GATE_OFF_END)
|
||||
continue;
|
||||
|
||||
val = readl(reg);
|
||||
val |= GATE_MANUAL;
|
||||
val &= ~GATE_ENABLE_HWACG;
|
||||
writel(val, reg);
|
||||
}
|
||||
|
||||
iounmap(reg_base);
|
||||
}
|
||||
|
||||
/* ---- CMU_TOP ------------------------------------------------------------- */
|
||||
|
||||
/* Register Offset definitions for CMU_TOP (0x120e0000) */
|
||||
#define PLL_LOCKTIME_PLL_MMC 0x0000
|
||||
#define PLL_LOCKTIME_PLL_SHARED0 0x0004
|
||||
#define PLL_LOCKTIME_PLL_SHARED1 0x0008
|
||||
#define PLL_CON0_PLL_MMC 0x0100
|
||||
#define PLL_CON3_PLL_MMC 0x010c
|
||||
#define PLL_CON0_PLL_SHARED0 0x0140
|
||||
#define PLL_CON3_PLL_SHARED0 0x014c
|
||||
#define PLL_CON0_PLL_SHARED1 0x0180
|
||||
#define PLL_CON3_PLL_SHARED1 0x018c
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS 0x1014
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_CORE_CCI 0x1018
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD 0x101c
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_CORE_SSS 0x1020
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_DPU 0x1034
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_HSI_BUS 0x103c
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD 0x1040
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD 0x1044
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_PERI_BUS 0x1070
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_PERI_IP 0x1074
|
||||
#define CLK_CON_MUX_MUX_CLKCMU_PERI_UART 0x1078
|
||||
#define CLK_CON_DIV_CLKCMU_CORE_BUS 0x1820
|
||||
#define CLK_CON_DIV_CLKCMU_CORE_CCI 0x1824
|
||||
#define CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD 0x1828
|
||||
#define CLK_CON_DIV_CLKCMU_CORE_SSS 0x182c
|
||||
#define CLK_CON_DIV_CLKCMU_DPU 0x1840
|
||||
#define CLK_CON_DIV_CLKCMU_HSI_BUS 0x1848
|
||||
#define CLK_CON_DIV_CLKCMU_HSI_MMC_CARD 0x184c
|
||||
#define CLK_CON_DIV_CLKCMU_HSI_USB20DRD 0x1850
|
||||
#define CLK_CON_DIV_CLKCMU_PERI_BUS 0x187c
|
||||
#define CLK_CON_DIV_CLKCMU_PERI_IP 0x1880
|
||||
#define CLK_CON_DIV_CLKCMU_PERI_UART 0x1884
|
||||
#define CLK_CON_DIV_PLL_SHARED0_DIV2 0x188c
|
||||
#define CLK_CON_DIV_PLL_SHARED0_DIV3 0x1890
|
||||
#define CLK_CON_DIV_PLL_SHARED0_DIV4 0x1894
|
||||
#define CLK_CON_DIV_PLL_SHARED1_DIV2 0x1898
|
||||
#define CLK_CON_DIV_PLL_SHARED1_DIV3 0x189c
|
||||
#define CLK_CON_DIV_PLL_SHARED1_DIV4 0x18a0
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS 0x201c
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_CORE_CCI 0x2020
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD 0x2024
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_CORE_SSS 0x2028
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_DPU 0x203c
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_HSI_BUS 0x2044
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD 0x2048
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD 0x204c
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_PERI_BUS 0x2080
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_PERI_IP 0x2084
|
||||
#define CLK_CON_GAT_GATE_CLKCMU_PERI_UART 0x2088
|
||||
|
||||
static const unsigned long top_clk_regs[] __initconst = {
|
||||
PLL_LOCKTIME_PLL_MMC,
|
||||
PLL_LOCKTIME_PLL_SHARED0,
|
||||
PLL_LOCKTIME_PLL_SHARED1,
|
||||
PLL_CON0_PLL_MMC,
|
||||
PLL_CON3_PLL_MMC,
|
||||
PLL_CON0_PLL_SHARED0,
|
||||
PLL_CON3_PLL_SHARED0,
|
||||
PLL_CON0_PLL_SHARED1,
|
||||
PLL_CON3_PLL_SHARED1,
|
||||
CLK_CON_MUX_MUX_CLKCMU_CORE_BUS,
|
||||
CLK_CON_MUX_MUX_CLKCMU_CORE_CCI,
|
||||
CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD,
|
||||
CLK_CON_MUX_MUX_CLKCMU_CORE_SSS,
|
||||
CLK_CON_MUX_MUX_CLKCMU_DPU,
|
||||
CLK_CON_MUX_MUX_CLKCMU_HSI_BUS,
|
||||
CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD,
|
||||
CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD,
|
||||
CLK_CON_MUX_MUX_CLKCMU_PERI_BUS,
|
||||
CLK_CON_MUX_MUX_CLKCMU_PERI_IP,
|
||||
CLK_CON_MUX_MUX_CLKCMU_PERI_UART,
|
||||
CLK_CON_DIV_CLKCMU_CORE_BUS,
|
||||
CLK_CON_DIV_CLKCMU_CORE_CCI,
|
||||
CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD,
|
||||
CLK_CON_DIV_CLKCMU_CORE_SSS,
|
||||
CLK_CON_DIV_CLKCMU_DPU,
|
||||
CLK_CON_DIV_CLKCMU_HSI_BUS,
|
||||
CLK_CON_DIV_CLKCMU_HSI_MMC_CARD,
|
||||
CLK_CON_DIV_CLKCMU_HSI_USB20DRD,
|
||||
CLK_CON_DIV_CLKCMU_PERI_BUS,
|
||||
CLK_CON_DIV_CLKCMU_PERI_IP,
|
||||
CLK_CON_DIV_CLKCMU_PERI_UART,
|
||||
CLK_CON_DIV_PLL_SHARED0_DIV2,
|
||||
CLK_CON_DIV_PLL_SHARED0_DIV3,
|
||||
CLK_CON_DIV_PLL_SHARED0_DIV4,
|
||||
CLK_CON_DIV_PLL_SHARED1_DIV2,
|
||||
CLK_CON_DIV_PLL_SHARED1_DIV3,
|
||||
CLK_CON_DIV_PLL_SHARED1_DIV4,
|
||||
CLK_CON_GAT_GATE_CLKCMU_CORE_BUS,
|
||||
CLK_CON_GAT_GATE_CLKCMU_CORE_CCI,
|
||||
CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD,
|
||||
CLK_CON_GAT_GATE_CLKCMU_CORE_SSS,
|
||||
CLK_CON_GAT_GATE_CLKCMU_DPU,
|
||||
CLK_CON_GAT_GATE_CLKCMU_HSI_BUS,
|
||||
CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD,
|
||||
CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD,
|
||||
CLK_CON_GAT_GATE_CLKCMU_PERI_BUS,
|
||||
CLK_CON_GAT_GATE_CLKCMU_PERI_IP,
|
||||
CLK_CON_GAT_GATE_CLKCMU_PERI_UART,
|
||||
};
|
||||
|
||||
/*
|
||||
* Do not provide PLL tables to core PLLs, as MANUAL_PLL_CTRL bit is not set
|
||||
* for those PLLs by default, so set_rate operation would fail.
|
||||
*/
|
||||
static const struct samsung_pll_clock top_pll_clks[] __initconst = {
|
||||
/* CMU_TOP_PURECLKCOMP */
|
||||
PLL(pll_0822x, CLK_FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk",
|
||||
PLL_LOCKTIME_PLL_SHARED0, PLL_CON3_PLL_SHARED0,
|
||||
NULL),
|
||||
PLL(pll_0822x, CLK_FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk",
|
||||
PLL_LOCKTIME_PLL_SHARED1, PLL_CON3_PLL_SHARED1,
|
||||
NULL),
|
||||
PLL(pll_0831x, CLK_FOUT_MMC_PLL, "fout_mmc_pll", "oscclk",
|
||||
PLL_LOCKTIME_PLL_MMC, PLL_CON3_PLL_MMC, NULL),
|
||||
};
|
||||
|
||||
/* List of parent clocks for Muxes in CMU_TOP */
|
||||
PNAME(mout_shared0_pll_p) = { "oscclk", "fout_shared0_pll" };
|
||||
PNAME(mout_shared1_pll_p) = { "oscclk", "fout_shared1_pll" };
|
||||
PNAME(mout_mmc_pll_p) = { "oscclk", "fout_mmc_pll" };
|
||||
/* List of parent clocks for Muxes in CMU_TOP: for CMU_CORE */
|
||||
PNAME(mout_core_bus_p) = { "dout_shared1_div2", "dout_shared0_div3",
|
||||
"dout_shared1_div3", "dout_shared0_div4" };
|
||||
PNAME(mout_core_cci_p) = { "dout_shared0_div2", "dout_shared1_div2",
|
||||
"dout_shared0_div3", "dout_shared1_div3" };
|
||||
PNAME(mout_core_mmc_embd_p) = { "oscclk", "dout_shared0_div2",
|
||||
"dout_shared1_div2", "dout_shared0_div3",
|
||||
"dout_shared1_div3", "mout_mmc_pll",
|
||||
"oscclk", "oscclk" };
|
||||
PNAME(mout_core_sss_p) = { "dout_shared0_div3", "dout_shared1_div3",
|
||||
"dout_shared0_div4", "dout_shared1_div4" };
|
||||
/* List of parent clocks for Muxes in CMU_TOP: for CMU_HSI */
|
||||
PNAME(mout_hsi_bus_p) = { "dout_shared0_div2", "dout_shared1_div2" };
|
||||
PNAME(mout_hsi_mmc_card_p) = { "oscclk", "dout_shared0_div2",
|
||||
"dout_shared1_div2", "dout_shared0_div3",
|
||||
"dout_shared1_div3", "mout_mmc_pll",
|
||||
"oscclk", "oscclk" };
|
||||
PNAME(mout_hsi_usb20drd_p) = { "oscclk", "dout_shared0_div4",
|
||||
"dout_shared1_div4", "oscclk" };
|
||||
/* List of parent clocks for Muxes in CMU_TOP: for CMU_PERI */
|
||||
PNAME(mout_peri_bus_p) = { "dout_shared0_div4", "dout_shared1_div4" };
|
||||
PNAME(mout_peri_uart_p) = { "oscclk", "dout_shared0_div4",
|
||||
"dout_shared1_div4", "oscclk" };
|
||||
PNAME(mout_peri_ip_p) = { "oscclk", "dout_shared0_div4",
|
||||
"dout_shared1_div4", "oscclk" };
|
||||
|
||||
/* List of parent clocks for Muxes in CMU_TOP: for CMU_DPU */
|
||||
PNAME(mout_dpu_p) = { "dout_shared0_div3", "dout_shared1_div3",
|
||||
"dout_shared0_div4", "dout_shared1_div4" };
|
||||
|
||||
static const struct samsung_mux_clock top_mux_clks[] __initconst = {
|
||||
/* CMU_TOP_PURECLKCOMP */
|
||||
MUX(CLK_MOUT_SHARED0_PLL, "mout_shared0_pll", mout_shared0_pll_p,
|
||||
PLL_CON0_PLL_SHARED0, 4, 1),
|
||||
MUX(CLK_MOUT_SHARED1_PLL, "mout_shared1_pll", mout_shared1_pll_p,
|
||||
PLL_CON0_PLL_SHARED1, 4, 1),
|
||||
MUX(CLK_MOUT_MMC_PLL, "mout_mmc_pll", mout_mmc_pll_p,
|
||||
PLL_CON0_PLL_MMC, 4, 1),
|
||||
|
||||
/* CORE */
|
||||
MUX(CLK_MOUT_CORE_BUS, "mout_core_bus", mout_core_bus_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, 0, 2),
|
||||
MUX(CLK_MOUT_CORE_CCI, "mout_core_cci", mout_core_cci_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_CORE_CCI, 0, 2),
|
||||
MUX(CLK_MOUT_CORE_MMC_EMBD, "mout_core_mmc_embd", mout_core_mmc_embd_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD, 0, 3),
|
||||
MUX(CLK_MOUT_CORE_SSS, "mout_core_sss", mout_core_sss_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_CORE_SSS, 0, 2),
|
||||
|
||||
/* DPU */
|
||||
MUX(CLK_MOUT_DPU, "mout_dpu", mout_dpu_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_DPU, 0, 2),
|
||||
|
||||
/* HSI */
|
||||
MUX(CLK_MOUT_HSI_BUS, "mout_hsi_bus", mout_hsi_bus_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_HSI_BUS, 0, 1),
|
||||
MUX(CLK_MOUT_HSI_MMC_CARD, "mout_hsi_mmc_card", mout_hsi_mmc_card_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD, 0, 3),
|
||||
MUX(CLK_MOUT_HSI_USB20DRD, "mout_hsi_usb20drd", mout_hsi_usb20drd_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD, 0, 2),
|
||||
|
||||
/* PERI */
|
||||
MUX(CLK_MOUT_PERI_BUS, "mout_peri_bus", mout_peri_bus_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_PERI_BUS, 0, 1),
|
||||
MUX(CLK_MOUT_PERI_UART, "mout_peri_uart", mout_peri_uart_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_PERI_UART, 0, 2),
|
||||
MUX(CLK_MOUT_PERI_IP, "mout_peri_ip", mout_peri_ip_p,
|
||||
CLK_CON_MUX_MUX_CLKCMU_PERI_IP, 0, 2),
|
||||
};
|
||||
|
||||
static const struct samsung_div_clock top_div_clks[] __initconst = {
|
||||
/* CMU_TOP_PURECLKCOMP */
|
||||
DIV(CLK_DOUT_SHARED0_DIV3, "dout_shared0_div3", "mout_shared0_pll",
|
||||
CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2),
|
||||
DIV(CLK_DOUT_SHARED0_DIV2, "dout_shared0_div2", "mout_shared0_pll",
|
||||
CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1),
|
||||
DIV(CLK_DOUT_SHARED1_DIV3, "dout_shared1_div3", "mout_shared1_pll",
|
||||
CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2),
|
||||
DIV(CLK_DOUT_SHARED1_DIV2, "dout_shared1_div2", "mout_shared1_pll",
|
||||
CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1),
|
||||
DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "dout_shared0_div2",
|
||||
CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1),
|
||||
DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "dout_shared1_div2",
|
||||
CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1),
|
||||
|
||||
/* CORE */
|
||||
DIV(CLK_DOUT_CORE_BUS, "dout_core_bus", "gout_core_bus",
|
||||
CLK_CON_DIV_CLKCMU_CORE_BUS, 0, 4),
|
||||
DIV(CLK_DOUT_CORE_CCI, "dout_core_cci", "gout_core_cci",
|
||||
CLK_CON_DIV_CLKCMU_CORE_CCI, 0, 4),
|
||||
DIV(CLK_DOUT_CORE_MMC_EMBD, "dout_core_mmc_embd", "gout_core_mmc_embd",
|
||||
CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD, 0, 9),
|
||||
DIV(CLK_DOUT_CORE_SSS, "dout_core_sss", "gout_core_sss",
|
||||
CLK_CON_DIV_CLKCMU_CORE_SSS, 0, 4),
|
||||
|
||||
/* DPU */
|
||||
DIV(CLK_DOUT_DPU, "dout_dpu", "gout_dpu",
|
||||
CLK_CON_DIV_CLKCMU_DPU, 0, 4),
|
||||
|
||||
/* HSI */
|
||||
DIV(CLK_DOUT_HSI_BUS, "dout_hsi_bus", "gout_hsi_bus",
|
||||
CLK_CON_DIV_CLKCMU_HSI_BUS, 0, 4),
|
||||
DIV(CLK_DOUT_HSI_MMC_CARD, "dout_hsi_mmc_card", "gout_hsi_mmc_card",
|
||||
CLK_CON_DIV_CLKCMU_HSI_MMC_CARD, 0, 9),
|
||||
DIV(CLK_DOUT_HSI_USB20DRD, "dout_hsi_usb20drd", "gout_hsi_usb20drd",
|
||||
CLK_CON_DIV_CLKCMU_HSI_USB20DRD, 0, 4),
|
||||
|
||||
/* PERI */
|
||||
DIV(CLK_DOUT_PERI_BUS, "dout_peri_bus", "gout_peri_bus",
|
||||
CLK_CON_DIV_CLKCMU_PERI_BUS, 0, 4),
|
||||
DIV(CLK_DOUT_PERI_UART, "dout_peri_uart", "gout_peri_uart",
|
||||
CLK_CON_DIV_CLKCMU_PERI_UART, 0, 4),
|
||||
DIV(CLK_DOUT_PERI_IP, "dout_peri_ip", "gout_peri_ip",
|
||||
CLK_CON_DIV_CLKCMU_PERI_IP, 0, 4),
|
||||
};
|
||||
|
||||
static const struct samsung_gate_clock top_gate_clks[] __initconst = {
|
||||
/* CORE */
|
||||
GATE(CLK_GOUT_CORE_BUS, "gout_core_bus", "mout_core_bus",
|
||||
CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, 21, 0, 0),
|
||||
GATE(CLK_GOUT_CORE_CCI, "gout_core_cci", "mout_core_cci",
|
||||
CLK_CON_GAT_GATE_CLKCMU_CORE_CCI, 21, 0, 0),
|
||||
GATE(CLK_GOUT_CORE_MMC_EMBD, "gout_core_mmc_embd", "mout_core_mmc_embd",
|
||||
CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD, 21, 0, 0),
|
||||
GATE(CLK_GOUT_CORE_SSS, "gout_core_sss", "mout_core_sss",
|
||||
CLK_CON_GAT_GATE_CLKCMU_CORE_SSS, 21, 0, 0),
|
||||
|
||||
/* DPU */
|
||||
GATE(CLK_GOUT_DPU, "gout_dpu", "mout_dpu",
|
||||
CLK_CON_GAT_GATE_CLKCMU_DPU, 21, 0, 0),
|
||||
|
||||
/* HSI */
|
||||
GATE(CLK_GOUT_HSI_BUS, "gout_hsi_bus", "mout_hsi_bus",
|
||||
CLK_CON_GAT_GATE_CLKCMU_HSI_BUS, 21, 0, 0),
|
||||
GATE(CLK_GOUT_HSI_MMC_CARD, "gout_hsi_mmc_card", "mout_hsi_mmc_card",
|
||||
CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD, 21, 0, 0),
|
||||
GATE(CLK_GOUT_HSI_USB20DRD, "gout_hsi_usb20drd", "mout_hsi_usb20drd",
|
||||
CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD, 21, 0, 0),
|
||||
|
||||
/* PERI */
|
||||
GATE(CLK_GOUT_PERI_BUS, "gout_peri_bus", "mout_peri_bus",
|
||||
CLK_CON_GAT_GATE_CLKCMU_PERI_BUS, 21, 0, 0),
|
||||
GATE(CLK_GOUT_PERI_UART, "gout_peri_uart", "mout_peri_uart",
|
||||
CLK_CON_GAT_GATE_CLKCMU_PERI_UART, 21, 0, 0),
|
||||
GATE(CLK_GOUT_PERI_IP, "gout_peri_ip", "mout_peri_ip",
|
||||
CLK_CON_GAT_GATE_CLKCMU_PERI_IP, 21, 0, 0),
|
||||
};
|
||||
|
||||
static const struct samsung_cmu_info top_cmu_info __initconst = {
|
||||
.pll_clks = top_pll_clks,
|
||||
.nr_pll_clks = ARRAY_SIZE(top_pll_clks),
|
||||
.mux_clks = top_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(top_mux_clks),
|
||||
.div_clks = top_div_clks,
|
||||
.nr_div_clks = ARRAY_SIZE(top_div_clks),
|
||||
.gate_clks = top_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(top_gate_clks),
|
||||
.nr_clk_ids = TOP_NR_CLK,
|
||||
.clk_regs = top_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(top_clk_regs),
|
||||
};
|
||||
|
||||
static void __init exynos850_cmu_top_init(struct device_node *np)
|
||||
{
|
||||
exynos850_init_clocks(np, top_clk_regs, ARRAY_SIZE(top_clk_regs));
|
||||
samsung_cmu_register_one(np, &top_cmu_info);
|
||||
}
|
||||
|
||||
CLK_OF_DECLARE(exynos850_cmu_top, "samsung,exynos850-cmu-top",
|
||||
exynos850_cmu_top_init);
|
||||
|
||||
/* ---- CMU_HSI ------------------------------------------------------------- */
|
||||
|
||||
/* Register Offset definitions for CMU_HSI (0x13400000) */
|
||||
#define PLL_CON0_MUX_CLKCMU_HSI_BUS_USER 0x0600
|
||||
#define PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER 0x0610
|
||||
#define PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER 0x0620
|
||||
#define CLK_CON_MUX_MUX_CLK_HSI_RTC 0x1000
|
||||
#define CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV 0x2008
|
||||
#define CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50 0x200c
|
||||
#define CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26 0x2010
|
||||
#define CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK 0x2018
|
||||
#define CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK 0x2024
|
||||
#define CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN 0x2028
|
||||
#define CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK 0x2038
|
||||
#define CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20 0x203c
|
||||
#define CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY 0x2040
|
||||
|
||||
static const unsigned long hsi_clk_regs[] __initconst = {
|
||||
PLL_CON0_MUX_CLKCMU_HSI_BUS_USER,
|
||||
PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER,
|
||||
PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER,
|
||||
CLK_CON_MUX_MUX_CLK_HSI_RTC,
|
||||
CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV,
|
||||
CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50,
|
||||
CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26,
|
||||
CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK,
|
||||
CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK,
|
||||
CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN,
|
||||
CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK,
|
||||
CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20,
|
||||
CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY,
|
||||
};
|
||||
|
||||
/* List of parent clocks for Muxes in CMU_PERI */
|
||||
PNAME(mout_hsi_bus_user_p) = { "oscclk", "dout_hsi_bus" };
|
||||
PNAME(mout_hsi_mmc_card_user_p) = { "oscclk", "dout_hsi_mmc_card" };
|
||||
PNAME(mout_hsi_usb20drd_user_p) = { "oscclk", "dout_hsi_usb20drd" };
|
||||
PNAME(mout_hsi_rtc_p) = { "rtcclk", "oscclk" };
|
||||
|
||||
static const struct samsung_mux_clock hsi_mux_clks[] __initconst = {
|
||||
MUX(CLK_MOUT_HSI_BUS_USER, "mout_hsi_bus_user", mout_hsi_bus_user_p,
|
||||
PLL_CON0_MUX_CLKCMU_HSI_BUS_USER, 4, 1),
|
||||
MUX_F(CLK_MOUT_HSI_MMC_CARD_USER, "mout_hsi_mmc_card_user",
|
||||
mout_hsi_mmc_card_user_p, PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER,
|
||||
4, 1, CLK_SET_RATE_PARENT, 0),
|
||||
MUX(CLK_MOUT_HSI_USB20DRD_USER, "mout_hsi_usb20drd_user",
|
||||
mout_hsi_usb20drd_user_p, PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER,
|
||||
4, 1),
|
||||
MUX(CLK_MOUT_HSI_RTC, "mout_hsi_rtc", mout_hsi_rtc_p,
|
||||
CLK_CON_MUX_MUX_CLK_HSI_RTC, 0, 1),
|
||||
};
|
||||
|
||||
static const struct samsung_gate_clock hsi_gate_clks[] __initconst = {
|
||||
GATE(CLK_GOUT_USB_RTC_CLK, "gout_usb_rtc", "mout_hsi_rtc",
|
||||
CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV, 21, 0, 0),
|
||||
GATE(CLK_GOUT_USB_REF_CLK, "gout_usb_ref", "mout_hsi_usb20drd_user",
|
||||
CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50, 21, 0, 0),
|
||||
GATE(CLK_GOUT_USB_PHY_REF_CLK, "gout_usb_phy_ref", "oscclk",
|
||||
CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26, 21, 0, 0),
|
||||
GATE(CLK_GOUT_GPIO_HSI_PCLK, "gout_gpio_hsi_pclk", "mout_hsi_bus_user",
|
||||
CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_MMC_CARD_ACLK, "gout_mmc_card_aclk", "mout_hsi_bus_user",
|
||||
CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_MMC_CARD_SDCLKIN, "gout_mmc_card_sdclkin",
|
||||
"mout_hsi_mmc_card_user",
|
||||
CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN, 21, CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_SYSREG_HSI_PCLK, "gout_sysreg_hsi_pclk",
|
||||
"mout_hsi_bus_user",
|
||||
CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_USB_PHY_ACLK, "gout_usb_phy_aclk", "mout_hsi_bus_user",
|
||||
CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20, 21, 0, 0),
|
||||
GATE(CLK_GOUT_USB_BUS_EARLY_CLK, "gout_usb_bus_early",
|
||||
"mout_hsi_bus_user",
|
||||
CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY, 21, 0, 0),
|
||||
};
|
||||
|
||||
static const struct samsung_cmu_info hsi_cmu_info __initconst = {
|
||||
.mux_clks = hsi_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(hsi_mux_clks),
|
||||
.gate_clks = hsi_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(hsi_gate_clks),
|
||||
.nr_clk_ids = HSI_NR_CLK,
|
||||
.clk_regs = hsi_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(hsi_clk_regs),
|
||||
.clk_name = "dout_hsi_bus",
|
||||
};
|
||||
|
||||
/* ---- CMU_PERI ------------------------------------------------------------ */
|
||||
|
||||
/* Register Offset definitions for CMU_PERI (0x10030000) */
|
||||
#define PLL_CON0_MUX_CLKCMU_PERI_BUS_USER 0x0600
|
||||
#define PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER 0x0610
|
||||
#define PLL_CON0_MUX_CLKCMU_PERI_SPI_USER 0x0620
|
||||
#define PLL_CON0_MUX_CLKCMU_PERI_UART_USER 0x0630
|
||||
#define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0 0x1800
|
||||
#define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1 0x1804
|
||||
#define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2 0x1808
|
||||
#define CLK_CON_DIV_DIV_CLK_PERI_SPI_0 0x180c
|
||||
#define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0 0x200c
|
||||
#define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1 0x2010
|
||||
#define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2 0x2014
|
||||
#define CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK 0x2020
|
||||
#define CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK 0x2024
|
||||
#define CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK 0x2028
|
||||
#define CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK 0x202c
|
||||
#define CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK 0x2030
|
||||
#define CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK 0x2034
|
||||
#define CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK 0x2038
|
||||
#define CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK 0x203c
|
||||
#define CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK 0x2040
|
||||
#define CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK 0x2044
|
||||
#define CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK 0x2048
|
||||
#define CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK 0x204c
|
||||
#define CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK 0x2050
|
||||
#define CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK 0x2054
|
||||
#define CLK_CON_GAT_GOUT_PERI_MCT_PCLK 0x205c
|
||||
#define CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK 0x2064
|
||||
#define CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK 0x209c
|
||||
#define CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK 0x20a0
|
||||
#define CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK 0x20a4
|
||||
#define CLK_CON_GAT_GOUT_PERI_UART_IPCLK 0x20a8
|
||||
#define CLK_CON_GAT_GOUT_PERI_UART_PCLK 0x20ac
|
||||
#define CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK 0x20b0
|
||||
#define CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK 0x20b4
|
||||
|
||||
static const unsigned long peri_clk_regs[] __initconst = {
|
||||
PLL_CON0_MUX_CLKCMU_PERI_BUS_USER,
|
||||
PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER,
|
||||
PLL_CON0_MUX_CLKCMU_PERI_SPI_USER,
|
||||
PLL_CON0_MUX_CLKCMU_PERI_UART_USER,
|
||||
CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0,
|
||||
CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1,
|
||||
CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2,
|
||||
CLK_CON_DIV_DIV_CLK_PERI_SPI_0,
|
||||
CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0,
|
||||
CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1,
|
||||
CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2,
|
||||
CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_MCT_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_UART_IPCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_UART_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK,
|
||||
CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK,
|
||||
};
|
||||
|
||||
/* List of parent clocks for Muxes in CMU_PERI */
|
||||
PNAME(mout_peri_bus_user_p) = { "oscclk", "dout_peri_bus" };
|
||||
PNAME(mout_peri_uart_user_p) = { "oscclk", "dout_peri_uart" };
|
||||
PNAME(mout_peri_hsi2c_user_p) = { "oscclk", "dout_peri_ip" };
|
||||
PNAME(mout_peri_spi_user_p) = { "oscclk", "dout_peri_ip" };
|
||||
|
||||
static const struct samsung_mux_clock peri_mux_clks[] __initconst = {
|
||||
MUX(CLK_MOUT_PERI_BUS_USER, "mout_peri_bus_user", mout_peri_bus_user_p,
|
||||
PLL_CON0_MUX_CLKCMU_PERI_BUS_USER, 4, 1),
|
||||
MUX(CLK_MOUT_PERI_UART_USER, "mout_peri_uart_user",
|
||||
mout_peri_uart_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART_USER, 4, 1),
|
||||
MUX(CLK_MOUT_PERI_HSI2C_USER, "mout_peri_hsi2c_user",
|
||||
mout_peri_hsi2c_user_p, PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER, 4, 1),
|
||||
MUX(CLK_MOUT_PERI_SPI_USER, "mout_peri_spi_user", mout_peri_spi_user_p,
|
||||
PLL_CON0_MUX_CLKCMU_PERI_SPI_USER, 4, 1),
|
||||
};
|
||||
|
||||
static const struct samsung_div_clock peri_div_clks[] __initconst = {
|
||||
DIV(CLK_DOUT_PERI_HSI2C0, "dout_peri_hsi2c0", "gout_peri_hsi2c0",
|
||||
CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0, 0, 5),
|
||||
DIV(CLK_DOUT_PERI_HSI2C1, "dout_peri_hsi2c1", "gout_peri_hsi2c1",
|
||||
CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1, 0, 5),
|
||||
DIV(CLK_DOUT_PERI_HSI2C2, "dout_peri_hsi2c2", "gout_peri_hsi2c2",
|
||||
CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2, 0, 5),
|
||||
DIV(CLK_DOUT_PERI_SPI0, "dout_peri_spi0", "mout_peri_spi_user",
|
||||
CLK_CON_DIV_DIV_CLK_PERI_SPI_0, 0, 5),
|
||||
};
|
||||
|
||||
static const struct samsung_gate_clock peri_gate_clks[] __initconst = {
|
||||
GATE(CLK_GOUT_PERI_HSI2C0, "gout_peri_hsi2c0", "mout_peri_hsi2c_user",
|
||||
CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0, 21, 0, 0),
|
||||
GATE(CLK_GOUT_PERI_HSI2C1, "gout_peri_hsi2c1", "mout_peri_hsi2c_user",
|
||||
CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1, 21, 0, 0),
|
||||
GATE(CLK_GOUT_PERI_HSI2C2, "gout_peri_hsi2c2", "mout_peri_hsi2c_user",
|
||||
CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2, 21, 0, 0),
|
||||
GATE(CLK_GOUT_HSI2C0_IPCLK, "gout_hsi2c0_ipclk", "dout_peri_hsi2c0",
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_HSI2C0_PCLK, "gout_hsi2c0_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_HSI2C1_IPCLK, "gout_hsi2c1_ipclk", "dout_peri_hsi2c1",
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_HSI2C1_PCLK, "gout_hsi2c1_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_HSI2C2_IPCLK, "gout_hsi2c2_ipclk", "dout_peri_hsi2c2",
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_HSI2C2_PCLK, "gout_hsi2c2_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_I2C0_PCLK, "gout_i2c0_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_I2C1_PCLK, "gout_i2c1_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_I2C2_PCLK, "gout_i2c2_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_I2C3_PCLK, "gout_i2c3_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_I2C4_PCLK, "gout_i2c4_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_I2C5_PCLK, "gout_i2c5_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_I2C6_PCLK, "gout_i2c6_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_MCT_PCLK, "gout_mct_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_MCT_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_PWM_MOTOR_PCLK, "gout_pwm_motor_pclk",
|
||||
"mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_SPI0_IPCLK, "gout_spi0_ipclk", "dout_peri_spi0",
|
||||
CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_SPI0_PCLK, "gout_spi0_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_SYSREG_PERI_PCLK, "gout_sysreg_peri_pclk",
|
||||
"mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_UART_IPCLK, "gout_uart_ipclk", "mout_peri_uart_user",
|
||||
CLK_CON_GAT_GOUT_PERI_UART_IPCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_UART_PCLK, "gout_uart_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_UART_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_WDT0_PCLK, "gout_wdt0_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_WDT1_PCLK, "gout_wdt1_pclk", "mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_GPIO_PERI_PCLK, "gout_gpio_peri_pclk",
|
||||
"mout_peri_bus_user",
|
||||
CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK, 21, 0, 0),
|
||||
};
|
||||
|
||||
static const struct samsung_cmu_info peri_cmu_info __initconst = {
|
||||
.mux_clks = peri_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(peri_mux_clks),
|
||||
.div_clks = peri_div_clks,
|
||||
.nr_div_clks = ARRAY_SIZE(peri_div_clks),
|
||||
.gate_clks = peri_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(peri_gate_clks),
|
||||
.nr_clk_ids = PERI_NR_CLK,
|
||||
.clk_regs = peri_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(peri_clk_regs),
|
||||
.clk_name = "dout_peri_bus",
|
||||
};
|
||||
|
||||
/* ---- CMU_CORE ------------------------------------------------------------ */
|
||||
|
||||
/* Register Offset definitions for CMU_CORE (0x12000000) */
|
||||
#define PLL_CON0_MUX_CLKCMU_CORE_BUS_USER 0x0600
|
||||
#define PLL_CON0_MUX_CLKCMU_CORE_CCI_USER 0x0610
|
||||
#define PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER 0x0620
|
||||
#define PLL_CON0_MUX_CLKCMU_CORE_SSS_USER 0x0630
|
||||
#define CLK_CON_MUX_MUX_CLK_CORE_GIC 0x1000
|
||||
#define CLK_CON_DIV_DIV_CLK_CORE_BUSP 0x1800
|
||||
#define CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK 0x2038
|
||||
#define CLK_CON_GAT_GOUT_CORE_GIC_CLK 0x2040
|
||||
#define CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK 0x20e8
|
||||
#define CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN 0x20ec
|
||||
#define CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK 0x2128
|
||||
#define CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK 0x212c
|
||||
|
||||
static const unsigned long core_clk_regs[] __initconst = {
|
||||
PLL_CON0_MUX_CLKCMU_CORE_BUS_USER,
|
||||
PLL_CON0_MUX_CLKCMU_CORE_CCI_USER,
|
||||
PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER,
|
||||
PLL_CON0_MUX_CLKCMU_CORE_SSS_USER,
|
||||
CLK_CON_MUX_MUX_CLK_CORE_GIC,
|
||||
CLK_CON_DIV_DIV_CLK_CORE_BUSP,
|
||||
CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK,
|
||||
CLK_CON_GAT_GOUT_CORE_GIC_CLK,
|
||||
CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK,
|
||||
CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN,
|
||||
CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK,
|
||||
CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK,
|
||||
};
|
||||
|
||||
/* List of parent clocks for Muxes in CMU_CORE */
|
||||
PNAME(mout_core_bus_user_p) = { "oscclk", "dout_core_bus" };
|
||||
PNAME(mout_core_cci_user_p) = { "oscclk", "dout_core_cci" };
|
||||
PNAME(mout_core_mmc_embd_user_p) = { "oscclk", "dout_core_mmc_embd" };
|
||||
PNAME(mout_core_sss_user_p) = { "oscclk", "dout_core_sss" };
|
||||
PNAME(mout_core_gic_p) = { "dout_core_busp", "oscclk" };
|
||||
|
||||
static const struct samsung_mux_clock core_mux_clks[] __initconst = {
|
||||
MUX(CLK_MOUT_CORE_BUS_USER, "mout_core_bus_user", mout_core_bus_user_p,
|
||||
PLL_CON0_MUX_CLKCMU_CORE_BUS_USER, 4, 1),
|
||||
MUX(CLK_MOUT_CORE_CCI_USER, "mout_core_cci_user", mout_core_cci_user_p,
|
||||
PLL_CON0_MUX_CLKCMU_CORE_CCI_USER, 4, 1),
|
||||
MUX_F(CLK_MOUT_CORE_MMC_EMBD_USER, "mout_core_mmc_embd_user",
|
||||
mout_core_mmc_embd_user_p, PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER,
|
||||
4, 1, CLK_SET_RATE_PARENT, 0),
|
||||
MUX(CLK_MOUT_CORE_SSS_USER, "mout_core_sss_user", mout_core_sss_user_p,
|
||||
PLL_CON0_MUX_CLKCMU_CORE_SSS_USER, 4, 1),
|
||||
MUX(CLK_MOUT_CORE_GIC, "mout_core_gic", mout_core_gic_p,
|
||||
CLK_CON_MUX_MUX_CLK_CORE_GIC, 0, 1),
|
||||
};
|
||||
|
||||
static const struct samsung_div_clock core_div_clks[] __initconst = {
|
||||
DIV(CLK_DOUT_CORE_BUSP, "dout_core_busp", "mout_core_bus_user",
|
||||
CLK_CON_DIV_DIV_CLK_CORE_BUSP, 0, 2),
|
||||
};
|
||||
|
||||
static const struct samsung_gate_clock core_gate_clks[] __initconst = {
|
||||
GATE(CLK_GOUT_CCI_ACLK, "gout_cci_aclk", "mout_core_cci_user",
|
||||
CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_GIC_CLK, "gout_gic_clk", "mout_core_gic",
|
||||
CLK_CON_GAT_GOUT_CORE_GIC_CLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_MMC_EMBD_ACLK, "gout_mmc_embd_aclk", "dout_core_busp",
|
||||
CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_MMC_EMBD_SDCLKIN, "gout_mmc_embd_sdclkin",
|
||||
"mout_core_mmc_embd_user", CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN,
|
||||
21, CLK_SET_RATE_PARENT, 0),
|
||||
GATE(CLK_GOUT_SSS_ACLK, "gout_sss_aclk", "mout_core_sss_user",
|
||||
CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_SSS_PCLK, "gout_sss_pclk", "dout_core_busp",
|
||||
CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK, 21, 0, 0),
|
||||
};
|
||||
|
||||
static const struct samsung_cmu_info core_cmu_info __initconst = {
|
||||
.mux_clks = core_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(core_mux_clks),
|
||||
.div_clks = core_div_clks,
|
||||
.nr_div_clks = ARRAY_SIZE(core_div_clks),
|
||||
.gate_clks = core_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(core_gate_clks),
|
||||
.nr_clk_ids = CORE_NR_CLK,
|
||||
.clk_regs = core_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(core_clk_regs),
|
||||
.clk_name = "dout_core_bus",
|
||||
};
|
||||
|
||||
/* ---- CMU_DPU ------------------------------------------------------------- */
|
||||
|
||||
/* Register Offset definitions for CMU_DPU (0x13000000) */
|
||||
#define PLL_CON0_MUX_CLKCMU_DPU_USER 0x0600
|
||||
#define CLK_CON_DIV_DIV_CLK_DPU_BUSP 0x1800
|
||||
#define CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK 0x2004
|
||||
#define CLK_CON_GAT_GOUT_DPU_ACLK_DECON0 0x2010
|
||||
#define CLK_CON_GAT_GOUT_DPU_ACLK_DMA 0x2014
|
||||
#define CLK_CON_GAT_GOUT_DPU_ACLK_DPP 0x2018
|
||||
#define CLK_CON_GAT_GOUT_DPU_PPMU_ACLK 0x2028
|
||||
#define CLK_CON_GAT_GOUT_DPU_PPMU_PCLK 0x202c
|
||||
#define CLK_CON_GAT_GOUT_DPU_SMMU_CLK 0x2038
|
||||
#define CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK 0x203c
|
||||
|
||||
static const unsigned long dpu_clk_regs[] __initconst = {
|
||||
PLL_CON0_MUX_CLKCMU_DPU_USER,
|
||||
CLK_CON_DIV_DIV_CLK_DPU_BUSP,
|
||||
CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK,
|
||||
CLK_CON_GAT_GOUT_DPU_ACLK_DECON0,
|
||||
CLK_CON_GAT_GOUT_DPU_ACLK_DMA,
|
||||
CLK_CON_GAT_GOUT_DPU_ACLK_DPP,
|
||||
CLK_CON_GAT_GOUT_DPU_PPMU_ACLK,
|
||||
CLK_CON_GAT_GOUT_DPU_PPMU_PCLK,
|
||||
CLK_CON_GAT_GOUT_DPU_SMMU_CLK,
|
||||
CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK,
|
||||
};
|
||||
|
||||
/* List of parent clocks for Muxes in CMU_CORE */
|
||||
PNAME(mout_dpu_user_p) = { "oscclk", "dout_dpu" };
|
||||
|
||||
static const struct samsung_mux_clock dpu_mux_clks[] __initconst = {
|
||||
MUX(CLK_MOUT_DPU_USER, "mout_dpu_user", mout_dpu_user_p,
|
||||
PLL_CON0_MUX_CLKCMU_DPU_USER, 4, 1),
|
||||
};
|
||||
|
||||
static const struct samsung_div_clock dpu_div_clks[] __initconst = {
|
||||
DIV(CLK_DOUT_DPU_BUSP, "dout_dpu_busp", "mout_dpu_user",
|
||||
CLK_CON_DIV_DIV_CLK_DPU_BUSP, 0, 3),
|
||||
};
|
||||
|
||||
static const struct samsung_gate_clock dpu_gate_clks[] __initconst = {
|
||||
GATE(CLK_GOUT_DPU_CMU_DPU_PCLK, "gout_dpu_cmu_dpu_pclk",
|
||||
"dout_dpu_busp", CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_DPU_DECON0_ACLK, "gout_dpu_decon0_aclk", "mout_dpu_user",
|
||||
CLK_CON_GAT_GOUT_DPU_ACLK_DECON0, 21, 0, 0),
|
||||
GATE(CLK_GOUT_DPU_DMA_ACLK, "gout_dpu_dma_aclk", "mout_dpu_user",
|
||||
CLK_CON_GAT_GOUT_DPU_ACLK_DMA, 21, 0, 0),
|
||||
GATE(CLK_GOUT_DPU_DPP_ACLK, "gout_dpu_dpp_aclk", "mout_dpu_user",
|
||||
CLK_CON_GAT_GOUT_DPU_ACLK_DPP, 21, 0, 0),
|
||||
GATE(CLK_GOUT_DPU_PPMU_ACLK, "gout_dpu_ppmu_aclk", "mout_dpu_user",
|
||||
CLK_CON_GAT_GOUT_DPU_PPMU_ACLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_DPU_PPMU_PCLK, "gout_dpu_ppmu_pclk", "dout_dpu_busp",
|
||||
CLK_CON_GAT_GOUT_DPU_PPMU_PCLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_DPU_SMMU_CLK, "gout_dpu_smmu_clk", "mout_dpu_user",
|
||||
CLK_CON_GAT_GOUT_DPU_SMMU_CLK, 21, 0, 0),
|
||||
GATE(CLK_GOUT_DPU_SYSREG_PCLK, "gout_dpu_sysreg_pclk", "dout_dpu_busp",
|
||||
CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK, 21, 0, 0),
|
||||
};
|
||||
|
||||
static const struct samsung_cmu_info dpu_cmu_info __initconst = {
|
||||
.mux_clks = dpu_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(dpu_mux_clks),
|
||||
.div_clks = dpu_div_clks,
|
||||
.nr_div_clks = ARRAY_SIZE(dpu_div_clks),
|
||||
.gate_clks = dpu_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(dpu_gate_clks),
|
||||
.nr_clk_ids = DPU_NR_CLK,
|
||||
.clk_regs = dpu_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(dpu_clk_regs),
|
||||
.clk_name = "dout_dpu",
|
||||
};
|
||||
|
||||
/* ---- platform_driver ----------------------------------------------------- */
|
||||
|
||||
static int __init exynos850_cmu_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct samsung_cmu_info *info;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
|
||||
info = of_device_get_match_data(dev);
|
||||
exynos850_init_clocks(np, info->clk_regs, info->nr_clk_regs);
|
||||
samsung_cmu_register_one(np, info);
|
||||
|
||||
/* Keep bus clock running, so it's possible to access CMU registers */
|
||||
if (info->clk_name) {
|
||||
struct clk *bus_clk;
|
||||
|
||||
bus_clk = clk_get(dev, info->clk_name);
|
||||
if (IS_ERR(bus_clk)) {
|
||||
pr_err("%s: could not find bus clock %s; err = %ld\n",
|
||||
__func__, info->clk_name, PTR_ERR(bus_clk));
|
||||
} else {
|
||||
clk_prepare_enable(bus_clk);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* CMUs which belong to Power Domains and need runtime PM to be implemented */
|
||||
static const struct of_device_id exynos850_cmu_of_match[] = {
|
||||
{
|
||||
.compatible = "samsung,exynos850-cmu-hsi",
|
||||
.data = &hsi_cmu_info,
|
||||
}, {
|
||||
.compatible = "samsung,exynos850-cmu-peri",
|
||||
.data = &peri_cmu_info,
|
||||
}, {
|
||||
.compatible = "samsung,exynos850-cmu-core",
|
||||
.data = &core_cmu_info,
|
||||
}, {
|
||||
.compatible = "samsung,exynos850-cmu-dpu",
|
||||
.data = &dpu_cmu_info,
|
||||
}, {
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_driver exynos850_cmu_driver __refdata = {
|
||||
.driver = {
|
||||
.name = "exynos850-cmu",
|
||||
.of_match_table = exynos850_cmu_of_match,
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
.probe = exynos850_cmu_probe,
|
||||
};
|
||||
|
||||
static int __init exynos850_cmu_init(void)
|
||||
{
|
||||
return platform_driver_register(&exynos850_cmu_driver);
|
||||
}
|
||||
core_initcall(exynos850_cmu_init);
|
@ -415,6 +415,186 @@ static const struct clk_ops samsung_pll36xx_clk_min_ops = {
|
||||
.recalc_rate = samsung_pll36xx_recalc_rate,
|
||||
};
|
||||
|
||||
/*
|
||||
* PLL0822x Clock Type
|
||||
*/
|
||||
/* Maximum lock time can be 150 * PDIV cycles */
|
||||
#define PLL0822X_LOCK_FACTOR (150)
|
||||
|
||||
#define PLL0822X_MDIV_MASK (0x3FF)
|
||||
#define PLL0822X_PDIV_MASK (0x3F)
|
||||
#define PLL0822X_SDIV_MASK (0x7)
|
||||
#define PLL0822X_MDIV_SHIFT (16)
|
||||
#define PLL0822X_PDIV_SHIFT (8)
|
||||
#define PLL0822X_SDIV_SHIFT (0)
|
||||
#define PLL0822X_LOCK_STAT_SHIFT (29)
|
||||
#define PLL0822X_ENABLE_SHIFT (31)
|
||||
|
||||
static unsigned long samsung_pll0822x_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 mdiv, pdiv, sdiv, pll_con3;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_con3 = readl_relaxed(pll->con_reg);
|
||||
mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL0822X_MDIV_MASK;
|
||||
pdiv = (pll_con3 >> PLL0822X_PDIV_SHIFT) & PLL0822X_PDIV_MASK;
|
||||
sdiv = (pll_con3 >> PLL0822X_SDIV_SHIFT) & PLL0822X_SDIV_MASK;
|
||||
|
||||
fvco *= mdiv;
|
||||
do_div(fvco, (pdiv << sdiv));
|
||||
|
||||
return (unsigned long)fvco;
|
||||
}
|
||||
|
||||
static int samsung_pll0822x_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
unsigned long prate)
|
||||
{
|
||||
const struct samsung_pll_rate_table *rate;
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 pll_con3;
|
||||
|
||||
/* Get required rate settings from table */
|
||||
rate = samsung_get_pll_settings(pll, drate);
|
||||
if (!rate) {
|
||||
pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
|
||||
drate, clk_hw_get_name(hw));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Change PLL PMS values */
|
||||
pll_con3 = readl_relaxed(pll->con_reg);
|
||||
pll_con3 &= ~((PLL0822X_MDIV_MASK << PLL0822X_MDIV_SHIFT) |
|
||||
(PLL0822X_PDIV_MASK << PLL0822X_PDIV_SHIFT) |
|
||||
(PLL0822X_SDIV_MASK << PLL0822X_SDIV_SHIFT));
|
||||
pll_con3 |= (rate->mdiv << PLL0822X_MDIV_SHIFT) |
|
||||
(rate->pdiv << PLL0822X_PDIV_SHIFT) |
|
||||
(rate->sdiv << PLL0822X_SDIV_SHIFT);
|
||||
|
||||
/* Set PLL lock time */
|
||||
writel_relaxed(rate->pdiv * PLL0822X_LOCK_FACTOR,
|
||||
pll->lock_reg);
|
||||
|
||||
/* Write PMS values */
|
||||
writel_relaxed(pll_con3, pll->con_reg);
|
||||
|
||||
/* Wait for PLL lock if the PLL is enabled */
|
||||
if (pll_con3 & BIT(pll->enable_offs))
|
||||
return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops samsung_pll0822x_clk_ops = {
|
||||
.recalc_rate = samsung_pll0822x_recalc_rate,
|
||||
.round_rate = samsung_pll_round_rate,
|
||||
.set_rate = samsung_pll0822x_set_rate,
|
||||
.enable = samsung_pll3xxx_enable,
|
||||
.disable = samsung_pll3xxx_disable,
|
||||
};
|
||||
|
||||
static const struct clk_ops samsung_pll0822x_clk_min_ops = {
|
||||
.recalc_rate = samsung_pll0822x_recalc_rate,
|
||||
};
|
||||
|
||||
/*
|
||||
* PLL0831x Clock Type
|
||||
*/
|
||||
/* Maximum lock time can be 500 * PDIV cycles */
|
||||
#define PLL0831X_LOCK_FACTOR (500)
|
||||
|
||||
#define PLL0831X_KDIV_MASK (0xFFFF)
|
||||
#define PLL0831X_MDIV_MASK (0x1FF)
|
||||
#define PLL0831X_PDIV_MASK (0x3F)
|
||||
#define PLL0831X_SDIV_MASK (0x7)
|
||||
#define PLL0831X_MDIV_SHIFT (16)
|
||||
#define PLL0831X_PDIV_SHIFT (8)
|
||||
#define PLL0831X_SDIV_SHIFT (0)
|
||||
#define PLL0831X_KDIV_SHIFT (0)
|
||||
#define PLL0831X_LOCK_STAT_SHIFT (29)
|
||||
#define PLL0831X_ENABLE_SHIFT (31)
|
||||
|
||||
static unsigned long samsung_pll0831x_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 mdiv, pdiv, sdiv, pll_con3, pll_con5;
|
||||
s16 kdiv;
|
||||
u64 fvco = parent_rate;
|
||||
|
||||
pll_con3 = readl_relaxed(pll->con_reg);
|
||||
pll_con5 = readl_relaxed(pll->con_reg + 8);
|
||||
mdiv = (pll_con3 >> PLL0831X_MDIV_SHIFT) & PLL0831X_MDIV_MASK;
|
||||
pdiv = (pll_con3 >> PLL0831X_PDIV_SHIFT) & PLL0831X_PDIV_MASK;
|
||||
sdiv = (pll_con3 >> PLL0831X_SDIV_SHIFT) & PLL0831X_SDIV_MASK;
|
||||
kdiv = (s16)((pll_con5 >> PLL0831X_KDIV_SHIFT) & PLL0831X_KDIV_MASK);
|
||||
|
||||
fvco *= (mdiv << 16) + kdiv;
|
||||
do_div(fvco, (pdiv << sdiv));
|
||||
fvco >>= 16;
|
||||
|
||||
return (unsigned long)fvco;
|
||||
}
|
||||
|
||||
static int samsung_pll0831x_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
const struct samsung_pll_rate_table *rate;
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 pll_con3, pll_con5;
|
||||
|
||||
/* Get required rate settings from table */
|
||||
rate = samsung_get_pll_settings(pll, drate);
|
||||
if (!rate) {
|
||||
pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
|
||||
drate, clk_hw_get_name(hw));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pll_con3 = readl_relaxed(pll->con_reg);
|
||||
pll_con5 = readl_relaxed(pll->con_reg + 8);
|
||||
|
||||
/* Change PLL PMSK values */
|
||||
pll_con3 &= ~((PLL0831X_MDIV_MASK << PLL0831X_MDIV_SHIFT) |
|
||||
(PLL0831X_PDIV_MASK << PLL0831X_PDIV_SHIFT) |
|
||||
(PLL0831X_SDIV_MASK << PLL0831X_SDIV_SHIFT));
|
||||
pll_con3 |= (rate->mdiv << PLL0831X_MDIV_SHIFT) |
|
||||
(rate->pdiv << PLL0831X_PDIV_SHIFT) |
|
||||
(rate->sdiv << PLL0831X_SDIV_SHIFT);
|
||||
pll_con5 &= ~(PLL0831X_KDIV_MASK << PLL0831X_KDIV_SHIFT);
|
||||
/*
|
||||
* kdiv is 16-bit 2's complement (s16), but stored as unsigned int.
|
||||
* Cast it to u16 to avoid leading 0xffff's in case of negative value.
|
||||
*/
|
||||
pll_con5 |= ((u16)rate->kdiv << PLL0831X_KDIV_SHIFT);
|
||||
|
||||
/* Set PLL lock time */
|
||||
writel_relaxed(rate->pdiv * PLL0831X_LOCK_FACTOR, pll->lock_reg);
|
||||
|
||||
/* Write PMSK values */
|
||||
writel_relaxed(pll_con3, pll->con_reg);
|
||||
writel_relaxed(pll_con5, pll->con_reg + 8);
|
||||
|
||||
/* Wait for PLL lock if the PLL is enabled */
|
||||
if (pll_con3 & BIT(pll->enable_offs))
|
||||
return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops samsung_pll0831x_clk_ops = {
|
||||
.recalc_rate = samsung_pll0831x_recalc_rate,
|
||||
.set_rate = samsung_pll0831x_set_rate,
|
||||
.round_rate = samsung_pll_round_rate,
|
||||
.enable = samsung_pll3xxx_enable,
|
||||
.disable = samsung_pll3xxx_disable,
|
||||
};
|
||||
|
||||
static const struct clk_ops samsung_pll0831x_clk_min_ops = {
|
||||
.recalc_rate = samsung_pll0831x_recalc_rate,
|
||||
};
|
||||
|
||||
/*
|
||||
* PLL45xx Clock Type
|
||||
*/
|
||||
@ -1296,6 +1476,14 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
|
||||
else
|
||||
init.ops = &samsung_pll35xx_clk_ops;
|
||||
break;
|
||||
case pll_0822x:
|
||||
pll->enable_offs = PLL0822X_ENABLE_SHIFT;
|
||||
pll->lock_offs = PLL0822X_LOCK_STAT_SHIFT;
|
||||
if (!pll->rate_table)
|
||||
init.ops = &samsung_pll0822x_clk_min_ops;
|
||||
else
|
||||
init.ops = &samsung_pll0822x_clk_ops;
|
||||
break;
|
||||
case pll_4500:
|
||||
init.ops = &samsung_pll45xx_clk_min_ops;
|
||||
break;
|
||||
@ -1316,6 +1504,14 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
|
||||
else
|
||||
init.ops = &samsung_pll36xx_clk_ops;
|
||||
break;
|
||||
case pll_0831x:
|
||||
pll->enable_offs = PLL0831X_ENABLE_SHIFT;
|
||||
pll->lock_offs = PLL0831X_LOCK_STAT_SHIFT;
|
||||
if (!pll->rate_table)
|
||||
init.ops = &samsung_pll0831x_clk_min_ops;
|
||||
else
|
||||
init.ops = &samsung_pll0831x_clk_ops;
|
||||
break;
|
||||
case pll_6552:
|
||||
case pll_6552_s3c2416:
|
||||
init.ops = &samsung_pll6552_clk_ops;
|
||||
|
@ -36,6 +36,8 @@ enum samsung_pll_type {
|
||||
pll_1451x,
|
||||
pll_1452x,
|
||||
pll_1460x,
|
||||
pll_0822x,
|
||||
pll_0831x,
|
||||
};
|
||||
|
||||
#define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \
|
||||
|
@ -63,15 +63,13 @@ static struct syscore_ops s5pv210_audss_clk_syscore_ops = {
|
||||
static int s5pv210_audss_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
int i, ret = 0;
|
||||
struct resource *res;
|
||||
const char *mout_audss_p[2];
|
||||
const char *mout_i2s_p[3];
|
||||
const char *hclk_p;
|
||||
struct clk_hw **clk_table;
|
||||
struct clk *hclk, *pll_ref, *pll_in, *cdclk, *sclk_audio;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg_base = devm_ioremap_resource(&pdev->dev, res);
|
||||
reg_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg_base))
|
||||
return PTR_ERR(reg_base);
|
||||
|
||||
|
@ -378,6 +378,8 @@ struct samsung_clk_provider * __init samsung_cmu_register_one(
|
||||
samsung_clk_extended_sleep_init(reg_base,
|
||||
cmu->clk_regs, cmu->nr_clk_regs,
|
||||
cmu->suspend_regs, cmu->nr_suspend_regs);
|
||||
if (cmu->cpu_clks)
|
||||
samsung_clk_register_cpu(ctx, cmu->cpu_clks, cmu->nr_cpu_clks);
|
||||
|
||||
samsung_clk_of_add_provider(np, ctx);
|
||||
|
||||
|
@ -271,6 +271,27 @@ struct samsung_pll_clock {
|
||||
__PLL(_typ, _id, _name, _pname, CLK_GET_RATE_NOCACHE, _lock, \
|
||||
_con, _rtable)
|
||||
|
||||
struct samsung_cpu_clock {
|
||||
unsigned int id;
|
||||
const char *name;
|
||||
unsigned int parent_id;
|
||||
unsigned int alt_parent_id;
|
||||
unsigned long flags;
|
||||
int offset;
|
||||
const struct exynos_cpuclk_cfg_data *cfg;
|
||||
};
|
||||
|
||||
#define CPU_CLK(_id, _name, _pid, _apid, _flags, _offset, _cfg) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_id = _pid, \
|
||||
.alt_parent_id = _apid, \
|
||||
.flags = _flags, \
|
||||
.offset = _offset, \
|
||||
.cfg = _cfg, \
|
||||
}
|
||||
|
||||
struct samsung_clock_reg_cache {
|
||||
struct list_head node;
|
||||
void __iomem *reg_base;
|
||||
@ -301,6 +322,9 @@ struct samsung_cmu_info {
|
||||
unsigned int nr_fixed_factor_clks;
|
||||
/* total number of clocks with IDs assigned*/
|
||||
unsigned int nr_clk_ids;
|
||||
/* list of cpu clocks and respective count */
|
||||
const struct samsung_cpu_clock *cpu_clks;
|
||||
unsigned int nr_cpu_clks;
|
||||
|
||||
/* list and number of clocks registers */
|
||||
const unsigned long *clk_regs;
|
||||
@ -350,6 +374,8 @@ extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
|
||||
extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
|
||||
const struct samsung_pll_clock *pll_list,
|
||||
unsigned int nr_clk, void __iomem *base);
|
||||
extern void samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
|
||||
const struct samsung_cpu_clock *list, unsigned int nr_clk);
|
||||
|
||||
extern struct samsung_clk_provider __init *samsung_cmu_register_one(
|
||||
struct device_node *,
|
||||
|
@ -71,6 +71,7 @@ config SUN8I_A33_CCU
|
||||
config SUN8I_A83T_CCU
|
||||
bool "Support for the Allwinner A83T CCU"
|
||||
default MACH_SUN8I
|
||||
depends on MACH_SUN8I || COMPILE_TEST
|
||||
|
||||
config SUN8I_H3_CCU
|
||||
bool "Support for the Allwinner H3 CCU"
|
||||
|
@ -1464,7 +1464,7 @@ static void __init sun4i_ccu_init(struct device_node *node,
|
||||
val &= ~GENMASK(7, 6);
|
||||
writel(val | (2 << 6), reg + SUN4I_AHB_REG);
|
||||
|
||||
sunxi_ccu_probe(node, reg, desc);
|
||||
of_sunxi_ccu_probe(node, reg, desc);
|
||||
}
|
||||
|
||||
static void __init sun4i_a10_ccu_setup(struct device_node *node)
|
||||
|
@ -196,7 +196,7 @@ static int sun50i_a100_r_ccu_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a100_r_ccu_desc);
|
||||
return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a100_r_ccu_desc);
|
||||
}
|
||||
|
||||
static const struct of_device_id sun50i_a100_r_ccu_ids[] = {
|
||||
@ -208,6 +208,7 @@ static struct platform_driver sun50i_a100_r_ccu_driver = {
|
||||
.probe = sun50i_a100_r_ccu_probe,
|
||||
.driver = {
|
||||
.name = "sun50i-a100-r-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun50i_a100_r_ccu_ids,
|
||||
},
|
||||
};
|
||||
|
@ -1247,7 +1247,7 @@ static int sun50i_a100_ccu_probe(struct platform_device *pdev)
|
||||
writel(val, reg + sun50i_a100_usb2_clk_regs[i]);
|
||||
}
|
||||
|
||||
ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a100_ccu_desc);
|
||||
ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a100_ccu_desc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1270,6 +1270,7 @@ static struct platform_driver sun50i_a100_ccu_driver = {
|
||||
.probe = sun50i_a100_ccu_probe,
|
||||
.driver = {
|
||||
.name = "sun50i-a100-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun50i_a100_ccu_ids,
|
||||
},
|
||||
};
|
||||
|
@ -938,13 +938,11 @@ static struct ccu_mux_nb sun50i_a64_cpu_nb = {
|
||||
|
||||
static int sun50i_a64_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
void __iomem *reg;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg = devm_ioremap_resource(&pdev->dev, res);
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
@ -955,7 +953,7 @@ static int sun50i_a64_ccu_probe(struct platform_device *pdev)
|
||||
|
||||
writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG);
|
||||
|
||||
ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc);
|
||||
ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_a64_ccu_desc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -978,6 +976,7 @@ static struct platform_driver sun50i_a64_ccu_driver = {
|
||||
.probe = sun50i_a64_ccu_probe,
|
||||
.driver = {
|
||||
.name = "sun50i-a64-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun50i_a64_ccu_ids,
|
||||
},
|
||||
};
|
||||
|
@ -232,7 +232,7 @@ static void __init sunxi_r_ccu_init(struct device_node *node,
|
||||
return;
|
||||
}
|
||||
|
||||
sunxi_ccu_probe(node, reg, desc);
|
||||
of_sunxi_ccu_probe(node, reg, desc);
|
||||
}
|
||||
|
||||
static void __init sun50i_h6_r_ccu_setup(struct device_node *node)
|
||||
|
@ -1183,13 +1183,11 @@ static const u32 usb2_clk_regs[] = {
|
||||
|
||||
static int sun50i_h6_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
void __iomem *reg;
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg = devm_ioremap_resource(&pdev->dev, res);
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
@ -1240,7 +1238,7 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev)
|
||||
val |= BIT(24);
|
||||
writel(val, reg + SUN50I_H6_HDMI_CEC_CLK_REG);
|
||||
|
||||
return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_h6_ccu_desc);
|
||||
return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h6_ccu_desc);
|
||||
}
|
||||
|
||||
static const struct of_device_id sun50i_h6_ccu_ids[] = {
|
||||
@ -1252,6 +1250,7 @@ static struct platform_driver sun50i_h6_ccu_driver = {
|
||||
.probe = sun50i_h6_ccu_probe,
|
||||
.driver = {
|
||||
.name = "sun50i-h6-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun50i_h6_ccu_ids,
|
||||
},
|
||||
};
|
||||
|
@ -1141,9 +1141,7 @@ static void __init sun50i_h616_ccu_setup(struct device_node *node)
|
||||
val |= BIT(24);
|
||||
writel(val, reg + SUN50I_H616_HDMI_CEC_CLK_REG);
|
||||
|
||||
i = sunxi_ccu_probe(node, reg, &sun50i_h616_ccu_desc);
|
||||
if (i)
|
||||
pr_err("%pOF: probing clocks fails: %d\n", node, i);
|
||||
of_sunxi_ccu_probe(node, reg, &sun50i_h616_ccu_desc);
|
||||
}
|
||||
|
||||
CLK_OF_DECLARE(sun50i_h616_ccu, "allwinner,sun50i-h616-ccu",
|
||||
|
@ -1012,7 +1012,7 @@ static void __init sun5i_ccu_init(struct device_node *node,
|
||||
val &= ~GENMASK(7, 6);
|
||||
writel(val | (2 << 6), reg + SUN5I_AHB_REG);
|
||||
|
||||
sunxi_ccu_probe(node, reg, desc);
|
||||
of_sunxi_ccu_probe(node, reg, desc);
|
||||
}
|
||||
|
||||
static void __init sun5i_a10s_ccu_setup(struct device_node *node)
|
||||
|
@ -1257,7 +1257,7 @@ static void __init sun6i_a31_ccu_setup(struct device_node *node)
|
||||
val |= 0x3 << 12;
|
||||
writel(val, reg + SUN6I_A31_AHB1_REG);
|
||||
|
||||
sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc);
|
||||
of_sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc);
|
||||
|
||||
ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk,
|
||||
&sun6i_a31_cpu_nb);
|
||||
|
@ -745,7 +745,7 @@ static void __init sun8i_a23_ccu_setup(struct device_node *node)
|
||||
val &= ~BIT(16);
|
||||
writel(val, reg + SUN8I_A23_PLL_MIPI_REG);
|
||||
|
||||
sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc);
|
||||
of_sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc);
|
||||
}
|
||||
CLK_OF_DECLARE(sun8i_a23_ccu, "allwinner,sun8i-a23-ccu",
|
||||
sun8i_a23_ccu_setup);
|
||||
|
@ -805,7 +805,7 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node)
|
||||
val &= ~BIT(16);
|
||||
writel(val, reg + SUN8I_A33_PLL_MIPI_REG);
|
||||
|
||||
sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc);
|
||||
of_sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc);
|
||||
|
||||
/* Gate then ungate PLL CPU after any rate changes */
|
||||
ccu_pll_notifier_register(&sun8i_a33_pll_cpu_nb);
|
||||
|
@ -887,12 +887,10 @@ static void sun8i_a83t_cpu_pll_fixup(void __iomem *reg)
|
||||
|
||||
static int sun8i_a83t_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
void __iomem *reg;
|
||||
u32 val;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg = devm_ioremap_resource(&pdev->dev, res);
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
@ -906,7 +904,7 @@ static int sun8i_a83t_ccu_probe(struct platform_device *pdev)
|
||||
sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C0CPUX_REG);
|
||||
sun8i_a83t_cpu_pll_fixup(reg + SUN8I_A83T_PLL_C1CPUX_REG);
|
||||
|
||||
return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun8i_a83t_ccu_desc);
|
||||
return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_a83t_ccu_desc);
|
||||
}
|
||||
|
||||
static const struct of_device_id sun8i_a83t_ccu_ids[] = {
|
||||
@ -918,6 +916,7 @@ static struct platform_driver sun8i_a83t_ccu_driver = {
|
||||
.probe = sun8i_a83t_ccu_probe,
|
||||
.driver = {
|
||||
.name = "sun8i-a83t-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun8i_a83t_ccu_ids,
|
||||
},
|
||||
};
|
||||
|
@ -280,7 +280,6 @@ static const struct sunxi_ccu_desc sun50i_h5_de2_clk_desc = {
|
||||
|
||||
static int sunxi_de2_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
struct clk *bus_clk, *mod_clk;
|
||||
struct reset_control *rstc;
|
||||
void __iomem *reg;
|
||||
@ -291,8 +290,7 @@ static int sunxi_de2_clk_probe(struct platform_device *pdev)
|
||||
if (!ccu_desc)
|
||||
return -EINVAL;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg = devm_ioremap_resource(&pdev->dev, res);
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
@ -342,7 +340,7 @@ static int sunxi_de2_clk_probe(struct platform_device *pdev)
|
||||
goto err_disable_mod_clk;
|
||||
}
|
||||
|
||||
ret = sunxi_ccu_probe(pdev->dev.of_node, reg, ccu_desc);
|
||||
ret = devm_sunxi_ccu_probe(&pdev->dev, reg, ccu_desc);
|
||||
if (ret)
|
||||
goto err_assert_reset;
|
||||
|
||||
|
@ -1154,7 +1154,7 @@ static void __init sunxi_h3_h5_ccu_init(struct device_node *node,
|
||||
val &= ~GENMASK(19, 16);
|
||||
writel(val | (0 << 16), reg + SUN8I_H3_PLL_AUDIO_REG);
|
||||
|
||||
sunxi_ccu_probe(node, reg, desc);
|
||||
of_sunxi_ccu_probe(node, reg, desc);
|
||||
|
||||
/* Gate then ungate PLL CPU after any rate changes */
|
||||
ccu_pll_notifier_register(&sun8i_h3_pll_cpu_nb);
|
||||
|
@ -265,7 +265,7 @@ static void __init sunxi_r_ccu_init(struct device_node *node,
|
||||
return;
|
||||
}
|
||||
|
||||
sunxi_ccu_probe(node, reg, desc);
|
||||
of_sunxi_ccu_probe(node, reg, desc);
|
||||
}
|
||||
|
||||
static void __init sun8i_a83t_r_ccu_setup(struct device_node *node)
|
||||
|
@ -1307,14 +1307,12 @@ static struct regmap_config sun8i_r40_ccu_regmap_config = {
|
||||
|
||||
static int sun8i_r40_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
struct regmap *regmap;
|
||||
void __iomem *reg;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg = devm_ioremap_resource(&pdev->dev, res);
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
@ -1346,7 +1344,7 @@ static int sun8i_r40_ccu_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun8i_r40_ccu_desc);
|
||||
ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_r40_ccu_desc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -1369,6 +1367,7 @@ static struct platform_driver sun8i_r40_ccu_driver = {
|
||||
.probe = sun8i_r40_ccu_probe,
|
||||
.driver = {
|
||||
.name = "sun8i-r40-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun8i_r40_ccu_ids,
|
||||
},
|
||||
};
|
||||
|
@ -822,7 +822,7 @@ static void __init sun8i_v3_v3s_ccu_init(struct device_node *node,
|
||||
val &= ~GENMASK(19, 16);
|
||||
writel(val, reg + SUN8I_V3S_PLL_AUDIO_REG);
|
||||
|
||||
sunxi_ccu_probe(node, reg, ccu_desc);
|
||||
of_sunxi_ccu_probe(node, reg, ccu_desc);
|
||||
}
|
||||
|
||||
static void __init sun8i_v3s_ccu_setup(struct device_node *node)
|
||||
|
@ -203,14 +203,12 @@ static const struct sunxi_ccu_desc sun9i_a80_de_clk_desc = {
|
||||
|
||||
static int sun9i_a80_de_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
struct clk *bus_clk;
|
||||
struct reset_control *rstc;
|
||||
void __iomem *reg;
|
||||
int ret;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg = devm_ioremap_resource(&pdev->dev, res);
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
@ -246,8 +244,7 @@ static int sun9i_a80_de_clk_probe(struct platform_device *pdev)
|
||||
goto err_disable_clk;
|
||||
}
|
||||
|
||||
ret = sunxi_ccu_probe(pdev->dev.of_node, reg,
|
||||
&sun9i_a80_de_clk_desc);
|
||||
ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun9i_a80_de_clk_desc);
|
||||
if (ret)
|
||||
goto err_assert_reset;
|
||||
|
||||
@ -269,6 +266,7 @@ static struct platform_driver sun9i_a80_de_clk_driver = {
|
||||
.probe = sun9i_a80_de_clk_probe,
|
||||
.driver = {
|
||||
.name = "sun9i-a80-de-clks",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun9i_a80_de_clk_ids,
|
||||
},
|
||||
};
|
||||
|
@ -92,13 +92,11 @@ static const struct sunxi_ccu_desc sun9i_a80_usb_clk_desc = {
|
||||
|
||||
static int sun9i_a80_usb_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
struct clk *bus_clk;
|
||||
void __iomem *reg;
|
||||
int ret;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg = devm_ioremap_resource(&pdev->dev, res);
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
@ -117,8 +115,7 @@ static int sun9i_a80_usb_clk_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sunxi_ccu_probe(pdev->dev.of_node, reg,
|
||||
&sun9i_a80_usb_clk_desc);
|
||||
ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun9i_a80_usb_clk_desc);
|
||||
if (ret)
|
||||
goto err_disable_clk;
|
||||
|
||||
|
@ -1213,12 +1213,10 @@ static void sun9i_a80_cpu_pll_fixup(void __iomem *reg)
|
||||
|
||||
static int sun9i_a80_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
void __iomem *reg;
|
||||
u32 val;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg = devm_ioremap_resource(&pdev->dev, res);
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
@ -1231,7 +1229,7 @@ static int sun9i_a80_ccu_probe(struct platform_device *pdev)
|
||||
sun9i_a80_cpu_pll_fixup(reg + SUN9I_A80_PLL_C0CPUX_REG);
|
||||
sun9i_a80_cpu_pll_fixup(reg + SUN9I_A80_PLL_C1CPUX_REG);
|
||||
|
||||
return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun9i_a80_ccu_desc);
|
||||
return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun9i_a80_ccu_desc);
|
||||
}
|
||||
|
||||
static const struct of_device_id sun9i_a80_ccu_ids[] = {
|
||||
@ -1243,6 +1241,7 @@ static struct platform_driver sun9i_a80_ccu_driver = {
|
||||
.probe = sun9i_a80_ccu_probe,
|
||||
.driver = {
|
||||
.name = "sun9i-a80-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun9i_a80_ccu_ids,
|
||||
},
|
||||
};
|
||||
|
@ -538,7 +538,7 @@ static void __init suniv_f1c100s_ccu_setup(struct device_node *node)
|
||||
val &= ~GENMASK(19, 16);
|
||||
writel(val | (3 << 16), reg + SUNIV_PLL_AUDIO_REG);
|
||||
|
||||
sunxi_ccu_probe(node, reg, &suniv_ccu_desc);
|
||||
of_sunxi_ccu_probe(node, reg, &suniv_ccu_desc);
|
||||
|
||||
/* Gate then ungate PLL CPU after any rate changes */
|
||||
ccu_pll_notifier_register(&suniv_pll_cpu_nb);
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
@ -14,7 +15,11 @@
|
||||
#include "ccu_gate.h"
|
||||
#include "ccu_reset.h"
|
||||
|
||||
static DEFINE_SPINLOCK(ccu_lock);
|
||||
struct sunxi_ccu {
|
||||
const struct sunxi_ccu_desc *desc;
|
||||
spinlock_t lock;
|
||||
struct ccu_reset reset;
|
||||
};
|
||||
|
||||
void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock)
|
||||
{
|
||||
@ -79,12 +84,17 @@ int ccu_pll_notifier_register(struct ccu_pll_nb *pll_nb)
|
||||
&pll_nb->clk_nb);
|
||||
}
|
||||
|
||||
int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
|
||||
const struct sunxi_ccu_desc *desc)
|
||||
static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
|
||||
struct device_node *node, void __iomem *reg,
|
||||
const struct sunxi_ccu_desc *desc)
|
||||
{
|
||||
struct ccu_reset *reset;
|
||||
int i, ret;
|
||||
|
||||
ccu->desc = desc;
|
||||
|
||||
spin_lock_init(&ccu->lock);
|
||||
|
||||
for (i = 0; i < desc->num_ccu_clks; i++) {
|
||||
struct ccu_common *cclk = desc->ccu_clks[i];
|
||||
|
||||
@ -92,7 +102,7 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
|
||||
continue;
|
||||
|
||||
cclk->base = reg;
|
||||
cclk->lock = &ccu_lock;
|
||||
cclk->lock = &ccu->lock;
|
||||
}
|
||||
|
||||
for (i = 0; i < desc->hw_clks->num ; i++) {
|
||||
@ -103,7 +113,10 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
|
||||
continue;
|
||||
|
||||
name = hw->init->name;
|
||||
ret = of_clk_hw_register(node, hw);
|
||||
if (dev)
|
||||
ret = clk_hw_register(dev, hw);
|
||||
else
|
||||
ret = of_clk_hw_register(node, hw);
|
||||
if (ret) {
|
||||
pr_err("Couldn't register clock %d - %s\n", i, name);
|
||||
goto err_clk_unreg;
|
||||
@ -115,29 +128,22 @@ int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
|
||||
if (ret)
|
||||
goto err_clk_unreg;
|
||||
|
||||
reset = kzalloc(sizeof(*reset), GFP_KERNEL);
|
||||
if (!reset) {
|
||||
ret = -ENOMEM;
|
||||
goto err_alloc_reset;
|
||||
}
|
||||
|
||||
reset = &ccu->reset;
|
||||
reset->rcdev.of_node = node;
|
||||
reset->rcdev.ops = &ccu_reset_ops;
|
||||
reset->rcdev.owner = THIS_MODULE;
|
||||
reset->rcdev.owner = dev ? dev->driver->owner : THIS_MODULE;
|
||||
reset->rcdev.nr_resets = desc->num_resets;
|
||||
reset->base = reg;
|
||||
reset->lock = &ccu_lock;
|
||||
reset->lock = &ccu->lock;
|
||||
reset->reset_map = desc->resets;
|
||||
|
||||
ret = reset_controller_register(&reset->rcdev);
|
||||
if (ret)
|
||||
goto err_of_clk_unreg;
|
||||
goto err_del_provider;
|
||||
|
||||
return 0;
|
||||
|
||||
err_of_clk_unreg:
|
||||
kfree(reset);
|
||||
err_alloc_reset:
|
||||
err_del_provider:
|
||||
of_clk_del_provider(node);
|
||||
err_clk_unreg:
|
||||
while (--i >= 0) {
|
||||
@ -149,3 +155,59 @@ err_clk_unreg:
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void devm_sunxi_ccu_release(struct device *dev, void *res)
|
||||
{
|
||||
struct sunxi_ccu *ccu = res;
|
||||
const struct sunxi_ccu_desc *desc = ccu->desc;
|
||||
int i;
|
||||
|
||||
reset_controller_unregister(&ccu->reset.rcdev);
|
||||
of_clk_del_provider(dev->of_node);
|
||||
|
||||
for (i = 0; i < desc->hw_clks->num; i++) {
|
||||
struct clk_hw *hw = desc->hw_clks->hws[i];
|
||||
|
||||
if (!hw)
|
||||
continue;
|
||||
clk_hw_unregister(hw);
|
||||
}
|
||||
}
|
||||
|
||||
int devm_sunxi_ccu_probe(struct device *dev, void __iomem *reg,
|
||||
const struct sunxi_ccu_desc *desc)
|
||||
{
|
||||
struct sunxi_ccu *ccu;
|
||||
int ret;
|
||||
|
||||
ccu = devres_alloc(devm_sunxi_ccu_release, sizeof(*ccu), GFP_KERNEL);
|
||||
if (!ccu)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = sunxi_ccu_probe(ccu, dev, dev->of_node, reg, desc);
|
||||
if (ret) {
|
||||
devres_free(ccu);
|
||||
return ret;
|
||||
}
|
||||
|
||||
devres_add(dev, ccu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
|
||||
const struct sunxi_ccu_desc *desc)
|
||||
{
|
||||
struct sunxi_ccu *ccu;
|
||||
int ret;
|
||||
|
||||
ccu = kzalloc(sizeof(*ccu), GFP_KERNEL);
|
||||
if (!ccu)
|
||||
return;
|
||||
|
||||
ret = sunxi_ccu_probe(ccu, NULL, node, reg, desc);
|
||||
if (ret) {
|
||||
pr_err("%pOF: probing clocks failed: %d\n", node, ret);
|
||||
kfree(ccu);
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,9 @@ struct ccu_pll_nb {
|
||||
|
||||
int ccu_pll_notifier_register(struct ccu_pll_nb *pll_nb);
|
||||
|
||||
int sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
|
||||
const struct sunxi_ccu_desc *desc);
|
||||
int devm_sunxi_ccu_probe(struct device *dev, void __iomem *reg,
|
||||
const struct sunxi_ccu_desc *desc);
|
||||
void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
|
||||
const struct sunxi_ccu_desc *desc);
|
||||
|
||||
#endif /* _COMMON_H_ */
|
||||
|
@ -40,7 +40,6 @@ struct ccu_mux_internal {
|
||||
_SUNXI_CCU_MUX_TABLE(_shift, _width, NULL)
|
||||
|
||||
struct ccu_mux {
|
||||
u16 reg;
|
||||
u32 enable;
|
||||
|
||||
struct ccu_mux_internal mux;
|
||||
|
@ -88,14 +88,12 @@ CLK_OF_DECLARE_DRIVER(sun4i_a10_mod0, "allwinner,sun4i-a10-mod0-clk",
|
||||
static int sun4i_a10_mod0_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct resource *r;
|
||||
void __iomem *reg;
|
||||
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg = devm_ioremap_resource(&pdev->dev, r);
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
|
@ -40,7 +40,6 @@ static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev)
|
||||
const struct gates_data *data;
|
||||
const char *clk_parent;
|
||||
const char *clk_name;
|
||||
struct resource *r;
|
||||
void __iomem *reg;
|
||||
int ngates;
|
||||
int i;
|
||||
@ -53,8 +52,7 @@ static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev)
|
||||
if (!data)
|
||||
return -ENODEV;
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg = devm_ioremap_resource(&pdev->dev, r);
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
|
@ -32,12 +32,10 @@ static int sun6i_a31_apb0_clk_probe(struct platform_device *pdev)
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
const char *clk_name = np->name;
|
||||
const char *clk_parent;
|
||||
struct resource *r;
|
||||
void __iomem *reg;
|
||||
struct clk *clk;
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg = devm_ioremap_resource(&pdev->dev, r);
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
|
@ -71,12 +71,10 @@ static DEFINE_SPINLOCK(sun6i_ar100_lock);
|
||||
static int sun6i_a31_ar100_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct resource *r;
|
||||
void __iomem *reg;
|
||||
struct clk *clk;
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg = devm_ioremap_resource(&pdev->dev, r);
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
|
@ -87,12 +87,10 @@ CLK_OF_DECLARE_DRIVER(sun8i_a23_apb0, "allwinner,sun8i-a23-apb0-clk",
|
||||
static int sun8i_a23_apb0_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct resource *r;
|
||||
void __iomem *reg;
|
||||
struct clk *clk;
|
||||
|
||||
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
reg = devm_ioremap_resource(&pdev->dev, r);
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
|
141
include/dt-bindings/clock/exynos850.h
Normal file
141
include/dt-bindings/clock/exynos850.h
Normal file
@ -0,0 +1,141 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
/*
|
||||
* Copyright (C) 2021 Linaro Ltd.
|
||||
* Author: Sam Protsenko <semen.protsenko@linaro.org>
|
||||
*
|
||||
* Device Tree binding constants for Exynos850 clock controller.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLOCK_EXYNOS_850_H
|
||||
#define _DT_BINDINGS_CLOCK_EXYNOS_850_H
|
||||
|
||||
/* CMU_TOP */
|
||||
#define CLK_FOUT_SHARED0_PLL 1
|
||||
#define CLK_FOUT_SHARED1_PLL 2
|
||||
#define CLK_FOUT_MMC_PLL 3
|
||||
#define CLK_MOUT_SHARED0_PLL 4
|
||||
#define CLK_MOUT_SHARED1_PLL 5
|
||||
#define CLK_MOUT_MMC_PLL 6
|
||||
#define CLK_MOUT_CORE_BUS 7
|
||||
#define CLK_MOUT_CORE_CCI 8
|
||||
#define CLK_MOUT_CORE_MMC_EMBD 9
|
||||
#define CLK_MOUT_CORE_SSS 10
|
||||
#define CLK_MOUT_DPU 11
|
||||
#define CLK_MOUT_HSI_BUS 12
|
||||
#define CLK_MOUT_HSI_MMC_CARD 13
|
||||
#define CLK_MOUT_HSI_USB20DRD 14
|
||||
#define CLK_MOUT_PERI_BUS 15
|
||||
#define CLK_MOUT_PERI_UART 16
|
||||
#define CLK_MOUT_PERI_IP 17
|
||||
#define CLK_DOUT_SHARED0_DIV3 18
|
||||
#define CLK_DOUT_SHARED0_DIV2 19
|
||||
#define CLK_DOUT_SHARED1_DIV3 20
|
||||
#define CLK_DOUT_SHARED1_DIV2 21
|
||||
#define CLK_DOUT_SHARED0_DIV4 22
|
||||
#define CLK_DOUT_SHARED1_DIV4 23
|
||||
#define CLK_DOUT_CORE_BUS 24
|
||||
#define CLK_DOUT_CORE_CCI 25
|
||||
#define CLK_DOUT_CORE_MMC_EMBD 26
|
||||
#define CLK_DOUT_CORE_SSS 27
|
||||
#define CLK_DOUT_DPU 28
|
||||
#define CLK_DOUT_HSI_BUS 29
|
||||
#define CLK_DOUT_HSI_MMC_CARD 30
|
||||
#define CLK_DOUT_HSI_USB20DRD 31
|
||||
#define CLK_DOUT_PERI_BUS 32
|
||||
#define CLK_DOUT_PERI_UART 33
|
||||
#define CLK_DOUT_PERI_IP 34
|
||||
#define CLK_GOUT_CORE_BUS 35
|
||||
#define CLK_GOUT_CORE_CCI 36
|
||||
#define CLK_GOUT_CORE_MMC_EMBD 37
|
||||
#define CLK_GOUT_CORE_SSS 38
|
||||
#define CLK_GOUT_DPU 39
|
||||
#define CLK_GOUT_HSI_BUS 40
|
||||
#define CLK_GOUT_HSI_MMC_CARD 41
|
||||
#define CLK_GOUT_HSI_USB20DRD 42
|
||||
#define CLK_GOUT_PERI_BUS 43
|
||||
#define CLK_GOUT_PERI_UART 44
|
||||
#define CLK_GOUT_PERI_IP 45
|
||||
#define TOP_NR_CLK 46
|
||||
|
||||
/* CMU_HSI */
|
||||
#define CLK_MOUT_HSI_BUS_USER 1
|
||||
#define CLK_MOUT_HSI_MMC_CARD_USER 2
|
||||
#define CLK_MOUT_HSI_USB20DRD_USER 3
|
||||
#define CLK_MOUT_HSI_RTC 4
|
||||
#define CLK_GOUT_USB_RTC_CLK 5
|
||||
#define CLK_GOUT_USB_REF_CLK 6
|
||||
#define CLK_GOUT_USB_PHY_REF_CLK 7
|
||||
#define CLK_GOUT_USB_PHY_ACLK 8
|
||||
#define CLK_GOUT_USB_BUS_EARLY_CLK 9
|
||||
#define CLK_GOUT_GPIO_HSI_PCLK 10
|
||||
#define CLK_GOUT_MMC_CARD_ACLK 11
|
||||
#define CLK_GOUT_MMC_CARD_SDCLKIN 12
|
||||
#define CLK_GOUT_SYSREG_HSI_PCLK 13
|
||||
#define HSI_NR_CLK 14
|
||||
|
||||
/* CMU_PERI */
|
||||
#define CLK_MOUT_PERI_BUS_USER 1
|
||||
#define CLK_MOUT_PERI_UART_USER 2
|
||||
#define CLK_MOUT_PERI_HSI2C_USER 3
|
||||
#define CLK_MOUT_PERI_SPI_USER 4
|
||||
#define CLK_DOUT_PERI_HSI2C0 5
|
||||
#define CLK_DOUT_PERI_HSI2C1 6
|
||||
#define CLK_DOUT_PERI_HSI2C2 7
|
||||
#define CLK_DOUT_PERI_SPI0 8
|
||||
#define CLK_GOUT_PERI_HSI2C0 9
|
||||
#define CLK_GOUT_PERI_HSI2C1 10
|
||||
#define CLK_GOUT_PERI_HSI2C2 11
|
||||
#define CLK_GOUT_GPIO_PERI_PCLK 12
|
||||
#define CLK_GOUT_HSI2C0_IPCLK 13
|
||||
#define CLK_GOUT_HSI2C0_PCLK 14
|
||||
#define CLK_GOUT_HSI2C1_IPCLK 15
|
||||
#define CLK_GOUT_HSI2C1_PCLK 16
|
||||
#define CLK_GOUT_HSI2C2_IPCLK 17
|
||||
#define CLK_GOUT_HSI2C2_PCLK 18
|
||||
#define CLK_GOUT_I2C0_PCLK 19
|
||||
#define CLK_GOUT_I2C1_PCLK 20
|
||||
#define CLK_GOUT_I2C2_PCLK 21
|
||||
#define CLK_GOUT_I2C3_PCLK 22
|
||||
#define CLK_GOUT_I2C4_PCLK 23
|
||||
#define CLK_GOUT_I2C5_PCLK 24
|
||||
#define CLK_GOUT_I2C6_PCLK 25
|
||||
#define CLK_GOUT_MCT_PCLK 26
|
||||
#define CLK_GOUT_PWM_MOTOR_PCLK 27
|
||||
#define CLK_GOUT_SPI0_IPCLK 28
|
||||
#define CLK_GOUT_SPI0_PCLK 29
|
||||
#define CLK_GOUT_SYSREG_PERI_PCLK 30
|
||||
#define CLK_GOUT_UART_IPCLK 31
|
||||
#define CLK_GOUT_UART_PCLK 32
|
||||
#define CLK_GOUT_WDT0_PCLK 33
|
||||
#define CLK_GOUT_WDT1_PCLK 34
|
||||
#define PERI_NR_CLK 35
|
||||
|
||||
/* CMU_CORE */
|
||||
#define CLK_MOUT_CORE_BUS_USER 1
|
||||
#define CLK_MOUT_CORE_CCI_USER 2
|
||||
#define CLK_MOUT_CORE_MMC_EMBD_USER 3
|
||||
#define CLK_MOUT_CORE_SSS_USER 4
|
||||
#define CLK_MOUT_CORE_GIC 5
|
||||
#define CLK_DOUT_CORE_BUSP 6
|
||||
#define CLK_GOUT_CCI_ACLK 7
|
||||
#define CLK_GOUT_GIC_CLK 8
|
||||
#define CLK_GOUT_MMC_EMBD_ACLK 9
|
||||
#define CLK_GOUT_MMC_EMBD_SDCLKIN 10
|
||||
#define CLK_GOUT_SSS_ACLK 11
|
||||
#define CLK_GOUT_SSS_PCLK 12
|
||||
#define CORE_NR_CLK 13
|
||||
|
||||
/* CMU_DPU */
|
||||
#define CLK_MOUT_DPU_USER 1
|
||||
#define CLK_DOUT_DPU_BUSP 2
|
||||
#define CLK_GOUT_DPU_CMU_DPU_PCLK 3
|
||||
#define CLK_GOUT_DPU_DECON0_ACLK 4
|
||||
#define CLK_GOUT_DPU_DMA_ACLK 5
|
||||
#define CLK_GOUT_DPU_DPP_ACLK 6
|
||||
#define CLK_GOUT_DPU_PPMU_ACLK 7
|
||||
#define CLK_GOUT_DPU_PPMU_PCLK 8
|
||||
#define CLK_GOUT_DPU_SMMU_CLK 9
|
||||
#define CLK_GOUT_DPU_SYSREG_PCLK 10
|
||||
#define DPU_NR_CLK 11
|
||||
|
||||
#endif /* _DT_BINDINGS_CLOCK_EXYNOS_850_H */
|
@ -105,6 +105,16 @@
|
||||
#define CLKID_PERIPH 126
|
||||
#define CLKID_AXI 128
|
||||
#define CLKID_L2_DRAM 130
|
||||
#define CLKID_HDMI_PLL_HDMI_OUT 132
|
||||
#define CLKID_VID_PLL_FINAL_DIV 137
|
||||
#define CLKID_VCLK_IN_SEL 138
|
||||
#define CLKID_VCLK2_IN_SEL 149
|
||||
#define CLKID_CTS_ENCT 161
|
||||
#define CLKID_CTS_ENCP 163
|
||||
#define CLKID_CTS_ENCI 165
|
||||
#define CLKID_HDMI_TX_PIXEL 167
|
||||
#define CLKID_CTS_ENCL 169
|
||||
#define CLKID_CTS_VDAC0 171
|
||||
#define CLKID_HDMI_SYS 174
|
||||
#define CLKID_VPU 190
|
||||
#define CLKID_VDEC_1 196
|
||||
|
Loading…
Reference in New Issue
Block a user