clk: move from driver/clk/meson

PD#141217: initialize clock tree

Change-Id: Ie00bbdd65b4e430434e66d4c1f4275a6c46ee44a
Signed-off-by: Yun Cai <yun.cai@amlogic.com>
This commit is contained in:
Yun Cai
2017-03-23 19:11:07 +08:00
committed by Jianxin Pan
parent 08e78d81be
commit d3e988b452
9 changed files with 1147 additions and 8 deletions

View File

@@ -42,6 +42,9 @@ CONFIG_AMLOGIC_DRIVER=y
CONFIG_AMLOGIC_UART=y
CONFIG_AMLOGIC_SERIAL_MESON_CONSOLE=y
CONFIG_AMLOGIC_IOMAP=y
CONFIG_AMLOGIC_CLK=y
# CONFIG_AMLOGIC_RESET is not set
CONFIG_AMLOGIC_M8B_CLK=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_DMA_CMA=y

View File

@@ -8,7 +8,6 @@ menuconfig ARCH_MESON
select PINCTRL
select PINCTRL_MESON
select COMMON_CLK
select COMMON_CLK_AMLOGIC
if ARCH_MESON
@@ -26,6 +25,5 @@ config MACH_MESON8B
bool "Amlogic Meson8b SoCs support"
default ARCH_MESON
select MESON6_TIMER
select COMMON_CLK_MESON8B
endif

View File

@@ -22,4 +22,19 @@ config AMLOGIC_COMMON_CLK_SCPI
by firmware that implements the SCPI interface.
This driver uses SCPI Message Protocol to interact with the
firmware providing all the clock controls.
firmware providing all the clock controls.
config AMLOGIC_M8B_CLK
bool "Amlogic meson8b clock driver support"
depends on AMLOGIC_CLK
help
Support for the clock controller on AmLogic S805 devices, aka
meson8b. Say Y if you want peripherals and CPU frequency scaling to
work.
config AMLOGIC_GX_CLK
bool "Amlogic gx clock driver support"
depends on AMLOGIC_CLK
help
Support for the clock controller on AmLogic S905 devices, aka gxbb.
Say Y if you want peripherals and CPU frequency scaling to work.

View File

@@ -5,8 +5,16 @@
obj-$(CONFIG_AMLOGIC_COMMON_CLK_SCPI) += clk-scpi.o
obj-$(CONFIG_AMLOGIC_RESET) += rstc.o
obj-$(CONFIG_AMLOGIC_CLK) += clk-pll.o clk-cpu.o clk-mpll.o \
gxl.o clk_measure.o \
clk_sdemmc.o clk_gpu.o clk_media.o clk_misc.o\
clk-mux.o
obj-$(CONFIG_AMLOGIC_CLK) += clk_test.o
#obj-$(CONFIG_AMLOGIC_CLK) += clk-pll.o clk-cpu.o clk-mpll.o \
# clk_measure.o \
# clk_sdemmc.o clk_gpu.o clk_media.o clk_misc.o\
# clk-mux.o
obj-$(CONFIG_AMLOGIC_CLK) += clk-pll.o
obj-$(COMMON_AMLOGIC_GX_CLK) += clk-cpu.o clk-mpll.o clk-mux.o\
clk_measure.o clk_sdemmc.o clk_gpu.o clk_media.o clk_misc.o\
clk_gxl.o
obj-$(CONFIG_AMLOGIC_M8B_CLK) += m8b/clk-cpu.o m8b/meson8b.o
#obj-$(CONFIG_AMLOGIC_CLK) += clk_test.o

View File

