Commit 9bb87c02 authored by Stephen Boyd's avatar Stephen Boyd

Merge tag 'v4.9-rockchip-clk1' of...

Merge tag 'v4.9-rockchip-clk1' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip into clk-next

Pull rockchip clk driver updates from Heiko Stuebner:

The biggest addition is probably the special clock-type for ddr clock
control. While reading that clock is done the normal way from the
registers, setting it always requires some sort of special handling
to let the system survive this addition.

As the commit message explains, there are currently 3 handling-types
known. General SRAM-based code on rk3288 and before (which is waiting
essentially for the PIE support that is currently being worked on),
SCPI-based clk setting on the rk3368 through a coprocessor, which we
might support once the support for legacy scpi-variants has matured
and now on the rk3399 (and probably later) using a dcf controller that
is controlled from the arm-trusted-firmware and gets accessed through
firmware calls from the kernel. This is the variant we currently
support, but the clock type is made to support the other variants in
the future as well.

Apart from that slightly bigger chunk, we have a mix of PLL rates,
clock-ids and flags mainly for the rk3399.

And interestingly an iomap fix for the legacy gate driver, where I
hopefully could deter the submitter from actually using that in any
new works.

* tag 'v4.9-rockchip-clk1' of git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip:
  clk: rockchip: use the dclk_vop_frac clock ids on rk3399
  clk: rockchip: drop CLK_SET_RATE_PARENT from rk3399 fractional dividers
  clk: rockchip: add 2016M to big cpu clk rate table on rk3399
  clk: rockchip: add rk3399 ddr clock support
  clk: rockchip: add dclk_vop_frac ids for rk3399 vop
  clk: rockchip: add new clock-type for the ddrclk
  soc: rockchip: add header for ddr rate SIP interface
  clk: rockchip: add SCLK_DDRC id for rk3399 ddrc
  clk: rockchip: handle of_iomap failures in legacy clock driver
  clk: rockchip: mark rk3399 hdcp_noc and vio_noc as critical
  clk: rockchip: use general clock flag when registering pll
  clk: rockchip: delete the CLK_IGNORE_UNUSED from aclk_pcie on rk3399
  clk: rockchip: add 65MHz and 106.5MHz rates to rk3399 plls used for HDMI
