From: Qiufang Dai Date: Thu, 1 Feb 2018 15:38:17 +0000 (+0800) Subject: clock: g12a: add emmc portA and aoclkc X-Git-Tag: khadas-vims-v0.9.6-release~2479 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8bbcb53bd60d88926aac958c5c8bd2fb44020887;p=platform%2Fkernel%2Flinux-amlogic.git clock: g12a: add emmc portA and aoclkc PD#156734: add emmc portA and aoclkc Change-Id: Ib54a6eb113bdce21eacc7a2d460df23ee9129e92 Signed-off-by: Qiufang Dai --- diff --git a/Documentation/devicetree/bindings/clock/amlogic,meson-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,meson-clkc.txt index 6b91cc2..c974ab0 100644 --- a/Documentation/devicetree/bindings/clock/amlogic,meson-clkc.txt +++ b/Documentation/devicetree/bindings/clock/amlogic,meson-clkc.txt @@ -13,6 +13,7 @@ Required Properties: "amlogic,txlx-clkc" - for txlx ee clock "amlogic,txlx-aoclkc" - for txlx ao clock "amlogic,g12a-clkc" - for g12a ee clock + "amlogic,g12a-aoclkc" - for g12a ao clock - reg: physical base address of the clock controller and length of memory mapped region. diff --git a/MAINTAINERS b/MAINTAINERS index e817e7d..704579b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14283,6 +14283,7 @@ F: include/dt-bindings/clock/amlogic,g12a-audio-clk.h F: include/dt-bindings/clock/amlogic,g12a-clkc.h F: drivers/amlogic/clk/g12a/* F: drivers/amlogic/clk/clkc.h +F: drivers/amlogic/clk/g12a/g12a_ao.c AMLOGIC G12A clk tree for media/gpu M: Qiufang Dai @@ -14334,4 +14335,4 @@ F: sound/soc/codecs/amlogic/aml_codec_t9015.c AMLOGIC Audio codec AD82584F driver M: Peipeng Zhao F: sound/soc/codecs/amlogic/ad82584f.c -F: sound/soc/codecs/amlogic/ad82584f.h \ No newline at end of file +F: sound/soc/codecs/amlogic/ad82584f.h diff --git a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi index a71e9f17..e0f6a55 100644 --- a/arch/arm64/boot/dts/amlogic/mesong12a.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesong12a.dtsi @@ -508,6 +508,12 @@ reg=<0x0 0x220 0x0 0x4>; }; + aoclkc: clock-controller@0 { + compatible = "amlogic,g12a-aoclkc"; + #clock-cells = <1>; + reg = <0x0 0x0 0x0 0x320>; + }; + pwm_AO_ab: pwm@7000 { compatible = "amlogic,txlx-ao-pwm"; reg = <0x0 0x7000 0x0 0x20>; diff --git a/drivers/amlogic/clk/g12a/Makefile b/drivers/amlogic/clk/g12a/Makefile index ae81de7..b75522c 100644 --- a/drivers/amlogic/clk/g12a/Makefile +++ b/drivers/amlogic/clk/g12a/Makefile @@ -3,4 +3,4 @@ # obj-$(CONFIG_AMLOGIC_GX_CLK) += g12a.o g12a_clk-pll.o g12a_clk_sdemmc.o g12a_clk-mpll.o \ - g12a_clk_media.o g12a_clk_gpu.o g12a_clk_misc.o + g12a_clk_media.o g12a_clk_gpu.o g12a_clk_misc.o g12a_ao.o diff --git a/drivers/amlogic/clk/g12a/g12a.h b/drivers/amlogic/clk/g12a/g12a.h index b4c9bff..a5bcc63 100644 --- a/drivers/amlogic/clk/g12a/g12a.h +++ b/drivers/amlogic/clk/g12a/g12a.h @@ -104,6 +104,11 @@ #define HHI_SYS_PLL_CNTL5 0x308 /* 0xc2 offset in data sheet */ #define HHI_SYS_PLL_CNTL6 0x30c /* 0xc3 offset in data sheet */ + +/* AO registers*/ +#define AO_RTI_PWR_CNTL_REG0 0x10 /* 0x4 offset in data sheet */ +#define AO_SAR_CLK 0x90 /* 0x24 offset in data sheet */ + /*G12A: pll: FDCO: 3G~6G FDCO = 24*(M+frac)/N *N: recommend is 1 *clk_out = FDCO >> OD diff --git a/drivers/amlogic/clk/g12a/g12a_ao.c b/drivers/amlogic/clk/g12a/g12a_ao.c new file mode 100644 index 0000000..594aaf0 --- /dev/null +++ b/drivers/amlogic/clk/g12a/g12a_ao.c @@ -0,0 +1,144 @@ +/* + * drivers/amlogic/clk/g12a/g12a_ao.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../clkc.h" +#include "g12a.h" + +/* #undef pr_debug */ +/* #define pr_debug pr_info */ +static void __iomem *ao_clk_base; + +static struct clk_mux aoclk81 = { + .reg = (void *)AO_RTI_PWR_CNTL_REG0, + .mask = 0x1, + .shift = 8, + .flags = CLK_MUX_READ_ONLY, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "aoclk81", + .ops = &clk_mux_ops, + .parent_names = (const char *[]){ "clk81", "ao_slow_clk" }, + .num_parents = 2, + .flags = (CLK_SET_RATE_NO_REPARENT), + }, +}; + +/* sar_adc_clk */ +static struct clk_mux g12a_saradc_mux = { + .reg = (void *)AO_SAR_CLK, + .mask = 0x3, + .shift = 9, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "g12a_saradc_mux", + .ops = &clk_mux_ops, + .parent_names = (const char *[]){ "xtal", "aoclk81"}, + .num_parents = 2, + .flags = (CLK_GET_RATE_NOCACHE), + }, +}; + +static struct clk_divider g12a_saradc_div = { + .reg = (void *)AO_SAR_CLK, + .shift = 0, + .width = 8, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "g12a_saradc_div", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "g12a_saradc_mux" }, + .num_parents = 1, + .flags = (CLK_DIVIDER_ROUND_CLOSEST), + }, +}; + +static struct clk_gate g12a_saradc_gate = { + .reg = (void *)AO_SAR_CLK, + .bit_idx = 8, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "g12a_saradc_gate", + .ops = &clk_gate_ops, + .parent_names = (const char *[]){ "g12a_saradc_div" }, + .num_parents = 1, + .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), + }, +}; + +/* Array of all clocks provided by this provider */ + +static struct clk_hw *g12a_ao_clk_hws[] = { + [CLKID_AO_CLK81 - CLKID_AO_CLK81] + = &aoclk81.hw, + [CLKID_SARADC_MUX - CLKID_AO_CLK81] + = &g12a_saradc_mux.hw, + [CLKID_SARADC_DIV - CLKID_AO_CLK81] + = &g12a_saradc_div.hw, + [CLKID_SARADC_GATE - CLKID_AO_CLK81] + = &g12a_saradc_gate.hw, +}; + +static void __init g12a_aoclkc_init(struct device_node *np) +{ + int clkid; + + /* Generic clocks and PLLs */ + ao_clk_base = of_iomap(np, 0); + if (!ao_clk_base) { + pr_err("%s: Unable to map clk base\n", __func__); + /* return -ENXIO; */ + return; + } + /* pr_debug("%s: iomap clk_base ok!", __func__); */ + /* Populate the base address for ao clk */ + aoclk81.reg = ao_clk_base + (u64)aoclk81.reg; + g12a_saradc_mux.reg = ao_clk_base + (u64)g12a_saradc_mux.reg; + g12a_saradc_div.reg = ao_clk_base + (u64)g12a_saradc_div.reg; + g12a_saradc_gate.reg = ao_clk_base + (u64)g12a_saradc_gate.reg; + + if (!clks) { + clks = kzalloc(NR_CLKS*sizeof(struct clk *), GFP_KERNEL); + if (!clks) { + /* pr_err("%s: alloc clks fail!", __func__); */ + /* return -ENOMEM; */ + return; + } + } + + for (clkid = CLKID_AO_BASE; clkid < NR_CLKS; clkid++) { + if (g12a_ao_clk_hws[clkid - CLKID_AO_BASE]) { + clks[clkid] = clk_register(NULL, + g12a_ao_clk_hws[clkid - CLKID_AO_BASE]); + WARN_ON(IS_ERR(clks[clkid])); + } + } + + pr_info("%s: register ao clk ok!\n", __func__); + /*of_clk_add_provider in ee clk g12a_clkc_init*/ +} + +CLK_OF_DECLARE(g12a, "amlogic,g12a-aoclkc", g12a_aoclkc_init); + + diff --git a/drivers/amlogic/clk/g12a/g12a_clk_sdemmc.c b/drivers/amlogic/clk/g12a/g12a_clk_sdemmc.c index acd96e0..c4388bb 100644 --- a/drivers/amlogic/clk/g12a/g12a_clk_sdemmc.c +++ b/drivers/amlogic/clk/g12a/g12a_clk_sdemmc.c @@ -29,6 +29,47 @@ static const char * const sd_emmc_parent_names[] = { "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7", "mpll2", "mpll3", "gp0" }; +static struct clk_mux sd_emmc_p0_mux_A = { + .reg = (void *)HHI_SD_EMMC_CLK_CNTL, + .mask = 0x7, + .shift = 9, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "sd_emmc_p0_mux_A", + .ops = &clk_mux_ops, + .parent_names = sd_emmc_parent_names, + .num_parents = 8, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_divider sd_emmc_p0_div_A = { + .reg = (void *)HHI_SD_EMMC_CLK_CNTL, + .shift = 0, + .width = 7, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "sd_emmc_p0_div_A", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "sd_emmc_p0_mux_A" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_gate sd_emmc_p0_gate_A = { + .reg = (void *)HHI_SD_EMMC_CLK_CNTL, + .bit_idx = 7, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data) { + .name = "sd_emmc_p0_gate_A", + .ops = &clk_gate_ops, + .parent_names = (const char *[]){ "sd_emmc_p0_div_A" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + static struct clk_mux sd_emmc_p0_mux_B = { .reg = (void *)HHI_SD_EMMC_CLK_CNTL, .mask = 0x7, @@ -112,17 +153,23 @@ static struct clk_gate sd_emmc_p0_gate_C = { }; static struct clk_hw *sd_emmc_clk_hws[] = { - [CLKID_SD_EMMC_B_P0_MUX - CLKID_SD_EMMC_B_P0_MUX] + [CLKID_SD_EMMC_A_P0_MUX - CLKID_SD_EMMC_A_P0_MUX] + = &sd_emmc_p0_mux_A.hw, + [CLKID_SD_EMMC_A_P0_DIV - CLKID_SD_EMMC_A_P0_MUX] + = &sd_emmc_p0_div_A.hw, + [CLKID_SD_EMMC_A_P0_GATE - CLKID_SD_EMMC_A_P0_MUX] + = &sd_emmc_p0_gate_A.hw, + [CLKID_SD_EMMC_B_P0_MUX - CLKID_SD_EMMC_A_P0_MUX] = &sd_emmc_p0_mux_B.hw, - [CLKID_SD_EMMC_B_P0_DIV - CLKID_SD_EMMC_B_P0_MUX] + [CLKID_SD_EMMC_B_P0_DIV - CLKID_SD_EMMC_A_P0_MUX] = &sd_emmc_p0_div_B.hw, - [CLKID_SD_EMMC_B_P0_GATE - CLKID_SD_EMMC_B_P0_MUX] + [CLKID_SD_EMMC_B_P0_GATE - CLKID_SD_EMMC_A_P0_MUX] = &sd_emmc_p0_gate_B.hw, - [CLKID_SD_EMMC_C_P0_MUX - CLKID_SD_EMMC_B_P0_MUX] + [CLKID_SD_EMMC_C_P0_MUX - CLKID_SD_EMMC_A_P0_MUX] = &sd_emmc_p0_mux_C.hw, - [CLKID_SD_EMMC_C_P0_DIV - CLKID_SD_EMMC_B_P0_MUX] + [CLKID_SD_EMMC_C_P0_DIV - CLKID_SD_EMMC_A_P0_MUX] = &sd_emmc_p0_div_C.hw, - [CLKID_SD_EMMC_C_P0_GATE - CLKID_SD_EMMC_B_P0_MUX] + [CLKID_SD_EMMC_C_P0_GATE - CLKID_SD_EMMC_A_P0_MUX] = &sd_emmc_p0_gate_C.hw, }; @@ -132,6 +179,9 @@ void meson_g12a_sdemmc_init(void) /* Populate base address for reg */ pr_info("%s: register amlogic sdemmc clk\n", __func__); + sd_emmc_p0_mux_A.reg = clk_base + (u64)(sd_emmc_p0_mux_A.reg); + sd_emmc_p0_div_A.reg = clk_base + (u64)(sd_emmc_p0_div_A.reg); + sd_emmc_p0_gate_A.reg = clk_base + (u64)(sd_emmc_p0_gate_A.reg); sd_emmc_p0_mux_B.reg = clk_base + (u64)(sd_emmc_p0_mux_B.reg); sd_emmc_p0_div_B.reg = clk_base + (u64)(sd_emmc_p0_div_B.reg); sd_emmc_p0_gate_B.reg = clk_base + (u64)(sd_emmc_p0_gate_B.reg); @@ -139,14 +189,27 @@ void meson_g12a_sdemmc_init(void) sd_emmc_p0_div_C.reg = clk_base + (u64)(sd_emmc_p0_div_C.reg); sd_emmc_p0_gate_C.reg = clk_base + (u64)(sd_emmc_p0_gate_C.reg); + clks[CLKID_SD_EMMC_A_P0_COMP] = clk_register_composite(NULL, + "sd_emmc_p0_A_comp", + sd_emmc_parent_names, 8, + sd_emmc_clk_hws[CLKID_SD_EMMC_A_P0_MUX - CLKID_SD_EMMC_A_P0_MUX], + &clk_mux_ops, + sd_emmc_clk_hws[CLKID_SD_EMMC_A_P0_DIV - CLKID_SD_EMMC_A_P0_MUX], + &clk_divider_ops, + sd_emmc_clk_hws[CLKID_SD_EMMC_A_P0_GATE - CLKID_SD_EMMC_A_P0_MUX], + &clk_gate_ops, 0); + if (IS_ERR(clks[CLKID_SD_EMMC_A_P0_COMP])) + pr_err("%s: %d clk_register_composite sd_emmc_p0_A_comp error\n", + __func__, __LINE__); + clks[CLKID_SD_EMMC_B_P0_COMP] = clk_register_composite(NULL, "sd_emmc_p0_B_comp", sd_emmc_parent_names, 8, - sd_emmc_clk_hws[CLKID_SD_EMMC_B_P0_MUX - CLKID_SD_EMMC_B_P0_MUX], + sd_emmc_clk_hws[CLKID_SD_EMMC_B_P0_MUX - CLKID_SD_EMMC_A_P0_MUX], &clk_mux_ops, - sd_emmc_clk_hws[CLKID_SD_EMMC_B_P0_DIV - CLKID_SD_EMMC_B_P0_MUX], + sd_emmc_clk_hws[CLKID_SD_EMMC_B_P0_DIV - CLKID_SD_EMMC_A_P0_MUX], &clk_divider_ops, - sd_emmc_clk_hws[CLKID_SD_EMMC_B_P0_GATE - CLKID_SD_EMMC_B_P0_MUX], + sd_emmc_clk_hws[CLKID_SD_EMMC_B_P0_GATE - CLKID_SD_EMMC_A_P0_MUX], &clk_gate_ops, 0); if (IS_ERR(clks[CLKID_SD_EMMC_B_P0_COMP])) pr_err("%s: %d clk_register_composite sd_emmc_p0_B_comp error\n", @@ -155,11 +218,11 @@ void meson_g12a_sdemmc_init(void) clks[CLKID_SD_EMMC_C_P0_COMP] = clk_register_composite(NULL, "sd_emmc_p0_C_comp", sd_emmc_parent_names, 8, - sd_emmc_clk_hws[CLKID_SD_EMMC_C_P0_MUX - CLKID_SD_EMMC_B_P0_MUX], + sd_emmc_clk_hws[CLKID_SD_EMMC_C_P0_MUX - CLKID_SD_EMMC_A_P0_MUX], &clk_mux_ops, - sd_emmc_clk_hws[CLKID_SD_EMMC_C_P0_DIV - CLKID_SD_EMMC_B_P0_MUX], + sd_emmc_clk_hws[CLKID_SD_EMMC_C_P0_DIV - CLKID_SD_EMMC_A_P0_MUX], &clk_divider_ops, - sd_emmc_clk_hws[CLKID_SD_EMMC_C_P0_GATE - CLKID_SD_EMMC_B_P0_MUX], + sd_emmc_clk_hws[CLKID_SD_EMMC_C_P0_GATE - CLKID_SD_EMMC_A_P0_MUX], &clk_gate_ops, 0); if (IS_ERR(clks[CLKID_SD_EMMC_C_P0_COMP])) pr_err("%s: %d clk_register_composite sd_emmc_p0_C_comp error\n", diff --git a/include/dt-bindings/clock/amlogic,g12a-clkc.h b/include/dt-bindings/clock/amlogic,g12a-clkc.h index 0c8e07f..10d53e6 100644 --- a/include/dt-bindings/clock/amlogic,g12a-clkc.h +++ b/include/dt-bindings/clock/amlogic,g12a-clkc.h @@ -140,24 +140,28 @@ #define CLKID_AO_I2C (GATE_AO_BASE + 4) #define OTHER_BASE (GATE_AO_BASE + 5) -#define CLKID_SD_EMMC_B_P0_MUX (OTHER_BASE + 0) -#define CLKID_SD_EMMC_B_P0_DIV (OTHER_BASE + 1) -#define CLKID_SD_EMMC_B_P0_GATE (OTHER_BASE + 2) -#define CLKID_SD_EMMC_B_P0_COMP (OTHER_BASE + 3) -#define CLKID_SD_EMMC_C_P0_MUX (OTHER_BASE + 4) -#define CLKID_SD_EMMC_C_P0_DIV (OTHER_BASE + 5) -#define CLKID_SD_EMMC_C_P0_GATE (OTHER_BASE + 6) -#define CLKID_SD_EMMC_C_P0_COMP (OTHER_BASE + 7) -#define CLKID_SD_EMMC_B_MUX (OTHER_BASE + 8) -#define CLKID_SD_EMMC_B_DIV (OTHER_BASE + 9) -#define CLKID_SD_EMMC_B_GATE (OTHER_BASE + 10) -#define CLKID_SD_EMMC_B_COMP (OTHER_BASE + 11) -#define CLKID_SD_EMMC_C_MUX (OTHER_BASE + 12) -#define CLKID_SD_EMMC_C_DIV (OTHER_BASE + 13) -#define CLKID_SD_EMMC_C_GATE (OTHER_BASE + 14) -#define CLKID_SD_EMMC_C_COMP (OTHER_BASE + 15) +#define CLKID_SD_EMMC_A_P0_MUX (OTHER_BASE + 0) +#define CLKID_SD_EMMC_A_P0_DIV (OTHER_BASE + 1) +#define CLKID_SD_EMMC_A_P0_GATE (OTHER_BASE + 2) +#define CLKID_SD_EMMC_A_P0_COMP (OTHER_BASE + 3) +#define CLKID_SD_EMMC_B_P0_MUX (OTHER_BASE + 4) +#define CLKID_SD_EMMC_B_P0_DIV (OTHER_BASE + 5) +#define CLKID_SD_EMMC_B_P0_GATE (OTHER_BASE + 6) +#define CLKID_SD_EMMC_B_P0_COMP (OTHER_BASE + 7) +#define CLKID_SD_EMMC_C_P0_MUX (OTHER_BASE + 8) +#define CLKID_SD_EMMC_C_P0_DIV (OTHER_BASE + 9) +#define CLKID_SD_EMMC_C_P0_GATE (OTHER_BASE + 10) +#define CLKID_SD_EMMC_C_P0_COMP (OTHER_BASE + 11) +#define CLKID_SD_EMMC_B_MUX (OTHER_BASE + 12) +#define CLKID_SD_EMMC_B_DIV (OTHER_BASE + 13) +#define CLKID_SD_EMMC_B_GATE (OTHER_BASE + 14) +#define CLKID_SD_EMMC_B_COMP (OTHER_BASE + 15) +#define CLKID_SD_EMMC_C_MUX (OTHER_BASE + 16) +#define CLKID_SD_EMMC_C_DIV (OTHER_BASE + 17) +#define CLKID_SD_EMMC_C_GATE (OTHER_BASE + 18) +#define CLKID_SD_EMMC_C_COMP (OTHER_BASE + 19) -#define CLKID_GPU_BASE (OTHER_BASE + 16) +#define CLKID_GPU_BASE (OTHER_BASE + 20) #define CLKID_GPU_P0_MUX (CLKID_GPU_BASE + 0) #define CLKID_GPU_P0_DIV (CLKID_GPU_BASE + 1) #define CLKID_GPU_P0_GATE (CLKID_GPU_BASE + 2)