@@ -0,0 +1,178 @@
/*
* Copyright (c) 2015 Endless Mobile, Inc.
* Author: Carlo Caione <carlo@endlessm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* CPU clock path:
*
* +-[/N]-----|3|
* MUX2 +--[/3]-+----------|2| MUX1
* [sys_pll]---|1| |--[/2]------------|1|-|1|
* | |---+------------------|0| | |----- [a5_clk]
* +--|0| | |
* [xtal]---+-------------------------------|0|
*
*
*
*/
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#define MESON_CPU_CLK_CNTL1 0x00
#define MESON_CPU_CLK_CNTL 0x40
#define MESON_CPU_CLK_MUX1 BIT(7)
#define MESON_CPU_CLK_MUX2 BIT(0)
#define MESON_N_WIDTH 9
#define MESON_N_SHIFT 20
#define MESON_SEL_WIDTH 2
#define MESON_SEL_SHIFT 2
#include "clkc.h"
#define to_meson_clk_cpu_hw(_hw) container_of(_hw, struct meson_clk_cpu, hw)
#define to_meson_clk_cpu_nb(_nb) container_of(_nb, struct meson_clk_cpu, clk_nb)
static long meson_clk_cpu_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_hw(hw);
return divider_round_rate(hw, rate, prate, clk_cpu->div_table,
MESON_N_WIDTH, CLK_DIVIDER_ROUND_CLOSEST);
}
static int meson_clk_cpu_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_hw(hw);
unsigned int div, sel, N = 0;
u32 reg;
div = DIV_ROUND_UP(parent_rate, rate);
if (div <= 3) {
sel = div - 1;
} else {
sel = 3;
N = div / 2;
}
reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL1);
reg = PARM_SET(MESON_N_WIDTH, MESON_N_SHIFT, reg, N);
writel(reg, clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL1);
reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL);
reg = PARM_SET(MESON_SEL_WIDTH, MESON_SEL_SHIFT, reg, sel);
writel(reg, clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL);
return 0;
}
static unsigned long meson_clk_cpu_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_hw(hw);
unsigned int N, sel;
unsigned int div = 1;
u32 reg;
reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL1);
N = PARM_GET(MESON_N_WIDTH, MESON_N_SHIFT, reg);
reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL);
sel = PARM_GET(MESON_SEL_WIDTH, MESON_SEL_SHIFT, reg);
if (sel < 3)
div = sel + 1;
else
div = 2 * N;
return parent_rate / div;
}
/* FIXME MUX1 & MUX2 should be struct clk_hw objects */
static int meson_clk_cpu_pre_rate_change(struct meson_clk_cpu *clk_cpu,
struct clk_notifier_data *ndata)
{
u32 cpu_clk_cntl;
/* switch MUX1 to xtal */
cpu_clk_cntl = readl(clk_cpu->base + clk_cpu->reg_off
+ MESON_CPU_CLK_CNTL);
cpu_clk_cntl &= ~MESON_CPU_CLK_MUX1;
writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
+ MESON_CPU_CLK_CNTL);
udelay(100);
/* switch MUX2 to sys-pll */
cpu_clk_cntl |= MESON_CPU_CLK_MUX2;
writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
+ MESON_CPU_CLK_CNTL);
return 0;
}
/* FIXME MUX1 & MUX2 should be struct clk_hw objects */
static int meson_clk_cpu_post_rate_change(struct meson_clk_cpu *clk_cpu,
struct clk_notifier_data *ndata)
{
u32 cpu_clk_cntl;
/* switch MUX1 to divisors' output */
cpu_clk_cntl = readl(clk_cpu->base + clk_cpu->reg_off
+ MESON_CPU_CLK_CNTL);
cpu_clk_cntl |= MESON_CPU_CLK_MUX1;
writel(cpu_clk_cntl, clk_cpu->base + clk_cpu->reg_off
+ MESON_CPU_CLK_CNTL);
udelay(100);
return 0;
}
/*
* This clock notifier is called when the frequency of the of the parent
* PLL clock is to be changed. We use the xtal input as temporary parent
* while the PLL frequency is stabilized.
*/
int meson_clk_cpu_notifier_cb(struct notifier_block *nb,
unsigned long event, void *data)
{
struct clk_notifier_data *ndata = data;
struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_nb(nb);
int ret = 0;
if (event == PRE_RATE_CHANGE)
ret = meson_clk_cpu_pre_rate_change(clk_cpu, ndata);
else if (event == POST_RATE_CHANGE)
ret = meson_clk_cpu_post_rate_change(clk_cpu, ndata);
return notifier_from_errno(ret);
}
const struct clk_ops meson_clk_cpu_ops = {
.recalc_rate = meson_clk_cpu_recalc_rate,
.round_rate = meson_clk_cpu_round_rate,
.set_rate = meson_clk_cpu_set_rate,
};

View File

@@ -0,0 +1,120 @@
/*
* Copyright (c) 2015 Endless Mobile, Inc.
* Author: Carlo Caione <carlo@endlessm.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CLKC_H
#define __CLKC_H
#define PMASK(width) GENMASK(width - 1, 0)
#define SETPMASK(width, shift) GENMASK(shift + width - 1, shift)
#define CLRPMASK(width, shift) (~SETPMASK(width, shift))
#define PARM_GET(width, shift, reg) \
(((reg) & SETPMASK(width, shift)) >> (shift))
#define PARM_SET(width, shift, reg, val) \
(((reg) & CLRPMASK(width, shift)) | (val << (shift)))
#define MESON_PARM_APPLICABLE(p) (!!((p)->width))
struct parm {
u16 reg_off;
u8 shift;
u8 width;
};
struct pll_rate_table {
unsigned long rate;
u16 m;
u16 n;
u16 od;
u16 od2;
u16 frac;
};
#define PLL_RATE(_r, _m, _n, _od) \
{ \
.rate = (_r), \
.m = (_m), \
.n = (_n), \
.od = (_od), \
} \
#define PLL_FRAC_RATE(_r, _m, _n, _od, _od2, _frac) \
{ \
.rate = (_r), \
.m = (_m), \
.n = (_n), \
.od = (_od), \
.od2 = (_od2), \
.frac = (_frac), \
} \
struct meson_clk_pll {
struct clk_hw hw;
void __iomem *base;
struct parm m;
struct parm n;
struct parm frac;
struct parm od;
struct parm od2;
const struct pll_rate_table *rate_table;
unsigned int rate_count;
spinlock_t *lock;
};
#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
struct meson_clk_cpu {
struct clk_hw hw;
void __iomem *base;
u16 reg_off;
struct notifier_block clk_nb;
const struct clk_div_table *div_table;
};
int meson_clk_cpu_notifier_cb(struct notifier_block *nb, unsigned long event,
void *data);
struct meson_clk_mpll {
struct clk_hw hw;
void __iomem *base;
struct parm sdm;
struct parm n2;
/* FIXME ssen gate control? */
spinlock_t *lock;
};
#define MESON_GATE(_name, _reg, _bit) \
struct clk_gate _name = { \
.reg = (void __iomem *) _reg, \
.bit_idx = (_bit), \
.lock = &clk_lock, \
.hw.init = &(struct clk_init_data) { \
.name = #_name, \
.ops = &clk_gate_ops, \
.parent_names = (const char *[]){ "clk81" }, \
.num_parents = 1, \
.flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
}, \
};
/* clk_ops */
extern const struct clk_ops meson_clk_pll_ro_ops;
extern const struct clk_ops meson_clk_pll_ops;
extern const struct clk_ops meson_clk_cpu_ops;
extern const struct clk_ops meson_clk_mpll_ro_ops;
#endif /* __CLKC_H */

View File

