/* * Copyright (c) 2014 MundoReader S.L. * Author: Heiko Stuebner * * based on * * samsung/clk.h * Copyright (c) 2013 Samsung Electronics Co., Ltd. * Copyright (c) 2013 Linaro Ltd. * Author: Thomas Abraham * * 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. */ #ifndef CLK_ROCKCHIP_CLK_H #define CLK_ROCKCHIP_CLK_H #include #include #include #define HIWORD_UPDATE(val, mask, shift) \ ((val) << (shift) | (mask) << ((shift) + 16)) /* register positions shared by RK2928, RK3066 and RK3188 */ #define RK2928_PLL_CON(x) (x * 0x4) #define RK2928_MODE_CON 0x40 #define RK2928_CLKSEL_CON(x) (x * 0x4 + 0x44) #define RK2928_CLKGATE_CON(x) (x * 0x4 + 0xd0) #define RK2928_GLB_SRST_FST 0x100 #define RK2928_GLB_SRST_SND 0x104 #define RK2928_SOFTRST_CON(x) (x * 0x4 + 0x110) #define RK2928_MISC_CON 0x134 #define PNAME(x) static const char *x[] __initconst enum rockchip_clk_branch_type { branch_composite, branch_mux, branch_divider, branch_fraction_divider, branch_gate, }; struct rockchip_clk_branch { unsigned int id; enum rockchip_clk_branch_type branch_type; const char *name; const char **parent_names; u8 num_parents; unsigned long flags; int muxdiv_offset; u8 mux_shift; u8 mux_width; u8 mux_flags; u8 div_shift; u8 div_width; u8 div_flags; struct clk_div_table *div_table; int gate_offset; u8 gate_shift; u8 gate_flags; }; #define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw,\ df, go, gs, gf) \ { \ .id = _id, \ .branch_type = branch_composite, \ .name = cname, \ .parent_names = pnames, \ .num_parents = ARRAY_SIZE(pnames), \ .flags = f, \ .muxdiv_offset = mo, \ .mux_shift = ms, \ .mux_width = mw, \ .mux_flags = mf, \ .div_shift = ds, \ .div_width = dw, \ .div_flags = df, \ .gate_offset = go, \ .gate_shift = gs, \ .gate_flags = gf, \ } #define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df, \ go, gs, gf) \ { \ .id = _id, \ .branch_type = branch_composite, \ .name = cname, \ .parent_names = (const char *[]){ pname }, \ .num_parents = 1, \ .flags = f, \ .muxdiv_offset = mo, \ .div_shift = ds, \ .div_width = dw, \ .div_flags = df, \ .gate_offset = go, \ .gate_shift = gs, \ .gate_flags = gf, \ } #define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw,\ df, dt, go, gs, gf) \ { \ .id = _id, \ .branch_type = branch_composite, \ .name = cname, \ .parent_names = (const char *[]){ pname }, \ .num_parents = 1, \ .flags = f, \ .muxdiv_offset = mo, \ .div_shift = ds, \ .div_width = dw, \ .div_flags = df, \ .div_table = dt, \ .gate_offset = go, \ .gate_shift = gs, \ .gate_flags = gf, \ } #define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf, \ go, gs, gf) \ { \ .id = _id, \ .branch_type = branch_composite, \ .name = cname, \ .parent_names = pnames, \ .num_parents = ARRAY_SIZE(pnames), \ .flags = f, \ .muxdiv_offset = mo, \ .mux_shift = ms, \ .mux_width = mw, \ .mux_flags = mf, \ .gate_offset = go, \ .gate_shift = gs, \ .gate_flags = gf, \ } #define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, \ ds, dw, df) \ { \ .id = _id, \ .branch_type = branch_composite, \ .name = cname, \ .parent_names = pnames, \ .num_parents = ARRAY_SIZE(pnames), \ .flags = f, \ .muxdiv_offset = mo, \ .mux_shift = ms, \ .mux_width = mw, \ .mux_flags = mf, \ .div_shift = ds, \ .div_width = dw, \ .div_flags = df, \ .gate_offset = -1, \ } #define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\ { \ .id = _id, \ .branch_type = branch_fraction_divider, \ .name = cname, \ .parent_names = (const char *[]){ pname }, \ .num_parents = 1, \ .flags = f, \ .muxdiv_offset = mo, \ .div_shift = 16, \ .div_width = 16, \ .div_flags = df, \ .gate_offset = go, \ .gate_shift = gs, \ .gate_flags = gf, \ } #define MUX(_id, cname, pnames, f, o, s, w, mf) \ { \ .id = _id, \ .branch_type = branch_mux, \ .name = cname, \ .parent_names = pnames, \ .num_parents = ARRAY_SIZE(pnames), \ .flags = f, \ .muxdiv_offset = o, \ .mux_shift = s, \ .mux_width = w, \ .mux_flags = mf, \ .gate_offset = -1, \ } #define DIV(_id, cname, pname, f, o, s, w, df) \ { \ .id = _id, \ .branch_type = branch_divider, \ .name = cname, \ .parent_names = (const char *[]){ pname }, \ .num_parents = 1, \ .flags = f, \ .muxdiv_offset = o, \ .div_shift = s, \ .div_width = w, \ .div_flags = df, \ .gate_offset = -1, \ } #define DIVTBL(_id, cname, pname, f, o, s, w, df, dt) \ { \ .id = _id, \ .branch_type = branch_divider, \ .name = cname, \ .parent_names = (const char *[]){ pname }, \ .num_parents = 1, \ .flags = f, \ .muxdiv_offset = o, \ .div_shift = s, \ .div_width = w, \ .div_flags = df, \ .div_table = dt, \ } #define GATE(_id, cname, pname, f, o, b, gf) \ { \ .id = _id, \ .branch_type = branch_gate, \ .name = cname, \ .parent_names = (const char *[]){ pname }, \ .num_parents = 1, \ .flags = f, \ .gate_offset = o, \ .gate_shift = b, \ .gate_flags = gf, \ } void rockchip_clk_init(struct device_node *np, void __iomem *base, unsigned long nr_clks); void rockchip_clk_add_lookup(struct clk *clk, unsigned int id); void rockchip_clk_register_branches(struct rockchip_clk_branch *clk_list, unsigned int nr_clk); #endif