From c924fd661a5a3212b76dcc9db63dc6405deb07d2 Mon Sep 17 00:00:00 2001 From: Yun Cai Date: Thu, 18 May 2017 15:01:03 +0800 Subject: [PATCH] clk: add ao clk for axg PD#142470: add ao clk saradc for axg Change-Id: Icadbbf6e631a6158daade2feb4bfae31bed3c471 Signed-off-by: Yun Cai --- .../bindings/clock/amlogic,meson-clkc.txt | 1 + MAINTAINERS | 5 + arch/arm64/boot/dts/amlogic/mesonaxg.dtsi | 6 + drivers/amlogic/clk/axg/Makefile | 2 +- drivers/amlogic/clk/axg/axg.c | 8 +- drivers/amlogic/clk/axg/axg.h | 4 + drivers/amlogic/clk/axg/axg_ao.c | 142 +++++++++++++++++++++ include/dt-bindings/clock/amlogic,axg-clkc.h | 22 ++-- 8 files changed, 180 insertions(+), 10 deletions(-) create mode 100644 drivers/amlogic/clk/axg/axg_ao.c diff --git a/Documentation/devicetree/bindings/clock/amlogic,meson-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,meson-clkc.txt index bf503d9..7609723 100644 --- a/Documentation/devicetree/bindings/clock/amlogic,meson-clkc.txt +++ b/Documentation/devicetree/bindings/clock/amlogic,meson-clkc.txt @@ -9,6 +9,7 @@ Required Properties: "amlogic,gxl-aoclkc" - for gxl ao clock "amlogic,gxl-clkc" - for gxl ee clock "amlogic,axg-clkc" - for axg ee clock + "amlogic,axg-aoclkc" - for axg ao clock - reg: physical base address of the clock controller and length of memory mapped region. diff --git a/MAINTAINERS b/MAINTAINERS index bd8c7ff..7ea8921 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13956,3 +13956,8 @@ F: drivers/amlogic/media/vout/lcd/* F: include/linux/amlogic/media/vout/lcd/* F: arch/arm64/boot/dts/amlogic/mesongxm_q200-panel.dtsi F: arch/arm64/boot/dts/amlogic/mesonaxg_s400-panel.dtsi + +AMLOGIC AXG ADD AO CLK +M: Yun Cai +F: drivers/amlogic/clk/axg/axg_ao.c + diff --git a/arch/arm64/boot/dts/amlogic/mesonaxg.dtsi b/arch/arm64/boot/dts/amlogic/mesonaxg.dtsi index 005266d..c72e8bc 100644 --- a/arch/arm64/boot/dts/amlogic/mesonaxg.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesonaxg.dtsi @@ -302,6 +302,12 @@ cpu_version { reg=<0x0 0x220 0x0 0x4>; }; + + aoclkc: clock-controller@0 { + compatible = "amlogic,axg-aoclkc"; + #clock-cells = <1>; + reg = <0x0 0x0 0x0 0x320>; + }; };/* end of aobus */ periphs: periphs@ff634400 { diff --git a/drivers/amlogic/clk/axg/Makefile b/drivers/amlogic/clk/axg/Makefile index 7070d05..93c8433 100644 --- a/drivers/amlogic/clk/axg/Makefile +++ b/drivers/amlogic/clk/axg/Makefile @@ -2,6 +2,6 @@ # Makefile for Meson AXG clk # -obj-$(CONFIG_AMLOGIC_GX_CLK) += axg.o \ +obj-$(CONFIG_AMLOGIC_GX_CLK) += axg.o axg_ao.o\ axg_clk-pll.o \ axg_clk_sdemmc.o axg_clk_media.o axg_clk_misc.o diff --git a/drivers/amlogic/clk/axg/axg.c b/drivers/amlogic/clk/axg/axg.c index 241dfc1..8742567 100644 --- a/drivers/amlogic/clk/axg/axg.c +++ b/drivers/amlogic/clk/axg/axg.c @@ -811,13 +811,19 @@ static void __init axg_clkc_init(struct device_node *np) axg_clk_gates[i]->reg = clk_base + (u64)axg_clk_gates[i]->reg; +#if 0 clks = kzalloc(NR_CLKS*sizeof(struct clk *), GFP_KERNEL); if (!clks) { /* pr_err("%s: alloc clks fail!", __func__); */ /* return -ENOMEM; */ return; } - /* pr_debug("%s: kzalloc clks ok!", __func__); */ +#endif + if (NULL == clks) { + pr_err("%s: error: not kzalloc clks in aoclk!", __func__); + return; + } + clk_data.clks = clks; clk_data.clk_num = NR_CLKS; /* diff --git a/drivers/amlogic/clk/axg/axg.h b/drivers/amlogic/clk/axg/axg.h index 1c56159..3887676 100644 --- a/drivers/amlogic/clk/axg/axg.h +++ b/drivers/amlogic/clk/axg/axg.h @@ -80,6 +80,10 @@ #define HHI_SYS_PLL_CNTL4 0x30c /* 0xc3 offset in data sheet */ #define HHI_SYS_PLL_CNTL5 0x310 /* 0xc4 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 */ + static const struct pll_rate_table sys_pll_rate_table[] = { PLL_RATE(24000000, 56, 1, 2), PLL_RATE(48000000, 64, 1, 2), diff --git a/drivers/amlogic/clk/axg/axg_ao.c b/drivers/amlogic/clk/axg/axg_ao.c new file mode 100644 index 0000000..d37b27b --- /dev/null +++ b/drivers/amlogic/clk/axg/axg_ao.c @@ -0,0 +1,142 @@ +/* + * drivers/amlogic/clk/axg/axg_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 "axg.h" + +/* #undef pr_debug */ +/* #define pr_debug pr_info */ +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 axg_saradc_mux = { + .reg = (void *)AO_SAR_CLK, + .mask = 0x3, + .shift = 9, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "axg_saradc_mux", + .ops = &clk_mux_ops, + .parent_names = (const char *[]){ "xtal", "aoclk81"}, + .num_parents = 2, + .flags = (CLK_GET_RATE_NOCACHE), + }, +}; + +static struct clk_divider axg_saradc_div = { + .reg = (void *)AO_SAR_CLK, + .shift = 0, + .width = 7, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "axg_saradc_div", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "axg_saradc_mux" }, + .num_parents = 1, + .flags = (CLK_DIVIDER_ROUND_CLOSEST), + }, +}; + +static struct clk_gate axg_saradc_gate = { + .reg = (void *)AO_SAR_CLK, + .bit_idx = 8, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "axg_saradc_gate", + .ops = &clk_gate_ops, + .parent_names = (const char *[]){ "axg_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 *axg_ao_clk_hws[] = { + [CLKID_AO_CLK81 - CLKID_AO_CLK81] + = &aoclk81.hw, + [CLKID_SARADC_MUX - CLKID_AO_CLK81] + = &axg_saradc_mux.hw, + [CLKID_SARADC_DIV - CLKID_AO_CLK81] + = &axg_saradc_div.hw, + [CLKID_SARADC_GATE - CLKID_AO_CLK81] + = &axg_saradc_gate.hw, +}; + +static void __init axg_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; + axg_saradc_mux.reg = ao_clk_base + (u64)axg_saradc_mux.reg; + axg_saradc_div.reg = ao_clk_base + (u64)axg_saradc_div.reg; + axg_saradc_gate.reg = ao_clk_base + (u64)axg_saradc_gate.reg; + + 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 (axg_ao_clk_hws[clkid - CLKID_AO_BASE]) { + clks[clkid] = clk_register(NULL, + axg_ao_clk_hws[clkid - CLKID_AO_BASE]); + WARN_ON(IS_ERR(clks[clkid])); + } + } + + pr_info("%s: register ao clk ok!", __func__); + /*of_clk_add_provider in ee clk axg_clkc_init*/ +} + +CLK_OF_DECLARE(axg, "amlogic,axg-aoclkc", axg_aoclkc_init); + + diff --git a/include/dt-bindings/clock/amlogic,axg-clkc.h b/include/dt-bindings/clock/amlogic,axg-clkc.h index c546b54..b6d299f 100644 --- a/include/dt-bindings/clock/amlogic,axg-clkc.h +++ b/include/dt-bindings/clock/amlogic,axg-clkc.h @@ -97,14 +97,14 @@ #define CLKID_SEC_AHB_AHB3_BRIDGE (GATE_BASE2 + 6) #define CLKID_GIC (GATE_BASE2 + 7) -#define AO_BASE (GATE_BASE2 + 8) /*28+20+11+8*/ -#define CLKID_AO_MEDIA_CPU (AO_BASE + 0) -#define CLKID_AO_AHB_SRAM (AO_BASE + 1) -#define CLKID_AO_AHB_BUS (AO_BASE + 2) -#define CLKID_AO_IFACE (AO_BASE + 3) -#define CLKID_AO_I2C (AO_BASE + 4) +#define GATE_AO_BASE (GATE_BASE2 + 8) /*28+20+11+8*/ +#define CLKID_AO_MEDIA_CPU (GATE_AO_BASE + 0) +#define CLKID_AO_AHB_SRAM (GATE_AO_BASE + 1) +#define CLKID_AO_AHB_BUS (GATE_AO_BASE + 2) +#define CLKID_AO_IFACE (GATE_AO_BASE + 3) +#define CLKID_AO_I2C (GATE_AO_BASE + 4) -#define OTHER_BASE (AO_BASE + 5) /*28+20+11+8+5=72*/ +#define OTHER_BASE (GATE_AO_BASE + 5) /*28+20+11+8+5=72*/ #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) @@ -153,6 +153,12 @@ #define CLKID_SPICC_GATE (CLKID_MISC_BASE + 2) #define CLKID_SPICC_COMP (CLKID_MISC_BASE + 3) -#define NR_CLKS (OTHER_BASE + 43) +#define CLKID_AO_BASE (CLKID_MISC_BASE + 4) /*28+20+11+8+5+16+23+4 = 115*/ +#define CLKID_AO_CLK81 (CLKID_AO_BASE + 0) +#define CLKID_SARADC_MUX (CLKID_AO_BASE + 1) +#define CLKID_SARADC_DIV (CLKID_AO_BASE + 2) +#define CLKID_SARADC_GATE (CLKID_AO_BASE + 3) + +#define NR_CLKS (OTHER_BASE + 47) #endif /* __GX_CLKC_H */ -- 2.7.4