@@ -0,0 +1,681 @@
/*
* AmLogic S805 / Meson8b Clock Controller Driver
*
* Copyright (c) 2015 Endless Mobile, Inc.
* Author: Carlo Caione <carlo@endlessm.com>
*
* Copyright (c) 2016 BayLibre, Inc.
* Michael Turquette <mturquette@baylibre.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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/meson8b-clkc.h>
#include "clkc.h"
#include "meson8b.h"
static DEFINE_SPINLOCK(clk_lock);
struct clk **clks;
static struct clk_onecell_data clk_data;
static const struct pll_rate_table sys_pll_rate_table[] = {
PLL_RATE(312000000, 52, 1, 2),
PLL_RATE(336000000, 56, 1, 2),
PLL_RATE(360000000, 60, 1, 2),
PLL_RATE(384000000, 64, 1, 2),
PLL_RATE(408000000, 68, 1, 2),
PLL_RATE(432000000, 72, 1, 2),
PLL_RATE(456000000, 76, 1, 2),
PLL_RATE(480000000, 80, 1, 2),
PLL_RATE(504000000, 84, 1, 2),
PLL_RATE(528000000, 88, 1, 2),
PLL_RATE(552000000, 92, 1, 2),
PLL_RATE(576000000, 96, 1, 2),
PLL_RATE(600000000, 50, 1, 1),
PLL_RATE(624000000, 52, 1, 1),
PLL_RATE(648000000, 54, 1, 1),
PLL_RATE(672000000, 56, 1, 1),
PLL_RATE(696000000, 58, 1, 1),
PLL_RATE(720000000, 60, 1, 1),
PLL_RATE(744000000, 62, 1, 1),
PLL_RATE(768000000, 64, 1, 1),
PLL_RATE(792000000, 66, 1, 1),
PLL_RATE(816000000, 68, 1, 1),
PLL_RATE(840000000, 70, 1, 1),
PLL_RATE(864000000, 72, 1, 1),
PLL_RATE(888000000, 74, 1, 1),
PLL_RATE(912000000, 76, 1, 1),
PLL_RATE(936000000, 78, 1, 1),
PLL_RATE(960000000, 80, 1, 1),
PLL_RATE(984000000, 82, 1, 1),
PLL_RATE(1008000000, 84, 1, 1),
PLL_RATE(1032000000, 86, 1, 1),
PLL_RATE(1056000000, 88, 1, 1),
PLL_RATE(1080000000, 90, 1, 1),
PLL_RATE(1104000000, 92, 1, 1),
PLL_RATE(1128000000, 94, 1, 1),
PLL_RATE(1152000000, 96, 1, 1),
PLL_RATE(1176000000, 98, 1, 1),
PLL_RATE(1200000000, 50, 1, 0),
PLL_RATE(1224000000, 51, 1, 0),
PLL_RATE(1248000000, 52, 1, 0),
PLL_RATE(1272000000, 53, 1, 0),
PLL_RATE(1296000000, 54, 1, 0),
PLL_RATE(1320000000, 55, 1, 0),
PLL_RATE(1344000000, 56, 1, 0),
PLL_RATE(1368000000, 57, 1, 0),
PLL_RATE(1392000000, 58, 1, 0),
PLL_RATE(1416000000, 59, 1, 0),
PLL_RATE(1440000000, 60, 1, 0),
PLL_RATE(1464000000, 61, 1, 0),
PLL_RATE(1488000000, 62, 1, 0),
PLL_RATE(1512000000, 63, 1, 0),
PLL_RATE(1536000000, 64, 1, 0),
{ /* sentinel */ },
};
static const struct clk_div_table cpu_div_table[] = {
{ .val = 1, .div = 1 },
{ .val = 2, .div = 2 },
{ .val = 3, .div = 3 },
{ .val = 2, .div = 4 },
{ .val = 3, .div = 6 },
{ .val = 4, .div = 8 },
{ .val = 5, .div = 10 },
{ .val = 6, .div = 12 },
{ .val = 7, .div = 14 },
{ .val = 8, .div = 16 },
{ /* sentinel */ },
};
static struct clk_fixed_rate meson8b_xtal = {
.fixed_rate = 24000000,
.hw.init = &(struct clk_init_data){
.name = "xtal",
.num_parents = 0,
.ops = &clk_fixed_rate_ops,
},
};
static struct meson_clk_pll meson8b_fixed_pll = {
.m = {
.reg_off = HHI_MPLL_CNTL,
.shift = 0,
.width = 9,
},
.n = {
.reg_off = HHI_MPLL_CNTL,
.shift = 9,
.width = 5,
},
.od = {
.reg_off = HHI_MPLL_CNTL,
.shift = 16,
.width = 2,
},
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "fixed_pll",
.ops = &meson_clk_pll_ro_ops,
.parent_names = (const char *[]){ "xtal" },
.num_parents = 1,
.flags = CLK_GET_RATE_NOCACHE,
},
};
static struct meson_clk_pll meson8b_vid_pll = {
.m = {
.reg_off = HHI_VID_PLL_CNTL,
.shift = 0,
.width = 9,
},
.n = {
.reg_off = HHI_VID_PLL_CNTL,
.shift = 9,
.width = 5,
},
.od = {
.reg_off = HHI_VID_PLL_CNTL,
.shift = 16,
.width = 2,
},
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "vid_pll",
.ops = &meson_clk_pll_ro_ops,
.parent_names = (const char *[]){ "xtal" },
.num_parents = 1,
.flags = CLK_GET_RATE_NOCACHE,
},
};
static struct meson_clk_pll meson8b_sys_pll = {
.m = {
.reg_off = HHI_SYS_PLL_CNTL,
.shift = 0,
.width = 9,
},
.n = {
.reg_off = HHI_SYS_PLL_CNTL,
.shift = 9,
.width = 5,
},
.od = {
.reg_off = HHI_SYS_PLL_CNTL,
.shift = 16,
.width = 2,
},
.rate_table = sys_pll_rate_table,
.rate_count = ARRAY_SIZE(sys_pll_rate_table),
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "sys_pll",
.ops = &meson_clk_pll_ops,
.parent_names = (const char *[]){ "xtal" },
.num_parents = 1,
.flags = CLK_GET_RATE_NOCACHE,
},
};
static struct clk_fixed_factor meson8b_fclk_div2 = {
.mult = 1,
.div = 2,
.hw.init = &(struct clk_init_data){
.name = "fclk_div2",
.ops = &clk_fixed_factor_ops,
.parent_names = (const char *[]){ "fixed_pll" },
.num_parents = 1,
},
};
static struct clk_fixed_factor meson8b_fclk_div3 = {
.mult = 1,
.div = 3,
.hw.init = &(struct clk_init_data){
.name = "fclk_div3",
.ops = &clk_fixed_factor_ops,
.parent_names = (const char *[]){ "fixed_pll" },
.num_parents = 1,
},
};
static struct clk_fixed_factor meson8b_fclk_div4 = {
.mult = 1,
.div = 4,
.hw.init = &(struct clk_init_data){
.name = "fclk_div4",
.ops = &clk_fixed_factor_ops,
.parent_names = (const char *[]){ "fixed_pll" },
.num_parents = 1,
},
};
static struct clk_fixed_factor meson8b_fclk_div5 = {
.mult = 1,
.div = 5,
.hw.init = &(struct clk_init_data){
.name = "fclk_div5",
.ops = &clk_fixed_factor_ops,
.parent_names = (const char *[]){ "fixed_pll" },
.num_parents = 1,
},
};
static struct clk_fixed_factor meson8b_fclk_div7 = {
.mult = 1,
.div = 7,
.hw.init = &(struct clk_init_data){
.name = "fclk_div7",
.ops = &clk_fixed_factor_ops,
.parent_names = (const char *[]){ "fixed_pll" },
.num_parents = 1,
},
};
/*
* FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL
* post-dividers and should be modeled with their respective PLLs via the
* forthcoming coordinated clock rates feature
*/
static struct meson_clk_cpu meson8b_cpu_clk = {
.reg_off = HHI_SYS_CPU_CLK_CNTL1,
.div_table = cpu_div_table,
.clk_nb.notifier_call = meson_clk_cpu_notifier_cb,
.hw.init = &(struct clk_init_data){
.name = "cpu_clk",
.ops = &meson_clk_cpu_ops,
.parent_names = (const char *[]){ "sys_pll" },
.num_parents = 1,
},
};
static u32 mux_table_clk81[] = { 6, 5, 7 };
struct clk_mux meson8b_mpeg_clk_sel = {
.reg = (void *)HHI_MPEG_CLK_CNTL,
.mask = 0x7,
.shift = 12,
.flags = CLK_MUX_READ_ONLY,
.table = mux_table_clk81,
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpeg_clk_sel",
.ops = &clk_mux_ro_ops,
/*
* FIXME bits 14:12 selects from 8 possible parents:
* xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
* fclk_div4, fclk_div3, fclk_div5
*/
.parent_names = (const char *[]){ "fclk_div3", "fclk_div4",
"fclk_div5" },
.num_parents = 3,
.flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED),
},
};
struct clk_divider meson8b_mpeg_clk_div = {
.reg = (void *)HHI_MPEG_CLK_CNTL,
.shift = 0,
.width = 7,
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "mpeg_clk_div",
.ops = &clk_divider_ops,
.parent_names = (const char *[]){ "mpeg_clk_sel" },
.num_parents = 1,
.flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
},
};
struct clk_gate meson8b_clk81 = {
.reg = (void *)HHI_MPEG_CLK_CNTL,
.bit_idx = 7,
.lock = &clk_lock,
.hw.init = &(struct clk_init_data){
.name = "clk81",
.ops = &clk_gate_ops,
.parent_names = (const char *[]){ "mpeg_clk_div" },
.num_parents = 1,
.flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),
},
};
/* Everything Else (EE) domain gates */
static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0);
static MESON_GATE(meson8b_dos, HHI_GCLK_MPEG0, 1);
static MESON_GATE(meson8b_isa, HHI_GCLK_MPEG0, 5);
static MESON_GATE(meson8b_pl301, HHI_GCLK_MPEG0, 6);
static MESON_GATE(meson8b_periphs, HHI_GCLK_MPEG0, 7);
static MESON_GATE(meson8b_spicc, HHI_GCLK_MPEG0, 8);
static MESON_GATE(meson8b_i2c, HHI_GCLK_MPEG0, 9);
static MESON_GATE(meson8b_sar_adc, HHI_GCLK_MPEG0, 10);
static MESON_GATE(meson8b_smart_card, HHI_GCLK_MPEG0, 11);
static MESON_GATE(meson8b_rng0, HHI_GCLK_MPEG0, 12);
static MESON_GATE(meson8b_uart0, HHI_GCLK_MPEG0, 13);
static MESON_GATE(meson8b_sdhc, HHI_GCLK_MPEG0, 14);
static MESON_GATE(meson8b_stream, HHI_GCLK_MPEG0, 15);
static MESON_GATE(meson8b_async_fifo, HHI_GCLK_MPEG0, 16);
static MESON_GATE(meson8b_sdio, HHI_GCLK_MPEG0, 17);
static MESON_GATE(meson8b_abuf, HHI_GCLK_MPEG0, 18);
static MESON_GATE(meson8b_hiu_iface, HHI_GCLK_MPEG0, 19);
static MESON_GATE(meson8b_assist_misc, HHI_GCLK_MPEG0, 23);
static MESON_GATE(meson8b_spi, HHI_GCLK_MPEG0, 30);
static MESON_GATE(meson8b_i2s_spdif, HHI_GCLK_MPEG1, 2);
static MESON_GATE(meson8b_eth, HHI_GCLK_MPEG1, 3);
static MESON_GATE(meson8b_demux, HHI_GCLK_MPEG1, 4);
static MESON_GATE(meson8b_aiu_glue, HHI_GCLK_MPEG1, 6);
static MESON_GATE(meson8b_iec958, HHI_GCLK_MPEG1, 7);
static MESON_GATE(meson8b_i2s_out, HHI_GCLK_MPEG1, 8);
static MESON_GATE(meson8b_amclk, HHI_GCLK_MPEG1, 9);
static MESON_GATE(meson8b_aififo2, HHI_GCLK_MPEG1, 10);
static MESON_GATE(meson8b_mixer, HHI_GCLK_MPEG1, 11);
static MESON_GATE(meson8b_mixer_iface, HHI_GCLK_MPEG1, 12);
static MESON_GATE(meson8b_adc, HHI_GCLK_MPEG1, 13);
static MESON_GATE(meson8b_blkmv, HHI_GCLK_MPEG1, 14);
static MESON_GATE(meson8b_aiu, HHI_GCLK_MPEG1, 15);
static MESON_GATE(meson8b_uart1, HHI_GCLK_MPEG1, 16);
static MESON_GATE(meson8b_g2d, HHI_GCLK_MPEG1, 20);
static MESON_GATE(meson8b_usb0, HHI_GCLK_MPEG1, 21);
static MESON_GATE(meson8b_usb1, HHI_GCLK_MPEG1, 22);
static MESON_GATE(meson8b_reset, HHI_GCLK_MPEG1, 23);
static MESON_GATE(meson8b_nand, HHI_GCLK_MPEG1, 24);
static MESON_GATE(meson8b_dos_parser, HHI_GCLK_MPEG1, 25);
static MESON_GATE(meson8b_usb, HHI_GCLK_MPEG1, 26);
static MESON_GATE(meson8b_vdin1, HHI_GCLK_MPEG1, 28);
static MESON_GATE(meson8b_ahb_arb0, HHI_GCLK_MPEG1, 29);
static MESON_GATE(meson8b_efuse, HHI_GCLK_MPEG1, 30);
static MESON_GATE(meson8b_boot_rom, HHI_GCLK_MPEG1, 31);
static MESON_GATE(meson8b_ahb_data_bus, HHI_GCLK_MPEG2, 1);
static MESON_GATE(meson8b_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2);
static MESON_GATE(meson8b_hdmi_intr_sync, HHI_GCLK_MPEG2, 3);
static MESON_GATE(meson8b_hdmi_pclk, HHI_GCLK_MPEG2, 4);
static MESON_GATE(meson8b_usb1_ddr_bridge, HHI_GCLK_MPEG2, 8);
static MESON_GATE(meson8b_usb0_ddr_bridge, HHI_GCLK_MPEG2, 9);
static MESON_GATE(meson8b_mmc_pclk, HHI_GCLK_MPEG2, 11);
static MESON_GATE(meson8b_dvin, HHI_GCLK_MPEG2, 12);
static MESON_GATE(meson8b_uart2, HHI_GCLK_MPEG2, 15);
static MESON_GATE(meson8b_sana, HHI_GCLK_MPEG2, 22);
static MESON_GATE(meson8b_vpu_intr, HHI_GCLK_MPEG2, 25);
static MESON_GATE(meson8b_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26);
static MESON_GATE(meson8b_clk81_a9, HHI_GCLK_MPEG2, 29);
static MESON_GATE(meson8b_vclk2_venci0, HHI_GCLK_OTHER, 1);
static MESON_GATE(meson8b_vclk2_venci1, HHI_GCLK_OTHER, 2);
static MESON_GATE(meson8b_vclk2_vencp0, HHI_GCLK_OTHER, 3);
static MESON_GATE(meson8b_vclk2_vencp1, HHI_GCLK_OTHER, 4);
static MESON_GATE(meson8b_gclk_venci_int, HHI_GCLK_OTHER, 8);
static MESON_GATE(meson8b_gclk_vencp_int, HHI_GCLK_OTHER, 9);
static MESON_GATE(meson8b_dac_clk, HHI_GCLK_OTHER, 10);
static MESON_GATE(meson8b_aoclk_gate, HHI_GCLK_OTHER, 14);
static MESON_GATE(meson8b_iec958_gate, HHI_GCLK_OTHER, 16);
static MESON_GATE(meson8b_enc480p, HHI_GCLK_OTHER, 20);
static MESON_GATE(meson8b_rng1, HHI_GCLK_OTHER, 21);
static MESON_GATE(meson8b_gclk_vencl_int, HHI_GCLK_OTHER, 22);
static MESON_GATE(meson8b_vclk2_venclmcc, HHI_GCLK_OTHER, 24);
static MESON_GATE(meson8b_vclk2_vencl, HHI_GCLK_OTHER, 25);
static MESON_GATE(meson8b_vclk2_other, HHI_GCLK_OTHER, 26);
static MESON_GATE(meson8b_edp, HHI_GCLK_OTHER, 31);
/* Always On (AO) domain gates */
static MESON_GATE(meson8b_ao_media_cpu, HHI_GCLK_AO, 0);
static MESON_GATE(meson8b_ao_ahb_sram, HHI_GCLK_AO, 1);
static MESON_GATE(meson8b_ao_ahb_bus, HHI_GCLK_AO, 2);
static MESON_GATE(meson8b_ao_iface, HHI_GCLK_AO, 3);
static struct clk_hw *meson8b_clk_hws[] = {
[CLKID_XTAL] = &meson8b_xtal.hw,
[CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
[CLKID_PLL_VID] = &meson8b_vid_pll.hw,
[CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
[CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw,
[CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw,
[CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw,
[CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
[CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
[CLKID_CPUCLK] = &meson8b_cpu_clk.hw,
[CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw,
[CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw,
[CLKID_CLK81] = &meson8b_clk81.hw,
[CLKID_DDR] = &meson8b_ddr.hw,
[CLKID_DOS] = &meson8b_dos.hw,
[CLKID_ISA] = &meson8b_isa.hw,
[CLKID_PL301] = &meson8b_pl301.hw,
[CLKID_PERIPHS] = &meson8b_periphs.hw,
[CLKID_SPICC] = &meson8b_spicc.hw,
[CLKID_I2C] = &meson8b_i2c.hw,
[CLKID_SAR_ADC] = &meson8b_sar_adc.hw,
[CLKID_SMART_CARD] = &meson8b_smart_card.hw,
[CLKID_RNG0] = &meson8b_rng0.hw,
[CLKID_UART0] = &meson8b_uart0.hw,
[CLKID_SDHC] = &meson8b_sdhc.hw,
[CLKID_STREAM] = &meson8b_stream.hw,
[CLKID_ASYNC_FIFO] = &meson8b_async_fifo.hw,
[CLKID_SDIO] = &meson8b_sdio.hw,
[CLKID_ABUF] = &meson8b_abuf.hw,
[CLKID_HIU_IFACE] = &meson8b_hiu_iface.hw,
[CLKID_ASSIST_MISC] = &meson8b_assist_misc.hw,
[CLKID_SPI] = &meson8b_spi.hw,
[CLKID_I2S_SPDIF] = &meson8b_i2s_spdif.hw,
[CLKID_ETH] = &meson8b_eth.hw,
[CLKID_DEMUX] = &meson8b_demux.hw,
[CLKID_AIU_GLUE] = &meson8b_aiu_glue.hw,
[CLKID_IEC958] = &meson8b_iec958.hw,
[CLKID_I2S_OUT] = &meson8b_i2s_out.hw,
[CLKID_AMCLK] = &meson8b_amclk.hw,
[CLKID_AIFIFO2] = &meson8b_aififo2.hw,
[CLKID_MIXER] = &meson8b_mixer.hw,
[CLKID_MIXER_IFACE] = &meson8b_mixer_iface.hw,
[CLKID_ADC] = &meson8b_adc.hw,
[CLKID_BLKMV] = &meson8b_blkmv.hw,
[CLKID_AIU] = &meson8b_aiu.hw,
[CLKID_UART1] = &meson8b_uart1.hw,
[CLKID_G2D] = &meson8b_g2d.hw,
[CLKID_USB0] = &meson8b_usb0.hw,
[CLKID_USB1] = &meson8b_usb1.hw,
[CLKID_RESET] = &meson8b_reset.hw,
[CLKID_NAND] = &meson8b_nand.hw,
[CLKID_DOS_PARSER] = &meson8b_dos_parser.hw,
[CLKID_USB] = &meson8b_usb.hw,
[CLKID_VDIN1] = &meson8b_vdin1.hw,
[CLKID_AHB_ARB0] = &meson8b_ahb_arb0.hw,
[CLKID_EFUSE] = &meson8b_efuse.hw,
[CLKID_BOOT_ROM] = &meson8b_boot_rom.hw,
[CLKID_AHB_DATA_BUS] = &meson8b_ahb_data_bus.hw,
[CLKID_AHB_CTRL_BUS] = &meson8b_ahb_ctrl_bus.hw,
[CLKID_HDMI_INTR_SYNC] = &meson8b_hdmi_intr_sync.hw,
[CLKID_HDMI_PCLK] = &meson8b_hdmi_pclk.hw,
[CLKID_USB1_DDR_BRIDGE] = &meson8b_usb1_ddr_bridge.hw,
[CLKID_USB0_DDR_BRIDGE] = &meson8b_usb0_ddr_bridge.hw,
[CLKID_MMC_PCLK] = &meson8b_mmc_pclk.hw,
[CLKID_DVIN] = &meson8b_dvin.hw,
[CLKID_UART2] = &meson8b_uart2.hw,
[CLKID_SANA] = &meson8b_sana.hw,
[CLKID_VPU_INTR] = &meson8b_vpu_intr.hw,
[CLKID_SEC_AHB_AHB3_BRIDGE] = &meson8b_sec_ahb_ahb3_bridge.hw,
[CLKID_CLK81_A9] = &meson8b_clk81_a9.hw,
[CLKID_VCLK2_VENCI0] = &meson8b_vclk2_venci0.hw,
[CLKID_VCLK2_VENCI1] = &meson8b_vclk2_venci1.hw,
[CLKID_VCLK2_VENCP0] = &meson8b_vclk2_vencp0.hw,
[CLKID_VCLK2_VENCP1] = &meson8b_vclk2_vencp1.hw,
[CLKID_GCLK_VENCI_INT] = &meson8b_gclk_venci_int.hw,
[CLKID_GCLK_VENCP_INT] = &meson8b_gclk_vencp_int.hw,
[CLKID_DAC_CLK] = &meson8b_dac_clk.hw,
[CLKID_AOCLK_GATE] = &meson8b_aoclk_gate.hw,
[CLKID_IEC958_GATE] = &meson8b_iec958_gate.hw,
[CLKID_ENC480P] = &meson8b_enc480p.hw,
[CLKID_RNG1] = &meson8b_rng1.hw,
[CLKID_GCLK_VENCL_INT] = &meson8b_gclk_vencl_int.hw,
[CLKID_VCLK2_VENCLMCC] = &meson8b_vclk2_venclmcc.hw,
[CLKID_VCLK2_VENCL] = &meson8b_vclk2_vencl.hw,
[CLKID_VCLK2_OTHER] = &meson8b_vclk2_other.hw,
[CLKID_EDP] = &meson8b_edp.hw,
[CLKID_AO_MEDIA_CPU] = &meson8b_ao_media_cpu.hw,
[CLKID_AO_AHB_SRAM] = &meson8b_ao_ahb_sram.hw,
[CLKID_AO_AHB_BUS] = &meson8b_ao_ahb_bus.hw,
[CLKID_AO_IFACE] = &meson8b_ao_iface.hw,
};
static struct meson_clk_pll *const meson8b_clk_plls[] = {
&meson8b_fixed_pll,
&meson8b_vid_pll,
&meson8b_sys_pll,
};
static struct clk_gate *meson8b_clk_gates[] = {
&meson8b_clk81,
&meson8b_ddr,
&meson8b_dos,
&meson8b_isa,
&meson8b_pl301,
&meson8b_periphs,
&meson8b_spicc,
&meson8b_i2c,
&meson8b_sar_adc,
&meson8b_smart_card,
&meson8b_rng0,
&meson8b_uart0,
&meson8b_sdhc,
&meson8b_stream,
&meson8b_async_fifo,
&meson8b_sdio,
&meson8b_abuf,
&meson8b_hiu_iface,
&meson8b_assist_misc,
&meson8b_spi,
&meson8b_i2s_spdif,
&meson8b_eth,
&meson8b_demux,
&meson8b_aiu_glue,
&meson8b_iec958,
&meson8b_i2s_out,
&meson8b_amclk,
&meson8b_aififo2,
&meson8b_mixer,
&meson8b_mixer_iface,
&meson8b_adc,
&meson8b_blkmv,
&meson8b_aiu,
&meson8b_uart1,
&meson8b_g2d,
&meson8b_usb0,
&meson8b_usb1,
&meson8b_reset,
&meson8b_nand,
&meson8b_dos_parser,
&meson8b_usb,
&meson8b_vdin1,
&meson8b_ahb_arb0,
&meson8b_efuse,
&meson8b_boot_rom,
&meson8b_ahb_data_bus,
&meson8b_ahb_ctrl_bus,
&meson8b_hdmi_intr_sync,
&meson8b_hdmi_pclk,
&meson8b_usb1_ddr_bridge,
&meson8b_usb0_ddr_bridge,
&meson8b_mmc_pclk,
&meson8b_dvin,
&meson8b_uart2,
&meson8b_sana,
&meson8b_vpu_intr,
&meson8b_sec_ahb_ahb3_bridge,
&meson8b_clk81_a9,
&meson8b_vclk2_venci0,
&meson8b_vclk2_venci1,
&meson8b_vclk2_vencp0,
&meson8b_vclk2_vencp1,
&meson8b_gclk_venci_int,
&meson8b_gclk_vencp_int,
&meson8b_dac_clk,
&meson8b_aoclk_gate,
&meson8b_iec958_gate,
&meson8b_enc480p,
&meson8b_rng1,
&meson8b_gclk_vencl_int,
&meson8b_vclk2_venclmcc,
&meson8b_vclk2_vencl,
&meson8b_vclk2_other,
&meson8b_edp,
&meson8b_ao_media_cpu,
&meson8b_ao_ahb_sram,
&meson8b_ao_ahb_bus,
&meson8b_ao_iface,
};
static void __init meson8b_clkc_init(struct device_node *np)
{
void __iomem *clk_base;
int ret, clkid, i;
struct clk_hw *parent_hw;
struct clk *parent_clk;
//struct device *dev = &pdev->dev;
pr_info("%s\n", __func__);
/* Generic clocks and PLLs */
clk_base = of_iomap(np, 1);
if (!clk_base) {
pr_err("%s: Unable to map clk base\n", __func__);
/* return -ENXIO; */
return;
}
/* Populate base address for PLLs */
for (i = 0; i < ARRAY_SIZE(meson8b_clk_plls); i++)
meson8b_clk_plls[i]->base = clk_base;
/* Populate the base address for CPU clk */
meson8b_cpu_clk.base = clk_base;
/* Populate the base address for the MPEG clks */
meson8b_mpeg_clk_sel.reg = clk_base + (u32)meson8b_mpeg_clk_sel.reg;
meson8b_mpeg_clk_div.reg = clk_base + (u32)meson8b_mpeg_clk_div.reg;
meson8b_clk81.reg = clk_base + (u32)meson8b_clk81.reg;
/* Populate base address for gates */
for (i = 0; i < ARRAY_SIZE(meson8b_clk_gates); i++)
meson8b_clk_gates[i]->reg = clk_base +
(u32)meson8b_clk_gates[i]->reg;
clks = kzalloc(NR_CLKS*sizeof(struct clk *), GFP_KERNEL);
if (!clks) {
/* pr_err("%s: alloc clks fail!", __func__); */
/* return -ENOMEM; */
return;
}
clk_data.clks = clks;
clk_data.clk_num = NR_CLKS;
/*
* register all clks
* CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
*/
for (clkid = CLKID_XTAL; clkid < NR_CLKS; clkid++) {
/* array might be sparse */
if (!meson8b_clk_hws[clkid])
continue;
/* FIXME convert to devm_clk_register */
clks[clkid] = clk_register(NULL, meson8b_clk_hws[clkid]);
WARN_ON(IS_ERR(clks[clkid]));
}
/*
* Register CPU clk notifier
*
* FIXME this is wrong for a lot of reasons. First, the muxes should be
* struct clk_hw objects. Second, we shouldn't program the muxes in
* notifier handlers. The tricky programming sequence will be handled
* by the forthcoming coordinated clock rates mechanism once that
* feature is released.
*
* Furthermore, looking up the parent this way is terrible. At some
* point we will stop allocating a default struct clk when registering
* a new clk_hw, and this hack will no longer work. Releasing the ccr
* feature before that time solves the problem :-)
*/
parent_hw = clk_hw_get_parent(&meson8b_cpu_clk.hw);
parent_clk = parent_hw->clk;
ret = clk_notifier_register(parent_clk, &meson8b_cpu_clk.clk_nb);
if (ret) {
pr_err("%s: failed to register clock notifier for cpu_clk\n",
__func__);
goto iounmap;
}
pr_debug("%s: cpu clk register notifier ok!", __func__);
ret = of_clk_add_provider(np, of_clk_src_onecell_get,
&clk_data);
if (ret < 0)
pr_err("%s fail ret: %d\n", __func__, ret);
else
pr_info("%s initialization complete\n", __func__);
return;
iounmap:
iounmap(clk_base);
pr_info("%s: %d: ret: %d\n", __func__, __LINE__, ret);
/* return; */
}
CLK_OF_DECLARE(m8b, "amlogic,meson8b-clkc", meson8b_clkc_init);

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2015 Endless Mobile, Inc.
* Author: Carlo Caione <carlo@endlessm.com>
*
* Copyright (c) 2016 BayLibre, Inc.
* Michael Turquette <mturquette@baylibre.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope 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.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __MESON8B_H
#define __MESON8B_H
/*
* Clock controller register offsets
*
* Register offsets from the HardKernel[0] data sheet are listed in comment
* blocks below. Those offsets must be multiplied by 4 before adding them to
* the base address to get the right value
*
* [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
*/
#define HHI_GCLK_MPEG0 0x140 /* 0x50 offset in data sheet */
#define HHI_GCLK_MPEG1 0x144 /* 0x51 offset in data sheet */
#define HHI_GCLK_MPEG2 0x148 /* 0x52 offset in data sheet */
#define HHI_GCLK_OTHER 0x150 /* 0x54 offset in data sheet */
#define HHI_GCLK_AO 0x154 /* 0x55 offset in data sheet */
#define HHI_SYS_CPU_CLK_CNTL1 0x15c /* 0x57 offset in data sheet */
#define HHI_MPEG_CLK_CNTL 0x174 /* 0x5d offset in data sheet */
#define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */
#define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */
#define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */
/* include the CLKIDs that have been made part of the stable DT binding */
#include <dt-bindings/clock/meson8b-clkc.h>
#endif /* __MESON8B_H */

View File

@@ -2,6 +2,15 @@
* Meson8b clock tree IDs
*/
/*
* CLKID index values
*
* These indices are entirely contrived and do not map onto the hardware.
* Migrate them out of this header and into the DT header file when they need
* to be exposed to client nodes in DT: include/dt-bindings/clock/meson8b-clkc.h
*/
#ifndef __MESON8B_CLKC_H
#define __MESON8B_CLKC_H
@@ -21,5 +30,85 @@
#define CLKID_ZERO 13
#define CLKID_MPEG_SEL 14
#define CLKID_MPEG_DIV 15
#define CLKID_DDR 16
#define CLKID_DOS 17
#define CLKID_ISA 18
#define CLKID_PL301 19
#define CLKID_PERIPHS 20
#define CLKID_SPICC 21
#define CLKID_I2C 22
#define CLKID_SAR_ADC 23
#define CLKID_SMART_CARD 24
#define CLKID_RNG0 25
#define CLKID_UART0 26
#define CLKID_SDHC 27
#define CLKID_STREAM 28
#define CLKID_ASYNC_FIFO 29
#define CLKID_SDIO 30
#define CLKID_ABUF 31
#define CLKID_HIU_IFACE 32
#define CLKID_ASSIST_MISC 33
#define CLKID_SPI 34
#define CLKID_I2S_SPDIF 35
#define CLKID_ETH 36
#define CLKID_DEMUX 37
#define CLKID_AIU_GLUE 38
#define CLKID_IEC958 39
#define CLKID_I2S_OUT 40
#define CLKID_AMCLK 41
#define CLKID_AIFIFO2 42
#define CLKID_MIXER 43
#define CLKID_MIXER_IFACE 44
#define CLKID_ADC 45
#define CLKID_BLKMV 46
#define CLKID_AIU 47
#define CLKID_UART1 48
#define CLKID_G2D 49
#define CLKID_USB0 50
#define CLKID_USB1 51
#define CLKID_RESET 52
#define CLKID_NAND 53
#define CLKID_DOS_PARSER 54
#define CLKID_USB 55
#define CLKID_VDIN1 56
#define CLKID_AHB_ARB0 57
#define CLKID_EFUSE 58
#define CLKID_BOOT_ROM 59
#define CLKID_AHB_DATA_BUS 60
#define CLKID_AHB_CTRL_BUS 61
#define CLKID_HDMI_INTR_SYNC 62
#define CLKID_HDMI_PCLK 63
#define CLKID_USB1_DDR_BRIDGE 64
#define CLKID_USB0_DDR_BRIDGE 65
#define CLKID_MMC_PCLK 66
#define CLKID_DVIN 67
#define CLKID_UART2 68
#define CLKID_SANA 69
#define CLKID_VPU_INTR 70
#define CLKID_SEC_AHB_AHB3_BRIDGE 71
#define CLKID_CLK81_A9 72
#define CLKID_VCLK2_VENCI0 73
#define CLKID_VCLK2_VENCI1 74
#define CLKID_VCLK2_VENCP0 75
#define CLKID_VCLK2_VENCP1 76
#define CLKID_GCLK_VENCI_INT 77
#define CLKID_GCLK_VENCP_INT 78
#define CLKID_DAC_CLK 79
#define CLKID_AOCLK_GATE 80
#define CLKID_IEC958_GATE 81
#define CLKID_ENC480P 82
#define CLKID_RNG1 83
#define CLKID_GCLK_VENCL_INT 84
#define CLKID_VCLK2_VENCLMCC 85
#define CLKID_VCLK2_VENCL 86
#define CLKID_VCLK2_OTHER 87
#define CLKID_EDP 88
#define CLKID_AO_MEDIA_CPU 89
#define CLKID_AO_AHB_SRAM 90
#define CLKID_AO_AHB_BUS 91
#define CLKID_AO_IFACE 92
#define NR_CLKS 93
#endif /* __MESON8B_CLKC_H */