parents fedc81e7 7b0f9e35
...@@ -8,6 +8,7 @@ obj-y += clk-pll.o ...@@ -8,6 +8,7 @@ obj-y += clk-pll.o
obj-y += clk-cpu.o obj-y += clk-cpu.o
obj-y += clk-inverter.o obj-y += clk-inverter.o
obj-y += clk-mmc-phase.o obj-y += clk-mmc-phase.o
obj-y += clk-ddr.o
obj-$(CONFIG_RESET_CONTROLLER) += softrst.o obj-$(CONFIG_RESET_CONTROLLER) += softrst.o
obj-y += clk-rk3036.o obj-y += clk-rk3036.o
......
/*
* Copyright (c) 2016 Rockchip Electronics Co. Ltd.
* Author: Lin Huang <hl@rock-chips.com>
*
* 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/arm-smccc.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <soc/rockchip/rockchip_sip.h>
#include "clk.h"
struct rockchip_ddrclk {
struct clk_hw hw;
void __iomem *reg_base;
int mux_offset;
int mux_shift;
int mux_width;
int div_shift;
int div_width;
int ddr_flag;
spinlock_t *lock;
};
#define to_rockchip_ddrclk_hw(hw) container_of(hw, struct rockchip_ddrclk, hw)
static int rockchip_ddrclk_sip_set_rate(struct clk_hw *hw, unsigned long drate,
unsigned long prate)
{
struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
unsigned long flags;
struct arm_smccc_res res;
spin_lock_irqsave(ddrclk->lock, flags);
arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, drate, 0,
ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE,
0, 0, 0, 0, &res);
spin_unlock_irqrestore(ddrclk->lock, flags);
return res.a0;
}
static unsigned long
rockchip_ddrclk_sip_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct arm_smccc_res res;
arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0,
ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE,
0, 0, 0, 0, &res);
return res.a0;
}
static long rockchip_ddrclk_sip_round_rate(struct clk_hw *hw,
unsigned long rate,
unsigned long *prate)
{
struct arm_smccc_res res;
arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, rate, 0,
ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE,
0, 0, 0, 0, &res);
return res.a0;
}
static u8 rockchip_ddrclk_get_parent(struct clk_hw *hw)
{
struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
int num_parents = clk_hw_get_num_parents(hw);
u32 val;
val = clk_readl(ddrclk->reg_base +
ddrclk->mux_offset) >> ddrclk->mux_shift;
val &= GENMASK(ddrclk->mux_width - 1, 0);
if (val >= num_parents)
return -EINVAL;
return val;
}
static const struct clk_ops rockchip_ddrclk_sip_ops = {
.recalc_rate = rockchip_ddrclk_sip_recalc_rate,
.set_rate = rockchip_ddrclk_sip_set_rate,
.round_rate = rockchip_ddrclk_sip_round_rate,
.get_parent = rockchip_ddrclk_get_parent,
};
struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
const char *const *parent_names,
u8 num_parents, int mux_offset,
int mux_shift, int mux_width,
int div_shift, int div_width,
int ddr_flag, void __iomem *reg_base,
spinlock_t *lock)
{
struct rockchip_ddrclk *ddrclk;
struct clk_init_data init;
struct clk *clk;
ddrclk = kzalloc(sizeof(*ddrclk), GFP_KERNEL);
if (!ddrclk)
return ERR_PTR(-ENOMEM);
init.name = name;
init.parent_names = parent_names;
init.num_parents = num_parents;
init.flags = flags;
init.flags |= CLK_SET_RATE_NO_REPARENT;
switch (ddr_flag) {
case ROCKCHIP_DDRCLK_SIP:
init.ops = &rockchip_ddrclk_sip_ops;
break;
default:
pr_err("%s: unsupported ddrclk type %d\n", __func__, ddr_flag);
kfree(ddrclk);
return ERR_PTR(-EINVAL);
}
ddrclk->reg_base = reg_base;
ddrclk->lock = lock;
ddrclk->hw.init = &init;
ddrclk->mux_offset = mux_offset;
ddrclk->mux_shift = mux_shift;
ddrclk->mux_width = mux_width;
ddrclk->div_shift = div_shift;
ddrclk->div_width = div_width;
ddrclk->ddr_flag = ddr_flag;
clk = clk_register(NULL, &ddrclk->hw);
if (IS_ERR(clk)) {
pr_err("%s: could not register ddrclk %s\n", __func__, name);
kfree(ddrclk);
return NULL;
}
return clk;
}
...@@ -837,7 +837,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, ...@@ -837,7 +837,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
u8 num_parents, int con_offset, int grf_lock_offset, u8 num_parents, int con_offset, int grf_lock_offset,
int lock_shift, int mode_offset, int mode_shift, int lock_shift, int mode_offset, int mode_shift,
struct rockchip_pll_rate_table *rate_table, struct rockchip_pll_rate_table *rate_table,
u8 clk_pll_flags) unsigned long flags, u8 clk_pll_flags)
{ {
const char *pll_parents[3]; const char *pll_parents[3];
struct clk_init_data init; struct clk_init_data init;
...@@ -892,7 +892,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, ...@@ -892,7 +892,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
init.name = pll_name; init.name = pll_name;
/* keep all plls untouched for now */ /* keep all plls untouched for now */
init.flags = CLK_IGNORE_UNUSED; init.flags = flags | CLK_IGNORE_UNUSED;
init.parent_names = &parent_names[0]; init.parent_names = &parent_names[0];
init.num_parents = 1; init.num_parents = 1;
......
...@@ -100,8 +100,10 @@ static struct rockchip_pll_rate_table rk3399_pll_rates[] = { ...@@ -100,8 +100,10 @@ static struct rockchip_pll_rate_table rk3399_pll_rates[] = {
RK3036_PLL_RATE( 297000000, 1, 99, 4, 2, 1, 0), RK3036_PLL_RATE( 297000000, 1, 99, 4, 2, 1, 0),
RK3036_PLL_RATE( 216000000, 1, 72, 4, 2, 1, 0), RK3036_PLL_RATE( 216000000, 1, 72, 4, 2, 1, 0),
RK3036_PLL_RATE( 148500000, 1, 99, 4, 4, 1, 0), RK3036_PLL_RATE( 148500000, 1, 99, 4, 4, 1, 0),
RK3036_PLL_RATE( 106500000, 1, 71, 4, 4, 1, 0),
RK3036_PLL_RATE( 96000000, 1, 64, 4, 4, 1, 0), RK3036_PLL_RATE( 96000000, 1, 64, 4, 4, 1, 0),
RK3036_PLL_RATE( 74250000, 2, 99, 4, 4, 1, 0), RK3036_PLL_RATE( 74250000, 2, 99, 4, 4, 1, 0),
RK3036_PLL_RATE( 65000000, 1, 65, 6, 4, 1, 0),
RK3036_PLL_RATE( 54000000, 1, 54, 6, 4, 1, 0), RK3036_PLL_RATE( 54000000, 1, 54, 6, 4, 1, 0),
RK3036_PLL_RATE( 27000000, 1, 27, 6, 4, 1, 0), RK3036_PLL_RATE( 27000000, 1, 27, 6, 4, 1, 0),
{ /* sentinel */ }, { /* sentinel */ },
...@@ -118,6 +120,10 @@ PNAME(mux_armclkb_p) = { "clk_core_b_lpll_src", ...@@ -118,6 +120,10 @@ PNAME(mux_armclkb_p) = { "clk_core_b_lpll_src",
"clk_core_b_bpll_src", "clk_core_b_bpll_src",
"clk_core_b_dpll_src", "clk_core_b_dpll_src",
"clk_core_b_gpll_src" }; "clk_core_b_gpll_src" };
PNAME(mux_ddrclk_p) = { "clk_ddrc_lpll_src",
"clk_ddrc_bpll_src",
"clk_ddrc_dpll_src",
"clk_ddrc_gpll_src" };
PNAME(mux_aclk_cci_p) = { "cpll_aclk_cci_src", PNAME(mux_aclk_cci_p) = { "cpll_aclk_cci_src",
"gpll_aclk_cci_src", "gpll_aclk_cci_src",
"npll_aclk_cci_src", "npll_aclk_cci_src",
...@@ -373,6 +379,7 @@ static struct rockchip_cpuclk_rate_table rk3399_cpuclkb_rates[] __initdata = { ...@@ -373,6 +379,7 @@ static struct rockchip_cpuclk_rate_table rk3399_cpuclkb_rates[] __initdata = {
RK3399_CPUCLKB_RATE(2184000000, 1, 11, 11), RK3399_CPUCLKB_RATE(2184000000, 1, 11, 11),
RK3399_CPUCLKB_RATE(2088000000, 1, 10, 10), RK3399_CPUCLKB_RATE(2088000000, 1, 10, 10),
RK3399_CPUCLKB_RATE(2040000000, 1, 10, 10), RK3399_CPUCLKB_RATE(2040000000, 1, 10, 10),
RK3399_CPUCLKB_RATE(2016000000, 1, 9, 9),
RK3399_CPUCLKB_RATE(1992000000, 1, 9, 9), RK3399_CPUCLKB_RATE(1992000000, 1, 9, 9),
RK3399_CPUCLKB_RATE(1896000000, 1, 9, 9), RK3399_CPUCLKB_RATE(1896000000, 1, 9, 9),
RK3399_CPUCLKB_RATE(1800000000, 1, 8, 8), RK3399_CPUCLKB_RATE(1800000000, 1, 8, 8),
...@@ -578,7 +585,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { ...@@ -578,7 +585,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
COMPOSITE(0, "clk_spdif_div", mux_pll_src_cpll_gpll_p, 0, COMPOSITE(0, "clk_spdif_div", mux_pll_src_cpll_gpll_p, 0,
RK3399_CLKSEL_CON(32), 7, 1, MFLAGS, 0, 7, DFLAGS, RK3399_CLKSEL_CON(32), 7, 1, MFLAGS, 0, 7, DFLAGS,
RK3399_CLKGATE_CON(8), 13, GFLAGS), RK3399_CLKGATE_CON(8), 13, GFLAGS),
COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div", CLK_SET_RATE_PARENT, COMPOSITE_FRACMUX(0, "clk_spdif_frac", "clk_spdif_div", 0,
RK3399_CLKSEL_CON(99), 0, RK3399_CLKSEL_CON(99), 0,
RK3399_CLKGATE_CON(8), 14, GFLAGS, RK3399_CLKGATE_CON(8), 14, GFLAGS,
&rk3399_spdif_fracmux), &rk3399_spdif_fracmux),
...@@ -592,7 +599,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { ...@@ -592,7 +599,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
COMPOSITE(0, "clk_i2s0_div", mux_pll_src_cpll_gpll_p, 0, COMPOSITE(0, "clk_i2s0_div", mux_pll_src_cpll_gpll_p, 0,
RK3399_CLKSEL_CON(28), 7, 1, MFLAGS, 0, 7, DFLAGS, RK3399_CLKSEL_CON(28), 7, 1, MFLAGS, 0, 7, DFLAGS,
RK3399_CLKGATE_CON(8), 3, GFLAGS), RK3399_CLKGATE_CON(8), 3, GFLAGS),
COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", CLK_SET_RATE_PARENT, COMPOSITE_FRACMUX(0, "clk_i2s0_frac", "clk_i2s0_div", 0,
RK3399_CLKSEL_CON(96), 0, RK3399_CLKSEL_CON(96), 0,
RK3399_CLKGATE_CON(8), 4, GFLAGS, RK3399_CLKGATE_CON(8), 4, GFLAGS,
&rk3399_i2s0_fracmux), &rk3399_i2s0_fracmux),
...@@ -602,7 +609,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { ...@@ -602,7 +609,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
COMPOSITE(0, "clk_i2s1_div", mux_pll_src_cpll_gpll_p, 0, COMPOSITE(0, "clk_i2s1_div", mux_pll_src_cpll_gpll_p, 0,
RK3399_CLKSEL_CON(29), 7, 1, MFLAGS, 0, 7, DFLAGS, RK3399_CLKSEL_CON(29), 7, 1, MFLAGS, 0, 7, DFLAGS,
RK3399_CLKGATE_CON(8), 6, GFLAGS), RK3399_CLKGATE_CON(8), 6, GFLAGS),
COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", CLK_SET_RATE_PARENT, COMPOSITE_FRACMUX(0, "clk_i2s1_frac", "clk_i2s1_div", 0,
RK3399_CLKSEL_CON(97), 0, RK3399_CLKSEL_CON(97), 0,
RK3399_CLKGATE_CON(8), 7, GFLAGS, RK3399_CLKGATE_CON(8), 7, GFLAGS,
&rk3399_i2s1_fracmux), &rk3399_i2s1_fracmux),
...@@ -612,7 +619,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { ...@@ -612,7 +619,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
COMPOSITE(0, "clk_i2s2_div", mux_pll_src_cpll_gpll_p, 0, COMPOSITE(0, "clk_i2s2_div", mux_pll_src_cpll_gpll_p, 0,
RK3399_CLKSEL_CON(30), 7, 1, MFLAGS, 0, 7, DFLAGS, RK3399_CLKSEL_CON(30), 7, 1, MFLAGS, 0, 7, DFLAGS,
RK3399_CLKGATE_CON(8), 9, GFLAGS), RK3399_CLKGATE_CON(8), 9, GFLAGS),
COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", CLK_SET_RATE_PARENT, COMPOSITE_FRACMUX(0, "clk_i2s2_frac", "clk_i2s2_div", 0,
RK3399_CLKSEL_CON(98), 0, RK3399_CLKSEL_CON(98), 0,
RK3399_CLKGATE_CON(8), 10, GFLAGS, RK3399_CLKGATE_CON(8), 10, GFLAGS,
&rk3399_i2s2_fracmux), &rk3399_i2s2_fracmux),
...@@ -631,7 +638,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { ...@@ -631,7 +638,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
COMPOSITE_NOMUX(0, "clk_uart0_div", "clk_uart0_src", 0, COMPOSITE_NOMUX(0, "clk_uart0_div", "clk_uart0_src", 0,
RK3399_CLKSEL_CON(33), 0, 7, DFLAGS, RK3399_CLKSEL_CON(33), 0, 7, DFLAGS,
RK3399_CLKGATE_CON(9), 0, GFLAGS), RK3399_CLKGATE_CON(9), 0, GFLAGS),
COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div", CLK_SET_RATE_PARENT, COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_div", 0,
RK3399_CLKSEL_CON(100), 0, RK3399_CLKSEL_CON(100), 0,
RK3399_CLKGATE_CON(9), 1, GFLAGS, RK3399_CLKGATE_CON(9), 1, GFLAGS,
&rk3399_uart0_fracmux), &rk3399_uart0_fracmux),
...@@ -641,7 +648,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { ...@@ -641,7 +648,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
COMPOSITE_NOMUX(0, "clk_uart1_div", "clk_uart_src", 0, COMPOSITE_NOMUX(0, "clk_uart1_div", "clk_uart_src", 0,
RK3399_CLKSEL_CON(34), 0, 7, DFLAGS, RK3399_CLKSEL_CON(34), 0, 7, DFLAGS,
RK3399_CLKGATE_CON(9), 2, GFLAGS), RK3399_CLKGATE_CON(9), 2, GFLAGS),
COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div", CLK_SET_RATE_PARENT, COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_div", 0,
RK3399_CLKSEL_CON(101), 0, RK3399_CLKSEL_CON(101), 0,
RK3399_CLKGATE_CON(9), 3, GFLAGS, RK3399_CLKGATE_CON(9), 3, GFLAGS,
&rk3399_uart1_fracmux), &rk3399_uart1_fracmux),
...@@ -649,7 +656,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { ...@@ -649,7 +656,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
COMPOSITE_NOMUX(0, "clk_uart2_div", "clk_uart_src", 0, COMPOSITE_NOMUX(0, "clk_uart2_div", "clk_uart_src", 0,
RK3399_CLKSEL_CON(35), 0, 7, DFLAGS, RK3399_CLKSEL_CON(35), 0, 7, DFLAGS,
RK3399_CLKGATE_CON(9), 4, GFLAGS), RK3399_CLKGATE_CON(9), 4, GFLAGS),
COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div", CLK_SET_RATE_PARENT, COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_div", 0,
RK3399_CLKSEL_CON(102), 0, RK3399_CLKSEL_CON(102), 0,
RK3399_CLKGATE_CON(9), 5, GFLAGS, RK3399_CLKGATE_CON(9), 5, GFLAGS,
&rk3399_uart2_fracmux), &rk3399_uart2_fracmux),
...@@ -657,7 +664,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { ...@@ -657,7 +664,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
COMPOSITE_NOMUX(0, "clk_uart3_div", "clk_uart_src", 0, COMPOSITE_NOMUX(0, "clk_uart3_div", "clk_uart_src", 0,
RK3399_CLKSEL_CON(36), 0, 7, DFLAGS, RK3399_CLKSEL_CON(36), 0, 7, DFLAGS,
RK3399_CLKGATE_CON(9), 6, GFLAGS), RK3399_CLKGATE_CON(9), 6, GFLAGS),
COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_div", CLK_SET_RATE_PARENT, COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_div", 0,
RK3399_CLKSEL_CON(103), 0, RK3399_CLKSEL_CON(103), 0,
RK3399_CLKGATE_CON(9), 7, GFLAGS, RK3399_CLKGATE_CON(9), 7, GFLAGS,
&rk3399_uart3_fracmux), &rk3399_uart3_fracmux),
...@@ -846,9 +853,9 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { ...@@ -846,9 +853,9 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
RK3399_CLKSEL_CON(14), 12, 2, DFLAGS, RK3399_CLKSEL_CON(14), 12, 2, DFLAGS,
RK3399_CLKGATE_CON(5), 4, GFLAGS), RK3399_CLKGATE_CON(5), 4, GFLAGS),
GATE(ACLK_PERF_PCIE, "aclk_perf_pcie", "aclk_perihp", CLK_IGNORE_UNUSED, GATE(ACLK_PERF_PCIE, "aclk_perf_pcie", "aclk_perihp", 0,
RK3399_CLKGATE_CON(20), 2, GFLAGS), RK3399_CLKGATE_CON(20), 2, GFLAGS),
GATE(ACLK_PCIE, "aclk_pcie", "aclk_perihp", CLK_IGNORE_UNUSED, GATE(ACLK_PCIE, "aclk_pcie", "aclk_perihp", 0,
RK3399_CLKGATE_CON(20), 10, GFLAGS), RK3399_CLKGATE_CON(20), 10, GFLAGS),
GATE(0, "aclk_perihp_noc", "aclk_perihp", CLK_IGNORE_UNUSED, GATE(0, "aclk_perihp_noc", "aclk_perihp", CLK_IGNORE_UNUSED,
RK3399_CLKGATE_CON(20), 12, GFLAGS), RK3399_CLKGATE_CON(20), 12, GFLAGS),
...@@ -1161,7 +1168,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { ...@@ -1161,7 +1168,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
RK3399_CLKSEL_CON(49), 8, 2, MFLAGS, 0, 8, DFLAGS, RK3399_CLKSEL_CON(49), 8, 2, MFLAGS, 0, 8, DFLAGS,
RK3399_CLKGATE_CON(10), 12, GFLAGS), RK3399_CLKGATE_CON(10), 12, GFLAGS),
COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop0_frac", "dclk_vop0_div", CLK_SET_RATE_PARENT, COMPOSITE_FRACMUX_NOGATE(DCLK_VOP0_FRAC, "dclk_vop0_frac", "dclk_vop0_div", 0,
RK3399_CLKSEL_CON(106), 0, RK3399_CLKSEL_CON(106), 0,
&rk3399_dclk_vop0_fracmux), &rk3399_dclk_vop0_fracmux),
...@@ -1191,7 +1198,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { ...@@ -1191,7 +1198,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
RK3399_CLKSEL_CON(50), 8, 2, MFLAGS, 0, 8, DFLAGS, RK3399_CLKSEL_CON(50), 8, 2, MFLAGS, 0, 8, DFLAGS,
RK3399_CLKGATE_CON(10), 13, GFLAGS), RK3399_CLKGATE_CON(10), 13, GFLAGS),
COMPOSITE_FRACMUX_NOGATE(0, "dclk_vop1_frac", "dclk_vop1_div", CLK_SET_RATE_PARENT, COMPOSITE_FRACMUX_NOGATE(DCLK_VOP1_FRAC, "dclk_vop1_frac", "dclk_vop1_div", 0,
RK3399_CLKSEL_CON(107), 0, RK3399_CLKSEL_CON(107), 0,
&rk3399_dclk_vop1_fracmux), &rk3399_dclk_vop1_fracmux),
...@@ -1305,7 +1312,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { ...@@ -1305,7 +1312,7 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
/* testout */ /* testout */
MUX(0, "clk_test_pre", mux_pll_src_cpll_gpll_p, CLK_SET_RATE_PARENT, MUX(0, "clk_test_pre", mux_pll_src_cpll_gpll_p, CLK_SET_RATE_PARENT,
RK3399_CLKSEL_CON(58), 7, 1, MFLAGS), RK3399_CLKSEL_CON(58), 7, 1, MFLAGS),
COMPOSITE_FRAC(0, "clk_test_frac", "clk_test_pre", CLK_SET_RATE_PARENT, COMPOSITE_FRAC(0, "clk_test_frac", "clk_test_pre", 0,
RK3399_CLKSEL_CON(105), 0, RK3399_CLKSEL_CON(105), 0,
RK3399_CLKGATE_CON(13), 9, GFLAGS), RK3399_CLKGATE_CON(13), 9, GFLAGS),
...@@ -1377,6 +1384,18 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = { ...@@ -1377,6 +1384,18 @@ static struct rockchip_clk_branch rk3399_clk_branches[] __initdata = {
COMPOSITE_NOMUX(0, "clk_test", "clk_test_pre", CLK_IGNORE_UNUSED, COMPOSITE_NOMUX(0, "clk_test", "clk_test_pre", CLK_IGNORE_UNUSED,
RK3368_CLKSEL_CON(58), 0, 5, DFLAGS, RK3368_CLKSEL_CON(58), 0, 5, DFLAGS,
RK3368_CLKGATE_CON(13), 11, GFLAGS), RK3368_CLKGATE_CON(13), 11, GFLAGS),
/* ddrc */
GATE(0, "clk_ddrc_lpll_src", "lpll", 0, RK3399_CLKGATE_CON(3),
0, GFLAGS),
GATE(0, "clk_ddrc_bpll_src", "bpll", 0, RK3399_CLKGATE_CON(3),
1, GFLAGS),
GATE(0, "clk_ddrc_dpll_src", "dpll", 0, RK3399_CLKGATE_CON(3),
2, GFLAGS),
GATE(0, "clk_ddrc_gpll_src", "gpll", 0, RK3399_CLKGATE_CON(3),
3, GFLAGS),
COMPOSITE_DDRCLK(SCLK_DDRC, "sclk_ddrc", mux_ddrclk_p, 0,
RK3399_CLKSEL_CON(6), 4, 2, 0, 0, ROCKCHIP_DDRCLK_SIP),
}; };
static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = { static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
...@@ -1398,7 +1417,7 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = { ...@@ -1398,7 +1417,7 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
RK3399_PMU_CLKSEL_CON(1), 13, 1, MFLAGS, 8, 5, DFLAGS, RK3399_PMU_CLKSEL_CON(1), 13, 1, MFLAGS, 8, 5, DFLAGS,
RK3399_PMU_CLKGATE_CON(0), 8, GFLAGS), RK3399_PMU_CLKGATE_CON(0), 8, GFLAGS),
COMPOSITE_FRACMUX_NOGATE(0, "clk_wifi_frac", "clk_wifi_div", CLK_SET_RATE_PARENT, COMPOSITE_FRACMUX_NOGATE(0, "clk_wifi_frac", "clk_wifi_div", 0,
RK3399_PMU_CLKSEL_CON(7), 0, RK3399_PMU_CLKSEL_CON(7), 0,
&rk3399_pmuclk_wifi_fracmux), &rk3399_pmuclk_wifi_fracmux),
...@@ -1426,7 +1445,7 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = { ...@@ -1426,7 +1445,7 @@ static struct rockchip_clk_branch rk3399_clk_pmu_branches[] __initdata = {
RK3399_PMU_CLKSEL_CON(5), 10, 1, MFLAGS, 0, 7, DFLAGS, RK3399_PMU_CLKSEL_CON(5), 10, 1, MFLAGS, 0, 7, DFLAGS,
RK3399_PMU_CLKGATE_CON(0), 5, GFLAGS), RK3399_PMU_CLKGATE_CON(0), 5, GFLAGS),
COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_div", CLK_SET_RATE_PARENT, COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_div", 0,
RK3399_PMU_CLKSEL_CON(6), 0, RK3399_PMU_CLKSEL_CON(6), 0,
RK3399_PMU_CLKGATE_CON(0), 6, GFLAGS, RK3399_PMU_CLKGATE_CON(0), 6, GFLAGS,
&rk3399_uart4_pmu_fracmux), &rk3399_uart4_pmu_fracmux),
...@@ -1468,6 +1487,9 @@ static const char *const rk3399_cru_critical_clocks[] __initconst = { ...@@ -1468,6 +1487,9 @@ static const char *const rk3399_cru_critical_clocks[] __initconst = {
"aclk_cci_pre", "aclk_cci_pre",
"aclk_gic", "aclk_gic",
"aclk_gic_noc", "aclk_gic_noc",
"aclk_hdcp_noc",
"hclk_hdcp_noc",
"pclk_hdcp_noc",
"pclk_perilp0", "pclk_perilp0",
"pclk_perilp0", "pclk_perilp0",
"hclk_perilp0", "hclk_perilp0",
...@@ -1488,6 +1510,10 @@ static const char *const rk3399_cru_critical_clocks[] __initconst = { ...@@ -1488,6 +1510,10 @@ static const char *const rk3399_cru_critical_clocks[] __initconst = {
"gpll_hclk_perilp1_src", "gpll_hclk_perilp1_src",
"gpll_aclk_perilp0_src", "gpll_aclk_perilp0_src",
"gpll_aclk_perihp_src", "gpll_aclk_perihp_src",
"aclk_vio_noc",
/* ddrc */
"sclk_ddrc"
}; };
static const char *const rk3399_pmucru_critical_clocks[] __initconst = { static const char *const rk3399_pmucru_critical_clocks[] __initconst = {
......
...@@ -49,14 +49,19 @@ static void __init rk2928_gate_clk_init(struct device_node *node) ...@@ -49,14 +49,19 @@ static void __init rk2928_gate_clk_init(struct device_node *node)
} }
reg = of_iomap(node, 0); reg = of_iomap(node, 0);
if (!reg)
return;
clk_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); clk_data = kzalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
if (!clk_data) if (!clk_data) {
iounmap(reg);
return; return;
}
clk_data->clks = kzalloc(qty * sizeof(struct clk *), GFP_KERNEL); clk_data->clks = kzalloc(qty * sizeof(struct clk *), GFP_KERNEL);
if (!clk_data->clks) { if (!clk_data->clks) {
kfree(clk_data); kfree(clk_data);
iounmap(reg);
return; return;
} }
......
...@@ -385,7 +385,7 @@ void __init rockchip_clk_register_plls(struct rockchip_clk_provider *ctx, ...@@ -385,7 +385,7 @@ void __init rockchip_clk_register_plls(struct rockchip_clk_provider *ctx,
list->con_offset, grf_lock_offset, list->con_offset, grf_lock_offset,
list->lock_shift, list->mode_offset, list->lock_shift, list->mode_offset,
list->mode_shift, list->rate_table, list->mode_shift, list->rate_table,
list->pll_flags); list->flags, list->pll_flags);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n", __func__, pr_err("%s: failed to register clock %s\n", __func__,
list->name); list->name);
...@@ -484,6 +484,15 @@ void __init rockchip_clk_register_branches( ...@@ -484,6 +484,15 @@ void __init rockchip_clk_register_branches(
list->gate_offset, list->gate_shift, list->gate_offset, list->gate_shift,
list->gate_flags, flags, &ctx->lock); list->gate_flags, flags, &ctx->lock);
break; break;
case branch_ddrclk:
clk = rockchip_clk_register_ddrclk(
list->name, list->flags,
list->parent_names, list->num_parents,
list->muxdiv_offset, list->mux_shift,
list->mux_width, list->div_shift,
list->div_width, list->div_flags,
ctx->reg_base, &ctx->lock);
break;
} }
/* none of the cases above matched */ /* none of the cases above matched */
......
...@@ -238,7 +238,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, ...@@ -238,7 +238,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx,
u8 num_parents, int con_offset, int grf_lock_offset, u8 num_parents, int con_offset, int grf_lock_offset,
int lock_shift, int mode_offset, int mode_shift, int lock_shift, int mode_offset, int mode_shift,
struct rockchip_pll_rate_table *rate_table, struct rockchip_pll_rate_table *rate_table,
u8 clk_pll_flags); unsigned long flags, u8 clk_pll_flags);
struct rockchip_cpuclk_clksel { struct rockchip_cpuclk_clksel {
int reg; int reg;
...@@ -281,6 +281,20 @@ struct clk *rockchip_clk_register_mmc(const char *name, ...@@ -281,6 +281,20 @@ struct clk *rockchip_clk_register_mmc(const char *name,
const char *const *parent_names, u8 num_parents, const char *const *parent_names, u8 num_parents,
void __iomem *reg, int shift); void __iomem *reg, int shift);
/*
* DDRCLK flags, including method of setting the rate
* ROCKCHIP_DDRCLK_SIP: use SIP call to bl31 to change ddrclk rate.
*/
#define ROCKCHIP_DDRCLK_SIP BIT(0)
struct clk *rockchip_clk_register_ddrclk(const char *name, int flags,
const char *const *parent_names,
u8 num_parents, int mux_offset,
int mux_shift, int mux_width,
int div_shift, int div_width,
int ddr_flags, void __iomem *reg_base,
spinlock_t *lock);
#define ROCKCHIP_INVERTER_HIWORD_MASK BIT(0) #define ROCKCHIP_INVERTER_HIWORD_MASK BIT(0)
struct clk *rockchip_clk_register_inverter(const char *name, struct clk *rockchip_clk_register_inverter(const char *name,
...@@ -299,6 +313,7 @@ enum rockchip_clk_branch_type { ...@@ -299,6 +313,7 @@ enum rockchip_clk_branch_type {
branch_mmc, branch_mmc,
branch_inverter, branch_inverter,
branch_factor, branch_factor,
branch_ddrclk,
}; };
struct rockchip_clk_branch { struct rockchip_clk_branch {
...@@ -488,6 +503,24 @@ struct rockchip_clk_branch { ...@@ -488,6 +503,24 @@ struct rockchip_clk_branch {
.child = ch, \ .child = ch, \
} }
#define COMPOSITE_DDRCLK(_id, cname, pnames, f, mo, ms, mw, \
ds, dw, df) \
{ \
.id = _id, \
.branch_type = branch_ddrclk, \
.name = cname, \
.parent_names = pnames, \
.num_parents = ARRAY_SIZE(pnames), \
.flags = f, \
.muxdiv_offset = mo, \
.mux_shift = ms, \
.mux_width = mw, \
.div_shift = ds, \
.div_width = dw, \
.div_flags = df, \
.gate_offset = -1, \
}
#define MUX(_id, cname, pnames, f, o, s, w, mf) \ #define MUX(_id, cname, pnames, f, o, s, w, mf) \
{ \ { \
.id = _id, \ .id = _id, \
......
...@@ -131,12 +131,15 @@ ...@@ -131,12 +131,15 @@
#define SCLK_DPHY_RX0_CFG 165 #define SCLK_DPHY_RX0_CFG 165
#define SCLK_RMII_SRC 166 #define SCLK_RMII_SRC 166
#define SCLK_PCIEPHY_REF100M 167 #define SCLK_PCIEPHY_REF100M 167
#define SCLK_DDRC 168
#define DCLK_VOP0 180 #define DCLK_VOP0 180
#define DCLK_VOP1 181 #define DCLK_VOP1 181
#define DCLK_VOP0_DIV 182 #define DCLK_VOP0_DIV 182
#define DCLK_VOP1_DIV 183 #define DCLK_VOP1_DIV 183
#define DCLK_M0_PERILP 184 #define DCLK_M0_PERILP 184
#define DCLK_VOP0_FRAC 185
#define DCLK_VOP1_FRAC 186
#define FCLK_CM0S 190 #define FCLK_CM0S 190
......
/*
* Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd
* Author: Lin Huang <hl@rock-chips.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.
*/
#ifndef __SOC_ROCKCHIP_SIP_H
#define __SOC_ROCKCHIP_SIP_H
#define ROCKCHIP_SIP_DRAM_FREQ 0x82000008
#define ROCKCHIP_SIP_CONFIG_DRAM_INIT 0x00
#define ROCKCHIP_SIP_CONFIG_DRAM_SET_RATE 0x01
#define ROCKCHIP_SIP_CONFIG_DRAM_ROUND_RATE 0x02
#define ROCKCHIP_SIP_CONFIG_DRAM_SET_AT_SR 0x03
#define ROCKCHIP_SIP_CONFIG_DRAM_GET_BW 0x04
#define ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE 0x05
#define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ 0x06
#define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM 0x07
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment