clk: add ao clk for axg
authorYun Cai <yun.cai@amlogic.com>
Thu, 18 May 2017 07:01:03 +0000 (15:01 +0800)
committerYun Cai <yun.cai@amlogic.com>
Tue, 20 Jun 2017 07:06:04 +0000 (15:06 +0800)
PD#142470: add ao clk saradc for axg

Change-Id: Icadbbf6e631a6158daade2feb4bfae31bed3c471
Signed-off-by: Yun Cai <yun.cai@amlogic.com>
Documentation/devicetree/bindings/clock/amlogic,meson-clkc.txt
MAINTAINERS
arch/arm64/boot/dts/amlogic/mesonaxg.dtsi
drivers/amlogic/clk/axg/Makefile
drivers/amlogic/clk/axg/axg.c
drivers/amlogic/clk/axg/axg.h
drivers/amlogic/clk/axg/axg_ao.c [new file with mode: 0644]
include/dt-bindings/clock/amlogic,axg-clkc.h

index bf503d9..7609723 100644 (file)
@@ -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.
index bd8c7ff..7ea8921 100644 (file)
@@ -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 <yun.cai@amlogic.com>
+F:     drivers/amlogic/clk/axg/axg_ao.c
+
index 005266d..c72e8bc 100644 (file)
                        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 {
index 7070d05..93c8433 100644 (file)
@@ -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
index 241dfc1..8742567 100644 (file)
@@ -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;
        /*
index 1c56159..3887676 100644 (file)
 #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 (file)
index 0000000..d37b27b
--- /dev/null
@@ -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 <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <dt-bindings/clock/amlogic,axg-clkc.h>
+
+#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);
+
+
index c546b54..b6d299f 100644 (file)
 #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)
 #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 */