mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 11:50:43 +09:00
clk: update clk for axg
PD#142470: 1. add amlogic,axg-clkc.h for mesonaxg.dtsi and fix clkc reg value 2. update pcie and hifi pll setting for axg PD#142470: update hifi pll setting for axg Change-Id: I34aac4ead8384e6a150ae8630034c247f53ac27a Signed-off-by: Yun Cai <yun.cai@amlogic.com>
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include <dt-bindings/gpio/mesonaxg-gpio.h>
|
||||
#include <dt-bindings/pwm/pwm.h>
|
||||
#include <dt-bindings/pwm/meson.h>
|
||||
|
||||
/ {
|
||||
cpus:cpus {
|
||||
#address-cells = <2>;
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
#
|
||||
|
||||
obj-$(CONFIG_AMLOGIC_GX_CLK) += axg.o \
|
||||
axg_clk-pll.o \
|
||||
axg_clk_sdemmc.o axg_clk_media.o axg_clk_misc.o
|
||||
|
||||
@@ -63,7 +63,7 @@ static struct meson_clk_pll axg_fixed_pll = {
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "fixed_pll",
|
||||
.ops = &meson_clk_pll_ro_ops,
|
||||
.ops = &meson_axg_pll_ro_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
@@ -91,7 +91,7 @@ static struct meson_clk_pll axg_sys_pll = {
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "sys_pll",
|
||||
.ops = &meson_clk_pll_ops,
|
||||
.ops = &meson_axg_pll_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
@@ -119,7 +119,7 @@ static struct meson_clk_pll axg_gp0_pll = {
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gp0_pll",
|
||||
.ops = &meson_clk_pll_ops,
|
||||
.ops = &meson_axg_pll_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
@@ -147,7 +147,7 @@ static struct meson_clk_pll axg_hifi_pll = {
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "hifi_pll",
|
||||
.ops = &meson_clk_pll_ops,
|
||||
.ops = &meson_axg_pll_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
@@ -305,7 +305,7 @@ static struct meson_clk_mpll axg_mpll3 = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct meson_clk_pll axg_pcierefpll = {
|
||||
static struct meson_clk_pll axg_pcie_pll = {
|
||||
.m = {
|
||||
.reg_off = HHI_PCIE_PLL_CNTL,
|
||||
.shift = 0,
|
||||
@@ -321,18 +321,71 @@ static struct meson_clk_pll axg_pcierefpll = {
|
||||
.shift = 16,
|
||||
.width = 2,
|
||||
},
|
||||
//.rate_table = axg_gp0_pll_rate_table,
|
||||
//.rate_count = ARRAY_SIZE(axg_gp0_pll_rate_table),
|
||||
.od2 = {
|
||||
.reg_off = HHI_PCIE_PLL_CNTL6,
|
||||
.shift = 6,
|
||||
.width = 2,
|
||||
},
|
||||
.frac = {
|
||||
.reg_off = HHI_PCIE_PLL_CNTL1,
|
||||
.shift = 0,
|
||||
.width = 12,
|
||||
},
|
||||
.rate_table = axg_pcie_pll_rate_table,
|
||||
.rate_count = ARRAY_SIZE(axg_pcie_pll_rate_table),
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "pcierefpll",
|
||||
.ops = &meson_clk_pll_ops,
|
||||
.parent_names = (const char *[]){ "mpll3" },
|
||||
.name = "pcie_pll",
|
||||
.ops = &meson_axg_pll_ops,
|
||||
.parent_names = (const char *[]){ "xtal" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_mux axg_pcie_mux = {
|
||||
.reg = (void *)HHI_PCIE_PLL_CNTL6,
|
||||
.mask = 0x1,
|
||||
.shift = 2,
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "axg_pcie_mux",
|
||||
.ops = &clk_mux_ops,
|
||||
.parent_names = (const char *[]){ "mpll3", "pcie_pll" },
|
||||
.num_parents = 2,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED),
|
||||
},
|
||||
};
|
||||
#if 0
|
||||
static struct clk_gate axg_pcie_input_gate = {
|
||||
.reg = (void *)HHI_PCIE_PLL_CNTL6,
|
||||
.bit_idx = 1,
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "axg_pcie_input_gate",
|
||||
.ops = &clk_gate_ops,
|
||||
.parent_names = (const char *[]){ "pcie_input" },
|
||||
.num_parents = 1,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED),
|
||||
},
|
||||
};
|
||||
#endif
|
||||
static struct clk_mux axg_pcie_ref = {
|
||||
.reg = (void *)HHI_PCIE_PLL_CNTL6,
|
||||
.mask = 0x1,
|
||||
.shift = 1,
|
||||
.lock = &clk_lock,
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "axg_pcie_ref",
|
||||
.ops = &clk_mux_ops,
|
||||
//.parent_names = (const char *[]){ "axg_pcie_input_gate",
|
||||
.parent_names = (const char *[]){ "NULL",
|
||||
"axg_pcie_mux" },
|
||||
.num_parents = 2,
|
||||
.flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED),
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL
|
||||
* post-dividers and should be modelled with their respective PLLs via the
|
||||
@@ -644,7 +697,10 @@ static struct clk_hw *axg_clk_hws[] = {
|
||||
[CLKID_CPU_FCLK_P1] = &axg_cpu_fixedpll_p1.hw,
|
||||
[CLKID_CPU_FCLK_P] = &axg_cpu_fixedpll_p.hw,
|
||||
[CLKID_CPU_CLK] = &axg_cpu_clk.mux.hw,
|
||||
[CLKID_PCIE_REFPLL] = &axg_pcierefpll.hw,
|
||||
[CLKID_PCIE_PLL] = &axg_pcie_pll.hw,
|
||||
[CLKID_PCIE_MUX] = &axg_pcie_mux.hw,
|
||||
[CLKID_PCIE_REF] = &axg_pcie_ref.hw,
|
||||
// [CLKID_PCIE_INPUT_GATE] = &axg_pcie_input_gate.hw,
|
||||
};
|
||||
/* Convenience tables to populate base addresses in .probe */
|
||||
|
||||
@@ -653,7 +709,7 @@ static struct meson_clk_pll *const axg_clk_plls[] = {
|
||||
&axg_sys_pll,
|
||||
&axg_gp0_pll,
|
||||
&axg_hifi_pll,
|
||||
&axg_pcierefpll,
|
||||
&axg_pcie_pll,
|
||||
};
|
||||
|
||||
static struct meson_clk_mpll *const axg_clk_mplls[] = {
|
||||
@@ -747,6 +803,9 @@ static void __init axg_clkc_init(struct device_node *np)
|
||||
axg_mpeg_clk_sel.reg = clk_base + (u64)axg_mpeg_clk_sel.reg;
|
||||
axg_mpeg_clk_div.reg = clk_base + (u64)axg_mpeg_clk_div.reg;
|
||||
|
||||
axg_pcie_mux.reg = clk_base + (u64)axg_pcie_mux.reg;
|
||||
axg_pcie_ref.reg = clk_base + (u64)axg_pcie_ref.reg;
|
||||
|
||||
/* Populate base address for gates */
|
||||
for (i = 0; i < ARRAY_SIZE(axg_clk_gates); i++)
|
||||
axg_clk_gates[i]->reg = clk_base +
|
||||
@@ -766,10 +825,15 @@ static void __init axg_clkc_init(struct device_node *np)
|
||||
*/
|
||||
|
||||
for (clkid = 0; clkid < OTHER_BASE; clkid++) {
|
||||
if (axg_clk_hws[clkid]) {
|
||||
clks[clkid] = clk_register(NULL, axg_clk_hws[clkid]);
|
||||
WARN_ON(IS_ERR(clks[clkid]));
|
||||
}
|
||||
}
|
||||
|
||||
clk_set_parent(clks[CLKID_PCIE_MUX], clks[CLKID_PCIE_PLL]);
|
||||
clk_set_parent(clks[CLKID_PCIE_REF], clks[CLKID_PCIE_MUX]);
|
||||
|
||||
axg_amlogic_init_sdemmc();
|
||||
axg_amlogic_init_media();
|
||||
axg_amlogic_init_misc();
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
#define HHI_HIFI_PLL_CNTL 0x80 /* 0x20 offset in data sheet */
|
||||
|
||||
#define HHI_PCIE_PLL_CNTL 0xd8 /* 0x36 offset in data sheet */
|
||||
#define HHI_PCIE_PLL_CNTL1 0xdc /* 0x37 offset in data sheet */
|
||||
#define HHI_PCIE_PLL_CNTL6 0xf0 /* 0x3c offset in data sheet */
|
||||
|
||||
#define HHI_GCLK_MPEG0 0x140 /* 0x50 offset in data sheet */
|
||||
#define HHI_GCLK_MPEG1 0x144 /* 0x51 offset in data sheet */
|
||||
@@ -265,4 +267,9 @@ static const struct pll_rate_table axg_gp0_pll_rate_table[] = {
|
||||
PLL_RATE(1632000000, 68, 1, 0),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
static const struct pll_rate_table axg_pcie_pll_rate_table[] = {
|
||||
PLL_FRAC_RATE(100000000, 66, 1, 1, 3, 683),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
#endif /* __AXG_H */
|
||||
|
||||
274
drivers/amlogic/clk/axg/axg_clk-pll.c
Normal file
274
drivers/amlogic/clk/axg/axg_clk-pll.c
Normal file
@@ -0,0 +1,274 @@
|
||||
/*
|
||||
* drivers/amlogic/clk/axg/axg_clk-pll.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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* In the most basic form, a Meson PLL is composed as follows:
|
||||
*
|
||||
* PLL
|
||||
* +------------------------------+
|
||||
* | |
|
||||
* in -----[ /N ]---[ *M ]---[ >>OD ]----->> out
|
||||
* | ^ ^ |
|
||||
* +------------------------------+
|
||||
* | |
|
||||
* FREF VCO
|
||||
*
|
||||
* out = (in * M / N) >> OD
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#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/string.h>
|
||||
#include <linux/amlogic/cpu_version.h>
|
||||
|
||||
#ifdef CONFIG_ARM64
|
||||
#include "../clkc.h"
|
||||
#else
|
||||
#include "m8b/clkc.h"
|
||||
#endif
|
||||
|
||||
#define MESON_PLL_RESET BIT(29)
|
||||
#define MESON_PLL_ENABLE BIT(30)
|
||||
#define MESON_PLL_LOCK BIT(31)
|
||||
|
||||
/* GXL TXL */
|
||||
#define GXL_GP0_CNTL1 0xc084a000
|
||||
#define GXL_GP0_CNTL2 0xb75020be
|
||||
#define GXL_GP0_CNTL3 0x0a59a288
|
||||
#define GXL_GP0_CNTL4 0xc000004d
|
||||
#define GXL_GP0_CNTL5 0x00078000
|
||||
/* AXG */
|
||||
#define AXG_MIPI_CNTL0 0xa5b80000
|
||||
#define AXG_PCIE_PLL_CNTL 0x40010242
|
||||
#define AXG_PCIE_PLL_CNTL1 0xc084b2ab
|
||||
#define AXG_PCIE_PLL_CNTL2 0xb75020be
|
||||
#define AXG_PCIE_PLL_CNTL3 0x0a5aaa88
|
||||
#define AXG_PCIE_PLL_CNTL4 0xc000004d
|
||||
#define AXG_PCIE_PLL_CNTL5 0x00078000
|
||||
#define AXG_PCIE_PLL_CNTL6 0x003303de
|
||||
|
||||
#define AXG_HIFI_PLL_CNTL1 0xc084b000
|
||||
#define AXG_HIFI_PLL_CNTL2 0xb75020be
|
||||
#define AXG_HIFI_PLL_CNTL3 0x0a6a3a88
|
||||
#define AXG_HIFI_PLL_CNTL4 0xc000004d
|
||||
#define AXG_HIFI_PLL_CNTL5 0x000581eb
|
||||
|
||||
#define to_meson_clk_pll(_hw) container_of(_hw, struct meson_clk_pll, hw)
|
||||
|
||||
static unsigned long meson_axg_pll_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct meson_clk_pll *pll = to_meson_clk_pll(hw);
|
||||
struct parm *p;
|
||||
unsigned long parent_rate_mhz = parent_rate;
|
||||
unsigned long rate_mhz;
|
||||
u16 n, m, frac = 0, od, od2 = 0;
|
||||
u32 reg;
|
||||
|
||||
p = &pll->n;
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
n = PARM_GET(p->width, p->shift, reg);
|
||||
|
||||
p = &pll->m;
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
m = PARM_GET(p->width, p->shift, reg);
|
||||
|
||||
p = &pll->od;
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
od = PARM_GET(p->width, p->shift, reg);
|
||||
|
||||
p = &pll->od2;
|
||||
if (p->width) {
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
od2 = PARM_GET(p->width, p->shift, reg);
|
||||
}
|
||||
|
||||
p = &pll->frac;
|
||||
|
||||
if (p->width) {
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
frac = PARM_GET(p->width, p->shift, reg);
|
||||
rate_mhz = (parent_rate_mhz * m +
|
||||
(parent_rate_mhz * frac >> 12)) / n;
|
||||
rate_mhz = rate_mhz >> od >> od2;
|
||||
} else
|
||||
rate_mhz = (parent_rate_mhz * m / n) >> od >> od2;
|
||||
|
||||
return rate_mhz;
|
||||
}
|
||||
|
||||
static long meson_axg_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct meson_clk_pll *pll = to_meson_clk_pll(hw);
|
||||
const struct pll_rate_table *rate_table = pll->rate_table;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pll->rate_count; i++) {
|
||||
if (rate <= rate_table[i].rate)
|
||||
return rate_table[i].rate;
|
||||
}
|
||||
|
||||
/* else return the smallest value */
|
||||
return rate_table[0].rate;
|
||||
}
|
||||
|
||||
static const struct pll_rate_table *meson_axg_get_pll_settings
|
||||
(struct meson_clk_pll *pll, unsigned long rate)
|
||||
{
|
||||
const struct pll_rate_table *rate_table = pll->rate_table;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pll->rate_count; i++) {
|
||||
if (rate == rate_table[i].rate)
|
||||
return &rate_table[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int meson_axg_pll_wait_lock(struct meson_clk_pll *pll,
|
||||
struct parm *p_n)
|
||||
{
|
||||
int delay = 24000000;
|
||||
u32 reg;
|
||||
|
||||
while (delay > 0) {
|
||||
reg = readl(pll->base + p_n->reg_off);
|
||||
|
||||
if (reg & MESON_PLL_LOCK)
|
||||
return 0;
|
||||
delay--;
|
||||
}
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int meson_axg_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct meson_clk_pll *pll = to_meson_clk_pll(hw);
|
||||
struct parm *p;
|
||||
const struct pll_rate_table *rate_set;
|
||||
unsigned long old_rate;
|
||||
int ret = 0;
|
||||
u32 reg;
|
||||
|
||||
if (parent_rate == 0 || rate == 0)
|
||||
return -EINVAL;
|
||||
|
||||
old_rate = rate;
|
||||
|
||||
rate_set = meson_axg_get_pll_settings(pll, rate);
|
||||
if (!rate_set)
|
||||
return -EINVAL;
|
||||
|
||||
p = &pll->n;
|
||||
|
||||
if (!strcmp(clk_hw_get_name(hw), "gp0_pll")
|
||||
|| !strcmp(clk_hw_get_name(hw), "hifi_pll")
|
||||
|| !strcmp(clk_hw_get_name(hw), "pcie_pll")) {
|
||||
void *cntlbase = pll->base + p->reg_off;
|
||||
|
||||
if (!strcmp(clk_hw_get_name(hw), "pcie_pll")) {
|
||||
writel(AXG_MIPI_CNTL0, pll->base);
|
||||
writel(AXG_PCIE_PLL_CNTL, cntlbase + (u64)(0*4));
|
||||
writel(AXG_PCIE_PLL_CNTL1, cntlbase + (u64)(1*4));
|
||||
writel(AXG_PCIE_PLL_CNTL2, cntlbase + (u64)(2*4));
|
||||
writel(AXG_PCIE_PLL_CNTL3, cntlbase + (u64)(3*4));
|
||||
writel(AXG_PCIE_PLL_CNTL4, cntlbase + (u64)(4*4));
|
||||
writel(AXG_PCIE_PLL_CNTL5, cntlbase + (u64)(5*4));
|
||||
writel(AXG_PCIE_PLL_CNTL6, cntlbase + (u64)(6*4));
|
||||
} else if (!strcmp(clk_hw_get_name(hw), "hifi_pll")) {
|
||||
writel(AXG_HIFI_PLL_CNTL1, cntlbase + (u64)6*4);
|
||||
writel(AXG_HIFI_PLL_CNTL2, cntlbase + (u64)1*4);
|
||||
writel(AXG_HIFI_PLL_CNTL3, cntlbase + (u64)2*4);
|
||||
writel(AXG_HIFI_PLL_CNTL4, cntlbase + (u64)3*4);
|
||||
writel(AXG_HIFI_PLL_CNTL5, cntlbase + (u64)4*4);
|
||||
} else {
|
||||
writel(GXL_GP0_CNTL1, cntlbase + (u64)6*4);
|
||||
writel(GXL_GP0_CNTL2, cntlbase + (u64)1*4);
|
||||
writel(GXL_GP0_CNTL3, cntlbase + (u64)2*4);
|
||||
writel(GXL_GP0_CNTL4, cntlbase + (u64)3*4);
|
||||
writel(GXL_GP0_CNTL5, cntlbase + (u64)4*4);
|
||||
}
|
||||
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
writel(((reg | (MESON_PLL_ENABLE)) &
|
||||
(~MESON_PLL_RESET)), pll->base + p->reg_off);
|
||||
}
|
||||
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
|
||||
reg = PARM_SET(p->width, p->shift, reg, rate_set->n);
|
||||
writel(reg, pll->base + p->reg_off);
|
||||
|
||||
p = &pll->m;
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
reg = PARM_SET(p->width, p->shift, reg, rate_set->m);
|
||||
writel(reg, pll->base + p->reg_off);
|
||||
|
||||
p = &pll->od;
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
reg = PARM_SET(p->width, p->shift, reg, rate_set->od);
|
||||
writel(reg, pll->base + p->reg_off);
|
||||
|
||||
p = &pll->od2;
|
||||
if (p->width) {
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
reg = PARM_SET(p->width, p->shift, reg, rate_set->od2);
|
||||
writel(reg, pll->base + p->reg_off);
|
||||
}
|
||||
|
||||
p = &pll->frac;
|
||||
if (p->width) {
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
reg = PARM_SET(p->width, p->shift, reg, rate_set->frac);
|
||||
writel(reg, pll->base + p->reg_off);
|
||||
}
|
||||
|
||||
p = &pll->n;
|
||||
|
||||
/* PLL reset */
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
writel(reg | MESON_PLL_RESET, pll->base + p->reg_off);
|
||||
udelay(10);
|
||||
writel(reg & (~MESON_PLL_RESET), pll->base + p->reg_off);
|
||||
|
||||
ret = meson_axg_pll_wait_lock(pll, p);
|
||||
if (ret) {
|
||||
pr_warn("%s: pll did not lock, trying to restore old rate %lu\n",
|
||||
__func__, old_rate);
|
||||
meson_axg_pll_set_rate(hw, old_rate, parent_rate);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct clk_ops meson_axg_pll_ops = {
|
||||
.recalc_rate = meson_axg_pll_recalc_rate,
|
||||
.round_rate = meson_axg_pll_round_rate,
|
||||
.set_rate = meson_axg_pll_set_rate,
|
||||
};
|
||||
|
||||
const struct clk_ops meson_axg_pll_ro_ops = {
|
||||
.recalc_rate = meson_axg_pll_recalc_rate,
|
||||
};
|
||||
|
||||
@@ -93,6 +93,7 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
|
||||
}
|
||||
|
||||
p = &pll->frac;
|
||||
|
||||
if (p->width) {
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
frac = PARM_GET(p->width, p->shift, reg);
|
||||
@@ -172,25 +173,27 @@ static int meson_clk_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
p = &pll->n;
|
||||
|
||||
if (!strcmp(clk_hw_get_name(hw), "gp0_pll")) {
|
||||
void *cntlbase = pll->base + p->reg_off;
|
||||
|
||||
if ((get_cpu_type() == MESON_CPU_MAJOR_ID_GXBB) ||
|
||||
(get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB)) {
|
||||
writel(GXBB_GP0_CNTL2, pll->base + p->reg_off + 1*4);
|
||||
writel(GXBB_GP0_CNTL3, pll->base + p->reg_off + 2*4);
|
||||
writel(GXBB_GP0_CNTL4, pll->base + p->reg_off + 3*4);
|
||||
writel(GXBB_GP0_CNTL2, cntlbase + (u64)1*4);
|
||||
writel(GXBB_GP0_CNTL3, cntlbase + (u64)2*4);
|
||||
writel(GXBB_GP0_CNTL4, cntlbase + (u64)3*4);
|
||||
}
|
||||
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) {
|
||||
writel(GXL_GP0_CNTL1, pll->base + p->reg_off + 6*4);
|
||||
writel(GXL_GP0_CNTL2, pll->base + p->reg_off + 1*4);
|
||||
writel(GXL_GP0_CNTL3, pll->base + p->reg_off + 2*4);
|
||||
writel(GXL_GP0_CNTL4, pll->base + p->reg_off + 3*4);
|
||||
writel(GXL_GP0_CNTL5, pll->base + p->reg_off + 4*4);
|
||||
writel(GXL_GP0_CNTL1, cntlbase + (u64)6*4);
|
||||
writel(GXL_GP0_CNTL2, cntlbase + (u64)1*4);
|
||||
writel(GXL_GP0_CNTL3, cntlbase + (u64)2*4);
|
||||
writel(GXL_GP0_CNTL4, cntlbase + (u64)3*4);
|
||||
writel(GXL_GP0_CNTL5, cntlbase + (u64)4*4);
|
||||
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
writel(((reg | (MESON_PLL_ENABLE)) &
|
||||
(~MESON_PLL_RESET)), pll->base + p->reg_off);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
reg = readl(pll->base + p->reg_off);
|
||||
|
||||
reg = PARM_SET(p->width, p->shift, reg, rate_set->n);
|
||||
|
||||
@@ -128,6 +128,9 @@ extern const struct clk_ops meson_clk_cpu_ops;
|
||||
extern const struct clk_ops meson_clk_mpll_ro_ops;
|
||||
extern const struct clk_ops meson_clk_mpll_ops;
|
||||
extern const struct clk_ops meson_clk_mux_ops;
|
||||
extern const struct clk_ops meson_axg_pll_ro_ops;
|
||||
extern const struct clk_ops meson_axg_pll_ops;
|
||||
|
||||
extern spinlock_t clk_lock;
|
||||
extern void __iomem *clk_base;
|
||||
extern struct clk **clks;
|
||||
|
||||
@@ -46,7 +46,11 @@
|
||||
#define CLKID_CPU_FCLK_P1 21
|
||||
#define CLKID_CPU_FCLK_P 22
|
||||
#define CLKID_CPU_CLK 23
|
||||
#define CLKID_PCIE_REFPLL 24
|
||||
#define CLKID_PCIE_PLL 24
|
||||
#define CLKID_PCIE_MUX 25
|
||||
#define CLKID_PCIE_REF 26
|
||||
#define CLKID_PCIE_INPUT_GATE 27
|
||||
|
||||
/*HHI_GCLK_MPEG0: 0x50*/
|
||||
#define GATE_BASE0 25
|
||||
#define CLKID_DDR (GATE_BASE0 + 0)
|
||||
@@ -70,7 +74,7 @@
|
||||
#define CLKID_DMA (GATE_BASE0 + 18)
|
||||
#define CLKID_SPI (GATE_BASE0 + 19)
|
||||
/*HHI_GCLK_MPEG1: 0x51*/
|
||||
#define GATE_BASE1 (GATE_BASE0 + 20) /*25+20*/
|
||||
#define GATE_BASE1 (GATE_BASE0 + 20) /*28+20*/
|
||||
#define CLKID_AUDIO (GATE_BASE1 + 0)
|
||||
#define CLKID_ETH_CORE (GATE_BASE1 + 1)
|
||||
#define CLKID_UART1 (GATE_BASE1 + 2)
|
||||
@@ -83,7 +87,7 @@
|
||||
#define CLKID_EFUSE (GATE_BASE1 + 9)
|
||||
#define CLKID_BOOT_ROM (GATE_BASE1 + 10)
|
||||
/*HHI_GCLK_MPEG2: 0x52*/
|
||||
#define GATE_BASE2 (GATE_BASE1 + 11) /*25+20+11*/
|
||||
#define GATE_BASE2 (GATE_BASE1 + 11) /*28+20+11*/
|
||||
#define CLKID_AHB_DATA_BUS (GATE_BASE2 + 0)
|
||||
#define CLKID_AHB_CTRL_BUS (GATE_BASE2 + 1)
|
||||
#define CLKID_USB1_TO_DDR (GATE_BASE2 + 2)
|
||||
@@ -93,14 +97,14 @@
|
||||
#define CLKID_SEC_AHB_AHB3_BRIDGE (GATE_BASE2 + 6)
|
||||
#define CLKID_GIC (GATE_BASE2 + 7)
|
||||
|
||||
#define AO_BASE (GATE_BASE2 + 8) /*25+20+11+8*/
|
||||
#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 OTHER_BASE (AO_BASE + 5) /*25+20+11+8+5=69*/
|
||||
#define OTHER_BASE (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)
|
||||
@@ -118,7 +122,7 @@
|
||||
#define CLKID_SD_EMMC_C_GATE (OTHER_BASE + 14)
|
||||
#define CLKID_SD_EMMC_C_COMP (OTHER_BASE + 15)
|
||||
|
||||
#define CLKID_MEDIA_BASE (OTHER_BASE + 16) /*25+20+11+8+5+16*/
|
||||
#define CLKID_MEDIA_BASE (OTHER_BASE + 16) /*28+20+11+8+5+16*/
|
||||
#define CLKID_VPU_P0_MUX (CLKID_MEDIA_BASE + 0)
|
||||
#define CLKID_VPU_P0_DIV (CLKID_MEDIA_BASE + 1)
|
||||
#define CLKID_VPU_P0_GATE (CLKID_MEDIA_BASE + 2)
|
||||
@@ -143,7 +147,7 @@
|
||||
#define CLKID_DSI_MEAS_GATE (CLKID_MEDIA_BASE + 21)
|
||||
#define CLKID_DSI_MEAS_COMP (CLKID_MEDIA_BASE + 22)
|
||||
|
||||
#define CLKID_MISC_BASE (CLKID_MEDIA_BASE + 23) /*25+20+11+8+5+16+23 = 108*/
|
||||
#define CLKID_MISC_BASE (CLKID_MEDIA_BASE + 23) /*28+20+11+8+5+16+23 = 111*/
|
||||
#define CLKID_SPICC_MUX (CLKID_MISC_BASE + 0)
|
||||
#define CLKID_SPICC_DIV (CLKID_MISC_BASE + 1)
|
||||
#define CLKID_SPICC_GATE (CLKID_MISC_BASE + 2)
|
||||
|
||||
Reference in New Issue
Block a user