Renesas ARM-based SoC updates for v3.11
* Increased clock coverage for r8a7740, r8a73a4, r8a7778 and r8a7790 * Use fixed clock ratio for r8a7778 * Always use shmobile_setup_delay for sh73a0 * Add add CPUFreq support for sh73a0 * Check kick bit before changing rate on sh73a0 * Do not overwrite all div4 clock operations on sh73a0 * Cleanup SH_FIXED_RATIO_CLK and SH_FIXED_RATIO_CLK macros * sh73a0: Use DEFINE_RES_MEM*() everywhere * r8a7740: Make private clock arrays static * r8a7778: Correct model number The last four changes listed above are cleanups. I have included them in this series as all bar the last one are dependencies of non-cleanup patches. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJRsY+RAAoJENfPZGlqN0++q3cP/0UR42WWj+pm6a7N7JDiby+b +Dv1qxQB4zN+1eBFfLoNUNponGbKLPXP7ULHkN0BX0j5xLYhVpZJeCdAdMvHnKG7 rvDLfjE0eBWyxxnaKIx/UyOmE6TTWn/TRbj726qpQWv4CFNEtEx+WdRymMSikSPK HeaXuhpm98kwqYpCH8yVu2VYgYMgv8fJxhd/N2ppsN65KKoTq5EITZ9K7+sqlueX uwG45uquBM3K+UGfr/7KMhEY/IvWHrCqq2MpgRrcJAy6ROK39oNDtG/YfI8II/dK T8IOCpHKbDvsvU/XGY3E0e2H1FRZCqzfI0dYp9Q/iSd9HSfOR3CwoMlZCC6zRBq2 dzHRqsklurbYjCSOQlHRxGNISBaSnaf6Fy8Ok720Zh7xDPinZeQrfxGccYA8eQaW +Z7k3k6M5RaipRln5Hj4XiWc+Vk5ieJ1/clvSNpq+mmIxwGLJOdsqwhBktnGwsgs 3hxlzH6owR6JgP5iDZYcTdngRqhPb8AZeQduA0I3Lwf/1eyBKYH6ryPaKVutH89Q PKJnxKETbEDN7eueblV5EhBeFHewTRn5U6wnOkD2ompuGUQCs1T2djF4F0IFy5WD KZBaTkaKORaUq5woRzc12RYnLkRVlyQ1W+1u3e7NpZSG0ZlSufgW2m4pnfSpBJ6h y+IBsNzw4ZHkNbwtj5ai =9UCz -----END PGP SIGNATURE----- Merge tag 'renesas-soc-for-v3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas into next/soc From Simon Horman: Renesas ARM-based SoC updates for v3.11 * Increased clock coverage for r8a7740, r8a73a4, r8a7778 and r8a7790 * Use fixed clock ratio for r8a7778 * Always use shmobile_setup_delay for sh73a0 * Add add CPUFreq support for sh73a0 * Check kick bit before changing rate on sh73a0 * Do not overwrite all div4 clock operations on sh73a0 * Cleanup SH_FIXED_RATIO_CLK and SH_FIXED_RATIO_CLK macros * sh73a0: Use DEFINE_RES_MEM*() everywhere * r8a7740: Make private clock arrays static * r8a7778: Correct model number The last four changes listed above are cleanups. I have included them in this series as all bar the last one are dependencies of non-cleanup patches. * tag 'renesas-soc-for-v3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/renesas: (27 commits) ARM: shmobile: sh73a0: div4 clocks must check the kick bit before changing rate ARM: shmobile: sh73a0: do not overwrite all div4 clock operations ARM: shmobile: sh73a0: Always use shmobile_setup_delay() ARM: shmobile: sh73a0: add CPUFreq support ARM: shmobile: sh73a0: add support for adjusting CPU frequency ARM: shmobile: r8a7790: add TPU PWM support ARM: shmobile: r8a7790: Make private clock arrays static ARM: shmobile: r8a7790: add div6 clocks ARM: shmobile: r8a7790: add div4 clocks ARM: shmobile: r8a7790: add main clock ARM: shmobile: r8a7778: Register SDHI device ARM: shmobile: r8a7778: add SDHI clock support ARM: shmobile: r8a7778: use fixed ratio clock ARM: shmobile: r8a7779: Add PCIe clocks ARM: shmobile: r8a73a4: add div6 clocks ARM: shmobile: r8a73a4: add div4 clocks ARM: shmobile: r8a73a4: add pll clocks ARM: shmobile: r8a73a4: add main clock ARM: shmobile: r8a7740: add TPU PWM support ARM: shmobile: r8a7740: Add I2C DT clock names ... Conflicts: arch/arm/mach-shmobile/Kconfig arch/arm/mach-shmobile/include/mach/r8a7778.h arch/arm/mach-shmobile/setup-r8a7778.c
This commit is contained in:
commit
b67172ec00
|
@ -36,7 +36,7 @@ config ARCH_R8A7740
|
|||
select RENESAS_INTC_IRQPIN
|
||||
|
||||
config ARCH_R8A7778
|
||||
bool "R-Car M1 (R8A77780)"
|
||||
bool "R-Car M1A (R8A77781)"
|
||||
select ARCH_WANT_OPTIONAL_GPIOLIB
|
||||
select CPU_V7
|
||||
select SH_CLK_CPG
|
||||
|
@ -170,6 +170,8 @@ config MACH_KZM9D
|
|||
config MACH_KZM9G
|
||||
bool "KZM-A9-GT board"
|
||||
depends on ARCH_SH73A0
|
||||
select ARCH_HAS_CPUFREQ
|
||||
select ARCH_HAS_OPP
|
||||
select ARCH_REQUIRE_GPIOLIB
|
||||
select REGULATOR_FIXED_VOLTAGE if REGULATOR
|
||||
select SND_SOC_AK4642 if SND_SIMPLE_CARD
|
||||
|
|
|
@ -22,15 +22,43 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/sh_clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <mach/clock.h>
|
||||
#include <mach/common.h>
|
||||
|
||||
#define CPG_BASE 0xe6150000
|
||||
#define CPG_LEN 0x270
|
||||
|
||||
#define MPCKCR 0xe6150080
|
||||
#define SMSTPCR2 0xe6150138
|
||||
#define SMSTPCR5 0xe6150144
|
||||
|
||||
#define FRQCRA 0xE6150000
|
||||
#define FRQCRB 0xE6150004
|
||||
#define VCLKCR1 0xE6150008
|
||||
#define VCLKCR2 0xE615000C
|
||||
#define VCLKCR3 0xE615001C
|
||||
#define VCLKCR4 0xE6150014
|
||||
#define VCLKCR5 0xE6150034
|
||||
#define ZBCKCR 0xE6150010
|
||||
#define SD0CKCR 0xE6150074
|
||||
#define SD1CKCR 0xE6150078
|
||||
#define SD2CKCR 0xE615007C
|
||||
#define MMC0CKCR 0xE6150240
|
||||
#define MMC1CKCR 0xE6150244
|
||||
#define FSIACKCR 0xE6150018
|
||||
#define FSIBCKCR 0xE6150090
|
||||
#define MPCKCR 0xe6150080
|
||||
#define SPUVCKCR 0xE6150094
|
||||
#define HSICKCR 0xE615026C
|
||||
#define M4CKCR 0xE6150098
|
||||
#define PLLECR 0xE61500D0
|
||||
#define PLL1CR 0xE6150028
|
||||
#define PLL2CR 0xE615002C
|
||||
#define PLL2SCR 0xE61501F4
|
||||
#define PLL2HCR 0xE61501E4
|
||||
#define CKSCR 0xE61500C0
|
||||
|
||||
#define CPG_MAP(o) ((o - CPG_BASE) + cpg_mapping.base)
|
||||
|
||||
static struct clk_mapping cpg_mapping = {
|
||||
.phys = CPG_BASE,
|
||||
.len = CPG_LEN,
|
||||
|
@ -51,12 +79,273 @@ static struct clk extal2_clk = {
|
|||
.mapping = &cpg_mapping,
|
||||
};
|
||||
|
||||
static struct sh_clk_ops followparent_clk_ops = {
|
||||
.recalc = followparent_recalc,
|
||||
};
|
||||
|
||||
static struct clk main_clk = {
|
||||
/* .parent will be set r8a73a4_clock_init */
|
||||
.ops = &followparent_clk_ops,
|
||||
};
|
||||
|
||||
SH_CLK_RATIO(div2, 1, 2);
|
||||
SH_CLK_RATIO(div4, 1, 4);
|
||||
|
||||
SH_FIXED_RATIO_CLK(main_div2_clk, main_clk, div2);
|
||||
SH_FIXED_RATIO_CLK(extal1_div2_clk, extal1_clk, div2);
|
||||
SH_FIXED_RATIO_CLK(extal2_div2_clk, extal2_clk, div2);
|
||||
SH_FIXED_RATIO_CLK(extal2_div4_clk, extal2_clk, div4);
|
||||
|
||||
/* External FSIACK/FSIBCK clock */
|
||||
static struct clk fsiack_clk = {
|
||||
};
|
||||
|
||||
static struct clk fsibck_clk = {
|
||||
};
|
||||
|
||||
/*
|
||||
* PLL clocks
|
||||
*/
|
||||
static struct clk *pll_parent_main[] = {
|
||||
[0] = &main_clk,
|
||||
[1] = &main_div2_clk
|
||||
};
|
||||
|
||||
static struct clk *pll_parent_main_extal[8] = {
|
||||
[0] = &main_div2_clk,
|
||||
[1] = &extal2_div2_clk,
|
||||
[3] = &extal2_div4_clk,
|
||||
[4] = &main_clk,
|
||||
[5] = &extal2_clk,
|
||||
};
|
||||
|
||||
static unsigned long pll_recalc(struct clk *clk)
|
||||
{
|
||||
unsigned long mult = 1;
|
||||
|
||||
if (ioread32(CPG_MAP(PLLECR)) & (1 << clk->enable_bit))
|
||||
mult = (((ioread32(clk->mapped_reg) >> 24) & 0x7f) + 1);
|
||||
|
||||
return clk->parent->rate * mult;
|
||||
}
|
||||
|
||||
static int pll_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
u32 val;
|
||||
int i, ret;
|
||||
|
||||
if (!clk->parent_table || !clk->parent_num)
|
||||
return -EINVAL;
|
||||
|
||||
/* Search the parent */
|
||||
for (i = 0; i < clk->parent_num; i++)
|
||||
if (clk->parent_table[i] == parent)
|
||||
break;
|
||||
|
||||
if (i == clk->parent_num)
|
||||
return -ENODEV;
|
||||
|
||||
ret = clk_reparent(clk, parent);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
val = ioread32(clk->mapped_reg) &
|
||||
~(((1 << clk->src_width) - 1) << clk->src_shift);
|
||||
|
||||
iowrite32(val | i << clk->src_shift, clk->mapped_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sh_clk_ops pll_clk_ops = {
|
||||
.recalc = pll_recalc,
|
||||
.set_parent = pll_set_parent,
|
||||
};
|
||||
|
||||
#define PLL_CLOCK(name, p, pt, w, s, reg, e) \
|
||||
static struct clk name = { \
|
||||
.ops = &pll_clk_ops, \
|
||||
.flags = CLK_ENABLE_ON_INIT, \
|
||||
.parent = p, \
|
||||
.parent_table = pt, \
|
||||
.parent_num = ARRAY_SIZE(pt), \
|
||||
.src_width = w, \
|
||||
.src_shift = s, \
|
||||
.enable_reg = (void __iomem *)reg, \
|
||||
.enable_bit = e, \
|
||||
.mapping = &cpg_mapping, \
|
||||
}
|
||||
|
||||
PLL_CLOCK(pll1_clk, &main_clk, pll_parent_main, 1, 7, PLL1CR, 1);
|
||||
PLL_CLOCK(pll2_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2CR, 2);
|
||||
PLL_CLOCK(pll2s_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2SCR, 4);
|
||||
PLL_CLOCK(pll2h_clk, &main_div2_clk, pll_parent_main_extal, 3, 5, PLL2HCR, 5);
|
||||
|
||||
SH_FIXED_RATIO_CLK(pll1_div2_clk, pll1_clk, div2);
|
||||
|
||||
static struct clk *main_clks[] = {
|
||||
&extalr_clk,
|
||||
&extal1_clk,
|
||||
&extal1_div2_clk,
|
||||
&extal2_clk,
|
||||
&extal2_div2_clk,
|
||||
&extal2_div4_clk,
|
||||
&main_clk,
|
||||
&main_div2_clk,
|
||||
&fsiack_clk,
|
||||
&fsibck_clk,
|
||||
&pll1_clk,
|
||||
&pll1_div2_clk,
|
||||
&pll2_clk,
|
||||
&pll2s_clk,
|
||||
&pll2h_clk,
|
||||
};
|
||||
|
||||
/* DIV4 */
|
||||
static void div4_kick(struct clk *clk)
|
||||
{
|
||||
unsigned long value;
|
||||
|
||||
/* set KICK bit in FRQCRB to update hardware setting */
|
||||
value = ioread32(CPG_MAP(FRQCRB));
|
||||
value |= (1 << 31);
|
||||
iowrite32(value, CPG_MAP(FRQCRB));
|
||||
}
|
||||
|
||||
static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10};
|
||||
|
||||
static struct clk_div_mult_table div4_div_mult_table = {
|
||||
.divisors = divisors,
|
||||
.nr_divisors = ARRAY_SIZE(divisors),
|
||||
};
|
||||
|
||||
static struct clk_div4_table div4_table = {
|
||||
.div_mult_table = &div4_div_mult_table,
|
||||
.kick = div4_kick,
|
||||
};
|
||||
|
||||
enum {
|
||||
DIV4_I, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
|
||||
DIV4_ZX, DIV4_ZS, DIV4_HP,
|
||||
DIV4_NR };
|
||||
|
||||
static struct clk div4_clks[DIV4_NR] = {
|
||||
[DIV4_I] = SH_CLK_DIV4(&pll1_clk, FRQCRA, 20, 0x0dff, CLK_ENABLE_ON_INIT),
|
||||
[DIV4_M3] = SH_CLK_DIV4(&pll1_clk, FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT),
|
||||
[DIV4_B] = SH_CLK_DIV4(&pll1_clk, FRQCRA, 8, 0x0dff, CLK_ENABLE_ON_INIT),
|
||||
[DIV4_M1] = SH_CLK_DIV4(&pll1_clk, FRQCRA, 4, 0x1dff, 0),
|
||||
[DIV4_M2] = SH_CLK_DIV4(&pll1_clk, FRQCRA, 0, 0x1dff, 0),
|
||||
[DIV4_ZX] = SH_CLK_DIV4(&pll1_clk, FRQCRB, 12, 0x0dff, 0),
|
||||
[DIV4_ZS] = SH_CLK_DIV4(&pll1_clk, FRQCRB, 8, 0x0dff, 0),
|
||||
[DIV4_HP] = SH_CLK_DIV4(&pll1_clk, FRQCRB, 4, 0x0dff, 0),
|
||||
};
|
||||
|
||||
enum {
|
||||
DIV6_ZB,
|
||||
DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
|
||||
DIV6_MMC0, DIV6_MMC1,
|
||||
DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_VCK4, DIV6_VCK5,
|
||||
DIV6_FSIA, DIV6_FSIB,
|
||||
DIV6_MP, DIV6_M4, DIV6_HSI, DIV6_SPUV,
|
||||
DIV6_NR };
|
||||
|
||||
static struct clk *div6_parents[8] = {
|
||||
[0] = &pll1_div2_clk,
|
||||
[1] = &pll2s_clk,
|
||||
[3] = &extal2_clk,
|
||||
[4] = &main_div2_clk,
|
||||
[6] = &extalr_clk,
|
||||
};
|
||||
|
||||
static struct clk *fsia_parents[4] = {
|
||||
[0] = &pll1_div2_clk,
|
||||
[1] = &pll2s_clk,
|
||||
[2] = &fsiack_clk,
|
||||
};
|
||||
|
||||
static struct clk *fsib_parents[4] = {
|
||||
[0] = &pll1_div2_clk,
|
||||
[1] = &pll2s_clk,
|
||||
[2] = &fsibck_clk,
|
||||
};
|
||||
|
||||
static struct clk *mp_parents[4] = {
|
||||
[0] = &pll1_div2_clk,
|
||||
[1] = &pll2s_clk,
|
||||
[2] = &extal2_clk,
|
||||
[3] = &extal2_clk,
|
||||
};
|
||||
|
||||
static struct clk *m4_parents[2] = {
|
||||
[0] = &pll2s_clk,
|
||||
};
|
||||
|
||||
static struct clk *hsi_parents[4] = {
|
||||
[0] = &pll2h_clk,
|
||||
[1] = &pll1_div2_clk,
|
||||
[3] = &pll2s_clk,
|
||||
};
|
||||
|
||||
/*** FIXME ***
|
||||
* SH_CLK_DIV6_EXT() macro doesn't care .mapping
|
||||
* but, it is necessary on R-Car (= ioremap() base CPG)
|
||||
* The difference between
|
||||
* SH_CLK_DIV6_EXT() <--> SH_CLK_MAP_DIV6_EXT()
|
||||
* is only .mapping
|
||||
*/
|
||||
#define SH_CLK_MAP_DIV6_EXT(_reg, _flags, _parents, \
|
||||
_num_parents, _src_shift, _src_width) \
|
||||
{ \
|
||||
.enable_reg = (void __iomem *)_reg, \
|
||||
.enable_bit = 0, /* unused */ \
|
||||
.flags = _flags | CLK_MASK_DIV_ON_DISABLE, \
|
||||
.div_mask = SH_CLK_DIV6_MSK, \
|
||||
.parent_table = _parents, \
|
||||
.parent_num = _num_parents, \
|
||||
.src_shift = _src_shift, \
|
||||
.src_width = _src_width, \
|
||||
.mapping = &cpg_mapping, \
|
||||
}
|
||||
|
||||
static struct clk div6_clks[DIV6_NR] = {
|
||||
[DIV6_ZB] = SH_CLK_MAP_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT,
|
||||
div6_parents, 2, 7, 1),
|
||||
[DIV6_SDHI0] = SH_CLK_MAP_DIV6_EXT(SD0CKCR, 0,
|
||||
div6_parents, 2, 6, 2),
|
||||
[DIV6_SDHI1] = SH_CLK_MAP_DIV6_EXT(SD1CKCR, 0,
|
||||
div6_parents, 2, 6, 2),
|
||||
[DIV6_SDHI2] = SH_CLK_MAP_DIV6_EXT(SD2CKCR, 0,
|
||||
div6_parents, 2, 6, 2),
|
||||
[DIV6_MMC0] = SH_CLK_MAP_DIV6_EXT(MMC0CKCR, 0,
|
||||
div6_parents, 2, 6, 2),
|
||||
[DIV6_MMC1] = SH_CLK_MAP_DIV6_EXT(MMC1CKCR, 0,
|
||||
div6_parents, 2, 6, 2),
|
||||
[DIV6_VCK1] = SH_CLK_MAP_DIV6_EXT(VCLKCR1, 0, /* didn't care bit[6-7] */
|
||||
div6_parents, ARRAY_SIZE(div6_parents), 12, 3),
|
||||
[DIV6_VCK2] = SH_CLK_MAP_DIV6_EXT(VCLKCR2, 0, /* didn't care bit[6-7] */
|
||||
div6_parents, ARRAY_SIZE(div6_parents), 12, 3),
|
||||
[DIV6_VCK3] = SH_CLK_MAP_DIV6_EXT(VCLKCR3, 0, /* didn't care bit[6-7] */
|
||||
div6_parents, ARRAY_SIZE(div6_parents), 12, 3),
|
||||
[DIV6_VCK4] = SH_CLK_MAP_DIV6_EXT(VCLKCR4, 0, /* didn't care bit[6-7] */
|
||||
div6_parents, ARRAY_SIZE(div6_parents), 12, 3),
|
||||
[DIV6_VCK5] = SH_CLK_MAP_DIV6_EXT(VCLKCR5, 0, /* didn't care bit[6-7] */
|
||||
div6_parents, ARRAY_SIZE(div6_parents), 12, 3),
|
||||
[DIV6_FSIA] = SH_CLK_MAP_DIV6_EXT(FSIACKCR, 0,
|
||||
fsia_parents, ARRAY_SIZE(fsia_parents), 6, 2),
|
||||
[DIV6_FSIB] = SH_CLK_MAP_DIV6_EXT(FSIBCKCR, 0,
|
||||
fsib_parents, ARRAY_SIZE(fsib_parents), 6, 2),
|
||||
[DIV6_MP] = SH_CLK_MAP_DIV6_EXT(MPCKCR, 0, /* it needs bit[9-11] control */
|
||||
mp_parents, ARRAY_SIZE(mp_parents), 6, 2),
|
||||
/* pll2s will be selected always for M4 */
|
||||
[DIV6_M4] = SH_CLK_MAP_DIV6_EXT(M4CKCR, 0, /* it needs bit[9] control */
|
||||
m4_parents, ARRAY_SIZE(m4_parents), 6, 1),
|
||||
[DIV6_HSI] = SH_CLK_MAP_DIV6_EXT(HSICKCR, 0, /* it needs bit[9] control */
|
||||
hsi_parents, ARRAY_SIZE(hsi_parents), 6, 2),
|
||||
[DIV6_SPUV] = SH_CLK_MAP_DIV6_EXT(SPUVCKCR, 0,
|
||||
mp_parents, ARRAY_SIZE(mp_parents), 6, 2),
|
||||
};
|
||||
|
||||
/* MSTP */
|
||||
enum {
|
||||
MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203,
|
||||
MSTP522,
|
||||
|
@ -64,16 +353,52 @@ enum {
|
|||
};
|
||||
|
||||
static struct clk mstp_clks[MSTP_NR] = {
|
||||
[MSTP204] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 4, 0), /* SCIFA0 */
|
||||
[MSTP203] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 3, 0), /* SCIFA1 */
|
||||
[MSTP206] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 6, 0), /* SCIFB0 */
|
||||
[MSTP207] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 7, 0), /* SCIFB1 */
|
||||
[MSTP216] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 16, 0), /* SCIFB2 */
|
||||
[MSTP217] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 17, 0), /* SCIFB3 */
|
||||
[MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 4, 0), /* SCIFA0 */
|
||||
[MSTP203] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 3, 0), /* SCIFA1 */
|
||||
[MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 6, 0), /* SCIFB0 */
|
||||
[MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 7, 0), /* SCIFB1 */
|
||||
[MSTP216] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 16, 0), /* SCIFB2 */
|
||||
[MSTP217] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 17, 0), /* SCIFB3 */
|
||||
[MSTP522] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR5, 22, 0), /* Thermal */
|
||||
};
|
||||
|
||||
static struct clk_lookup lookups[] = {
|
||||
/* main clock */
|
||||
CLKDEV_CON_ID("extal1", &extal1_clk),
|
||||
CLKDEV_CON_ID("extal1_div2", &extal1_div2_clk),
|
||||
CLKDEV_CON_ID("extal2", &extal2_clk),
|
||||
CLKDEV_CON_ID("extal2_div2", &extal2_div2_clk),
|
||||
CLKDEV_CON_ID("extal2_div4", &extal2_div4_clk),
|
||||
CLKDEV_CON_ID("fsiack", &fsiack_clk),
|
||||
CLKDEV_CON_ID("fsibck", &fsibck_clk),
|
||||
|
||||
/* pll clock */
|
||||
CLKDEV_CON_ID("pll1", &pll1_clk),
|
||||
CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk),
|
||||
CLKDEV_CON_ID("pll2", &pll2_clk),
|
||||
CLKDEV_CON_ID("pll2s", &pll2s_clk),
|
||||
CLKDEV_CON_ID("pll2h", &pll2h_clk),
|
||||
|
||||
/* DIV6 */
|
||||
CLKDEV_CON_ID("zb", &div6_clks[DIV6_ZB]),
|
||||
CLKDEV_CON_ID("sdhi0", &div6_clks[DIV6_SDHI0]),
|
||||
CLKDEV_CON_ID("sdhi1", &div6_clks[DIV6_SDHI1]),
|
||||
CLKDEV_CON_ID("sdhi2", &div6_clks[DIV6_SDHI2]),
|
||||
CLKDEV_CON_ID("mmc0", &div6_clks[DIV6_MMC0]),
|
||||
CLKDEV_CON_ID("mmc1", &div6_clks[DIV6_MMC1]),
|
||||
CLKDEV_CON_ID("vck1", &div6_clks[DIV6_VCK1]),
|
||||
CLKDEV_CON_ID("vck2", &div6_clks[DIV6_VCK2]),
|
||||
CLKDEV_CON_ID("vck3", &div6_clks[DIV6_VCK3]),
|
||||
CLKDEV_CON_ID("vck4", &div6_clks[DIV6_VCK4]),
|
||||
CLKDEV_CON_ID("vck5", &div6_clks[DIV6_VCK5]),
|
||||
CLKDEV_CON_ID("fsia", &div6_clks[DIV6_FSIA]),
|
||||
CLKDEV_CON_ID("fsib", &div6_clks[DIV6_FSIB]),
|
||||
CLKDEV_CON_ID("mp", &div6_clks[DIV6_MP]),
|
||||
CLKDEV_CON_ID("m4", &div6_clks[DIV6_M4]),
|
||||
CLKDEV_CON_ID("hsi", &div6_clks[DIV6_HSI]),
|
||||
CLKDEV_CON_ID("spuv", &div6_clks[DIV6_SPUV]),
|
||||
|
||||
/* MSTP */
|
||||
CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
|
||||
CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]),
|
||||
CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]),
|
||||
|
@ -88,21 +413,39 @@ static struct clk_lookup lookups[] = {
|
|||
|
||||
void __init r8a73a4_clock_init(void)
|
||||
{
|
||||
void __iomem *cpg_base, *reg;
|
||||
void __iomem *reg;
|
||||
int k, ret = 0;
|
||||
u32 ckscr;
|
||||
|
||||
/* fix MPCLK to EXTAL2 for now.
|
||||
* this is needed until more detailed clock topology is supported
|
||||
*/
|
||||
cpg_base = ioremap_nocache(CPG_BASE, CPG_LEN);
|
||||
BUG_ON(!cpg_base);
|
||||
reg = cpg_base + (MPCKCR - CPG_BASE);
|
||||
iowrite32(ioread32(reg) | 1 << 7 | 0x0c, reg); /* set CKSEL */
|
||||
iounmap(cpg_base);
|
||||
reg = ioremap_nocache(CKSCR, PAGE_SIZE);
|
||||
BUG_ON(!reg);
|
||||
ckscr = ioread32(reg);
|
||||
iounmap(reg);
|
||||
|
||||
switch ((ckscr >> 28) & 0x3) {
|
||||
case 0:
|
||||
main_clk.parent = &extal1_clk;
|
||||
break;
|
||||
case 1:
|
||||
main_clk.parent = &extal1_div2_clk;
|
||||
break;
|
||||
case 2:
|
||||
main_clk.parent = &extal2_clk;
|
||||
break;
|
||||
case 3:
|
||||
main_clk.parent = &extal2_div2_clk;
|
||||
break;
|
||||
}
|
||||
|
||||
for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
|
||||
ret = clk_register(main_clks[k]);
|
||||
|
||||
if (!ret)
|
||||
ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
|
||||
|
||||
if (!ret)
|
||||
ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
|
||||
|
||||
if (!ret)
|
||||
ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
|
||||
|
||||
|
|
|
@ -266,7 +266,7 @@ static struct clk fsiack_clk = {
|
|||
static struct clk fsibck_clk = {
|
||||
};
|
||||
|
||||
struct clk *main_clks[] = {
|
||||
static struct clk *main_clks[] = {
|
||||
&extalr_clk,
|
||||
&extal1_clk,
|
||||
&extal2_clk,
|
||||
|
@ -317,7 +317,7 @@ enum {
|
|||
DIV4_NR
|
||||
};
|
||||
|
||||
struct clk div4_clks[DIV4_NR] = {
|
||||
static struct clk div4_clks[DIV4_NR] = {
|
||||
[DIV4_I] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
|
||||
[DIV4_ZG] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
|
||||
[DIV4_B] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT),
|
||||
|
@ -461,7 +461,7 @@ enum {
|
|||
|
||||
MSTP329, MSTP328, MSTP323, MSTP320,
|
||||
MSTP314, MSTP313, MSTP312,
|
||||
MSTP309,
|
||||
MSTP309, MSTP304,
|
||||
|
||||
MSTP416, MSTP415, MSTP407, MSTP406,
|
||||
|
||||
|
@ -499,6 +499,7 @@ static struct clk mstp_clks[MSTP_NR] = {
|
|||
[MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
|
||||
[MSTP312] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
|
||||
[MSTP309] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 9, 0), /* GEther */
|
||||
[MSTP304] = SH_CLK_MSTP32(&div4_clks[DIV4_CP], SMSTPCR3, 4, 0), /* TPU0 */
|
||||
|
||||
[MSTP416] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 16, 0), /* USBHOST */
|
||||
[MSTP415] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
|
||||
|
@ -551,6 +552,7 @@ static struct clk_lookup lookups[] = {
|
|||
CLKDEV_DEV_ID("sh_tmu.4", &mstp_clks[MSTP111]),
|
||||
CLKDEV_DEV_ID("sh_tmu.5", &mstp_clks[MSTP111]),
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]),
|
||||
CLKDEV_DEV_ID("fff20000.i2c", &mstp_clks[MSTP116]),
|
||||
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]),
|
||||
CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]),
|
||||
CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]),
|
||||
|
@ -584,6 +586,7 @@ static struct clk_lookup lookups[] = {
|
|||
CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]),
|
||||
CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]),
|
||||
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]),
|
||||
CLKDEV_DEV_ID("e6c20000.i2c", &mstp_clks[MSTP323]),
|
||||
CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP320]),
|
||||
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
|
||||
CLKDEV_DEV_ID("e6850000.sdhi", &mstp_clks[MSTP314]),
|
||||
|
@ -592,6 +595,8 @@ static struct clk_lookup lookups[] = {
|
|||
CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP312]),
|
||||
CLKDEV_DEV_ID("e6bd0000.mmcif", &mstp_clks[MSTP312]),
|
||||
CLKDEV_DEV_ID("sh-eth", &mstp_clks[MSTP309]),
|
||||
CLKDEV_DEV_ID("e9a00000.sh-eth", &mstp_clks[MSTP309]),
|
||||
CLKDEV_DEV_ID("renesas_tpu_pwm", &mstp_clks[MSTP304]),
|
||||
|
||||
CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]),
|
||||
CLKDEV_DEV_ID("e6870000.sdhi", &mstp_clks[MSTP415]),
|
||||
|
|
|
@ -23,9 +23,23 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* MD MD MD MD PLLA PLLB EXTAL clki clkz
|
||||
* 19 18 12 11 (HMz) (MHz) (MHz)
|
||||
*----------------------------------------------------------------------------
|
||||
* 1 0 0 0 x21 x21 38.00 800 800
|
||||
* 1 0 0 1 x24 x24 33.33 800 800
|
||||
* 1 0 1 0 x28 x28 28.50 800 800
|
||||
* 1 0 1 1 x32 x32 25.00 800 800
|
||||
* 1 1 0 1 x24 x21 33.33 800 700
|
||||
* 1 1 1 0 x28 x21 28.50 800 600
|
||||
* 1 1 1 1 x32 x24 25.00 800 600
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/sh_clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <mach/clock.h>
|
||||
#include <mach/common.h>
|
||||
|
||||
#define MSTPCR0 IOMEM(0xffc80030)
|
||||
|
@ -37,6 +51,9 @@
|
|||
#define MSTPCR4 IOMEM(0xffc80050)
|
||||
#define MSTPCR5 IOMEM(0xffc80054)
|
||||
#define MSTPCR6 IOMEM(0xffc80058)
|
||||
#define MODEMR 0xFFCC0020
|
||||
|
||||
#define MD(nr) BIT(nr)
|
||||
|
||||
/* ioremap() through clock mapping mandatory to avoid
|
||||
* collision with ARM coherent DMA virtual memory range.
|
||||
|
@ -47,36 +64,71 @@ static struct clk_mapping cpg_mapping = {
|
|||
.len = 0x80,
|
||||
};
|
||||
|
||||
static struct clk clkp = {
|
||||
.rate = 62500000, /* FIXME: shortcut */
|
||||
.flags = CLK_ENABLE_ON_INIT,
|
||||
static struct clk extal_clk = {
|
||||
/* .rate will be updated on r8a7778_clock_init() */
|
||||
.mapping = &cpg_mapping,
|
||||
};
|
||||
|
||||
/*
|
||||
* clock ratio of these clock will be updated
|
||||
* on r8a7778_clock_init()
|
||||
*/
|
||||
SH_FIXED_RATIO_CLK_SET(plla_clk, extal_clk, 1, 1);
|
||||
SH_FIXED_RATIO_CLK_SET(pllb_clk, extal_clk, 1, 1);
|
||||
SH_FIXED_RATIO_CLK_SET(i_clk, plla_clk, 1, 1);
|
||||
SH_FIXED_RATIO_CLK_SET(s_clk, plla_clk, 1, 1);
|
||||
SH_FIXED_RATIO_CLK_SET(s1_clk, plla_clk, 1, 1);
|
||||
SH_FIXED_RATIO_CLK_SET(s3_clk, plla_clk, 1, 1);
|
||||
SH_FIXED_RATIO_CLK_SET(s4_clk, plla_clk, 1, 1);
|
||||
SH_FIXED_RATIO_CLK_SET(b_clk, plla_clk, 1, 1);
|
||||
SH_FIXED_RATIO_CLK_SET(out_clk, plla_clk, 1, 1);
|
||||
SH_FIXED_RATIO_CLK_SET(p_clk, plla_clk, 1, 1);
|
||||
SH_FIXED_RATIO_CLK_SET(g_clk, plla_clk, 1, 1);
|
||||
SH_FIXED_RATIO_CLK_SET(z_clk, pllb_clk, 1, 1);
|
||||
|
||||
static struct clk *main_clks[] = {
|
||||
&clkp,
|
||||
&extal_clk,
|
||||
&plla_clk,
|
||||
&pllb_clk,
|
||||
&i_clk,
|
||||
&s_clk,
|
||||
&s1_clk,
|
||||
&s3_clk,
|
||||
&s4_clk,
|
||||
&b_clk,
|
||||
&out_clk,
|
||||
&p_clk,
|
||||
&g_clk,
|
||||
&z_clk,
|
||||
};
|
||||
|
||||
enum {
|
||||
MSTP323, MSTP322, MSTP321,
|
||||
MSTP114,
|
||||
MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
|
||||
MSTP016, MSTP015,
|
||||
MSTP_NR };
|
||||
|
||||
static struct clk mstp_clks[MSTP_NR] = {
|
||||
[MSTP114] = SH_CLK_MSTP32(&clkp, MSTPCR1, 14, 0), /* Ether */
|
||||
[MSTP026] = SH_CLK_MSTP32(&clkp, MSTPCR0, 26, 0), /* SCIF0 */
|
||||
[MSTP025] = SH_CLK_MSTP32(&clkp, MSTPCR0, 25, 0), /* SCIF1 */
|
||||
[MSTP024] = SH_CLK_MSTP32(&clkp, MSTPCR0, 24, 0), /* SCIF2 */
|
||||
[MSTP023] = SH_CLK_MSTP32(&clkp, MSTPCR0, 23, 0), /* SCIF3 */
|
||||
[MSTP022] = SH_CLK_MSTP32(&clkp, MSTPCR0, 22, 0), /* SCIF4 */
|
||||
[MSTP021] = SH_CLK_MSTP32(&clkp, MSTPCR0, 21, 0), /* SCIF5 */
|
||||
[MSTP016] = SH_CLK_MSTP32(&clkp, MSTPCR0, 16, 0), /* TMU0 */
|
||||
[MSTP015] = SH_CLK_MSTP32(&clkp, MSTPCR0, 15, 0), /* TMU1 */
|
||||
[MSTP323] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 23, 0), /* SDHI0 */
|
||||
[MSTP322] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 22, 0), /* SDHI1 */
|
||||
[MSTP321] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 21, 0), /* SDHI2 */
|
||||
[MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */
|
||||
[MSTP026] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 26, 0), /* SCIF0 */
|
||||
[MSTP025] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 25, 0), /* SCIF1 */
|
||||
[MSTP024] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 24, 0), /* SCIF2 */
|
||||
[MSTP023] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 23, 0), /* SCIF3 */
|
||||
[MSTP022] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 22, 0), /* SCIF4 */
|
||||
[MSTP021] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 21, 0), /* SCIF5 */
|
||||
[MSTP016] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 16, 0), /* TMU0 */
|
||||
[MSTP015] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 15, 0), /* TMU1 */
|
||||
};
|
||||
|
||||
static struct clk_lookup lookups[] = {
|
||||
/* MSTP32 clocks */
|
||||
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP323]), /* SDHI0 */
|
||||
CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */
|
||||
CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */
|
||||
CLKDEV_DEV_ID("sh-eth", &mstp_clks[MSTP114]), /* Ether */
|
||||
CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
|
||||
CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
|
||||
|
@ -90,8 +142,86 @@ static struct clk_lookup lookups[] = {
|
|||
|
||||
void __init r8a7778_clock_init(void)
|
||||
{
|
||||
void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
|
||||
u32 mode;
|
||||
int k, ret = 0;
|
||||
|
||||
BUG_ON(!modemr);
|
||||
mode = ioread32(modemr);
|
||||
iounmap(modemr);
|
||||
|
||||
switch (mode & (MD(19) | MD(18) | MD(12) | MD(11))) {
|
||||
case MD(19):
|
||||
extal_clk.rate = 38000000;
|
||||
SH_CLK_SET_RATIO(&plla_clk_ratio, 21, 1);
|
||||
SH_CLK_SET_RATIO(&pllb_clk_ratio, 21, 1);
|
||||
break;
|
||||
case MD(19) | MD(11):
|
||||
extal_clk.rate = 33333333;
|
||||
SH_CLK_SET_RATIO(&plla_clk_ratio, 24, 1);
|
||||
SH_CLK_SET_RATIO(&pllb_clk_ratio, 24, 1);
|
||||
break;
|
||||
case MD(19) | MD(12):
|
||||
extal_clk.rate = 28500000;
|
||||
SH_CLK_SET_RATIO(&plla_clk_ratio, 28, 1);
|
||||
SH_CLK_SET_RATIO(&pllb_clk_ratio, 28, 1);
|
||||
break;
|
||||
case MD(19) | MD(12) | MD(11):
|
||||
extal_clk.rate = 25000000;
|
||||
SH_CLK_SET_RATIO(&plla_clk_ratio, 32, 1);
|
||||
SH_CLK_SET_RATIO(&pllb_clk_ratio, 32, 1);
|
||||
break;
|
||||
case MD(19) | MD(18) | MD(11):
|
||||
extal_clk.rate = 33333333;
|
||||
SH_CLK_SET_RATIO(&plla_clk_ratio, 24, 1);
|
||||
SH_CLK_SET_RATIO(&pllb_clk_ratio, 21, 1);
|
||||
break;
|
||||
case MD(19) | MD(18) | MD(12):
|
||||
extal_clk.rate = 28500000;
|
||||
SH_CLK_SET_RATIO(&plla_clk_ratio, 28, 1);
|
||||
SH_CLK_SET_RATIO(&pllb_clk_ratio, 21, 1);
|
||||
break;
|
||||
case MD(19) | MD(18) | MD(12) | MD(11):
|
||||
extal_clk.rate = 25000000;
|
||||
SH_CLK_SET_RATIO(&plla_clk_ratio, 32, 1);
|
||||
SH_CLK_SET_RATIO(&pllb_clk_ratio, 24, 1);
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
if (mode & MD(1)) {
|
||||
SH_CLK_SET_RATIO(&i_clk_ratio, 1, 1);
|
||||
SH_CLK_SET_RATIO(&s_clk_ratio, 1, 3);
|
||||
SH_CLK_SET_RATIO(&s1_clk_ratio, 1, 6);
|
||||
SH_CLK_SET_RATIO(&s3_clk_ratio, 1, 4);
|
||||
SH_CLK_SET_RATIO(&s4_clk_ratio, 1, 8);
|
||||
SH_CLK_SET_RATIO(&p_clk_ratio, 1, 12);
|
||||
SH_CLK_SET_RATIO(&g_clk_ratio, 1, 12);
|
||||
if (mode & MD(2)) {
|
||||
SH_CLK_SET_RATIO(&b_clk_ratio, 1, 18);
|
||||
SH_CLK_SET_RATIO(&out_clk_ratio, 1, 18);
|
||||
} else {
|
||||
SH_CLK_SET_RATIO(&b_clk_ratio, 1, 12);
|
||||
SH_CLK_SET_RATIO(&out_clk_ratio, 1, 12);
|
||||
}
|
||||
} else {
|
||||
SH_CLK_SET_RATIO(&i_clk_ratio, 1, 1);
|
||||
SH_CLK_SET_RATIO(&s_clk_ratio, 1, 4);
|
||||
SH_CLK_SET_RATIO(&s1_clk_ratio, 1, 8);
|
||||
SH_CLK_SET_RATIO(&s3_clk_ratio, 1, 4);
|
||||
SH_CLK_SET_RATIO(&s4_clk_ratio, 1, 8);
|
||||
SH_CLK_SET_RATIO(&p_clk_ratio, 1, 16);
|
||||
SH_CLK_SET_RATIO(&g_clk_ratio, 1, 12);
|
||||
if (mode & MD(2)) {
|
||||
SH_CLK_SET_RATIO(&b_clk_ratio, 1, 16);
|
||||
SH_CLK_SET_RATIO(&out_clk_ratio, 1, 16);
|
||||
} else {
|
||||
SH_CLK_SET_RATIO(&b_clk_ratio, 1, 12);
|
||||
SH_CLK_SET_RATIO(&out_clk_ratio, 1, 12);
|
||||
}
|
||||
}
|
||||
|
||||
for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
|
||||
ret = clk_register(main_clks[k]);
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ static struct clk *main_clks[] = {
|
|||
};
|
||||
|
||||
enum { MSTP323, MSTP322, MSTP321, MSTP320,
|
||||
MSTP115, MSTP114,
|
||||
MSTP116, MSTP115, MSTP114,
|
||||
MSTP103, MSTP101, MSTP100,
|
||||
MSTP030,
|
||||
MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
|
||||
|
@ -125,6 +125,7 @@ static struct clk mstp_clks[MSTP_NR] = {
|
|||
[MSTP322] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 22, 0), /* SDHI1 */
|
||||
[MSTP321] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 21, 0), /* SDHI2 */
|
||||
[MSTP320] = SH_CLK_MSTP32(&clkp_clk, MSTPCR3, 20, 0), /* SDHI3 */
|
||||
[MSTP116] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 16, 0), /* PCIe */
|
||||
[MSTP115] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 15, 0), /* SATA */
|
||||
[MSTP114] = SH_CLK_MSTP32(&clkp_clk, MSTPCR1, 14, 0), /* Ether */
|
||||
[MSTP103] = SH_CLK_MSTP32(&clks_clk, MSTPCR1, 3, 0), /* DU */
|
||||
|
@ -161,6 +162,7 @@ static struct clk_lookup lookups[] = {
|
|||
CLKDEV_CON_ID("peripheral_clk", &clkp_clk),
|
||||
|
||||
/* MSTP32 clocks */
|
||||
CLKDEV_DEV_ID("rcar-pcie", &mstp_clks[MSTP116]), /* PCIe */
|
||||
CLKDEV_DEV_ID("sata_rcar", &mstp_clks[MSTP115]), /* SATA */
|
||||
CLKDEV_DEV_ID("fc600000.sata", &mstp_clks[MSTP115]), /* SATA w/DT */
|
||||
CLKDEV_DEV_ID("sh-eth", &mstp_clks[MSTP114]), /* Ether */
|
||||
|
|
|
@ -22,39 +22,174 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/sh_clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <mach/clock.h>
|
||||
#include <mach/common.h>
|
||||
|
||||
/*
|
||||
* MD EXTAL PLL0 PLL1 PLL3
|
||||
* 14 13 19 (MHz) *1 *1
|
||||
*---------------------------------------------------
|
||||
* 0 0 0 15 x 1 x172/2 x208/2 x106
|
||||
* 0 0 1 15 x 1 x172/2 x208/2 x88
|
||||
* 0 1 0 20 x 1 x130/2 x156/2 x80
|
||||
* 0 1 1 20 x 1 x130/2 x156/2 x66
|
||||
* 1 0 0 26 / 2 x200/2 x240/2 x122
|
||||
* 1 0 1 26 / 2 x200/2 x240/2 x102
|
||||
* 1 1 0 30 / 2 x172/2 x208/2 x106
|
||||
* 1 1 1 30 / 2 x172/2 x208/2 x88
|
||||
*
|
||||
* *1 : Table 7.6 indicates VCO ouput (PLLx = VCO/2)
|
||||
* see "p1 / 2" on R8A7790_CLOCK_ROOT() below
|
||||
*/
|
||||
|
||||
#define MD(nr) (1 << nr)
|
||||
|
||||
#define CPG_BASE 0xe6150000
|
||||
#define CPG_LEN 0x1000
|
||||
|
||||
#define SMSTPCR2 0xe6150138
|
||||
#define SMSTPCR3 0xe615013c
|
||||
#define SMSTPCR7 0xe615014c
|
||||
|
||||
#define MODEMR 0xE6160060
|
||||
#define SDCKCR 0xE6150074
|
||||
#define SD2CKCR 0xE6150078
|
||||
#define SD3CKCR 0xE615007C
|
||||
#define MMC0CKCR 0xE6150240
|
||||
#define MMC1CKCR 0xE6150244
|
||||
#define SSPCKCR 0xE6150248
|
||||
#define SSPRSCKCR 0xE615024C
|
||||
|
||||
static struct clk_mapping cpg_mapping = {
|
||||
.phys = CPG_BASE,
|
||||
.len = CPG_LEN,
|
||||
};
|
||||
|
||||
static struct clk p_clk = {
|
||||
.rate = 65000000, /* shortcut for now */
|
||||
static struct clk extal_clk = {
|
||||
/* .rate will be updated on r8a7790_clock_init() */
|
||||
.mapping = &cpg_mapping,
|
||||
};
|
||||
|
||||
static struct clk mp_clk = {
|
||||
.rate = 52000000, /* shortcut for now */
|
||||
.mapping = &cpg_mapping,
|
||||
static struct sh_clk_ops followparent_clk_ops = {
|
||||
.recalc = followparent_recalc,
|
||||
};
|
||||
|
||||
static struct clk main_clk = {
|
||||
/* .parent will be set r8a73a4_clock_init */
|
||||
.ops = &followparent_clk_ops,
|
||||
};
|
||||
|
||||
/*
|
||||
* clock ratio of these clock will be updated
|
||||
* on r8a7790_clock_init()
|
||||
*/
|
||||
SH_FIXED_RATIO_CLK_SET(pll1_clk, main_clk, 1, 1);
|
||||
SH_FIXED_RATIO_CLK_SET(pll3_clk, main_clk, 1, 1);
|
||||
SH_FIXED_RATIO_CLK_SET(lb_clk, pll1_clk, 1, 1);
|
||||
SH_FIXED_RATIO_CLK_SET(qspi_clk, pll1_clk, 1, 1);
|
||||
|
||||
/* fixed ratio clock */
|
||||
SH_FIXED_RATIO_CLK_SET(extal_div2_clk, extal_clk, 1, 2);
|
||||
SH_FIXED_RATIO_CLK_SET(cp_clk, extal_clk, 1, 2);
|
||||
|
||||
SH_FIXED_RATIO_CLK_SET(pll1_div2_clk, pll1_clk, 1, 2);
|
||||
SH_FIXED_RATIO_CLK_SET(zg_clk, pll1_clk, 1, 3);
|
||||
SH_FIXED_RATIO_CLK_SET(zx_clk, pll1_clk, 1, 3);
|
||||
SH_FIXED_RATIO_CLK_SET(zs_clk, pll1_clk, 1, 6);
|
||||
SH_FIXED_RATIO_CLK_SET(hp_clk, pll1_clk, 1, 12);
|
||||
SH_FIXED_RATIO_CLK_SET(i_clk, pll1_clk, 1, 2);
|
||||
SH_FIXED_RATIO_CLK_SET(b_clk, pll1_clk, 1, 12);
|
||||
SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24);
|
||||
SH_FIXED_RATIO_CLK_SET(cl_clk, pll1_clk, 1, 48);
|
||||
SH_FIXED_RATIO_CLK_SET(m2_clk, pll1_clk, 1, 8);
|
||||
SH_FIXED_RATIO_CLK_SET(imp_clk, pll1_clk, 1, 4);
|
||||
SH_FIXED_RATIO_CLK_SET(rclk_clk, pll1_clk, 1, (48 * 1024));
|
||||
SH_FIXED_RATIO_CLK_SET(oscclk_clk, pll1_clk, 1, (12 * 1024));
|
||||
|
||||
SH_FIXED_RATIO_CLK_SET(zb3_clk, pll3_clk, 1, 4);
|
||||
SH_FIXED_RATIO_CLK_SET(zb3d2_clk, pll3_clk, 1, 8);
|
||||
SH_FIXED_RATIO_CLK_SET(ddr_clk, pll3_clk, 1, 8);
|
||||
SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15);
|
||||
|
||||
static struct clk *main_clks[] = {
|
||||
&extal_clk,
|
||||
&extal_div2_clk,
|
||||
&main_clk,
|
||||
&pll1_clk,
|
||||
&pll1_div2_clk,
|
||||
&pll3_clk,
|
||||
&lb_clk,
|
||||
&qspi_clk,
|
||||
&zg_clk,
|
||||
&zx_clk,
|
||||
&zs_clk,
|
||||
&hp_clk,
|
||||
&i_clk,
|
||||
&b_clk,
|
||||
&p_clk,
|
||||
&cl_clk,
|
||||
&m2_clk,
|
||||
&imp_clk,
|
||||
&rclk_clk,
|
||||
&oscclk_clk,
|
||||
&zb3_clk,
|
||||
&zb3d2_clk,
|
||||
&ddr_clk,
|
||||
&mp_clk,
|
||||
&cp_clk,
|
||||
};
|
||||
|
||||
/* SDHI (DIV4) clock */
|
||||
static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10 };
|
||||
|
||||
static struct clk_div_mult_table div4_div_mult_table = {
|
||||
.divisors = divisors,
|
||||
.nr_divisors = ARRAY_SIZE(divisors),
|
||||
};
|
||||
|
||||
static struct clk_div4_table div4_table = {
|
||||
.div_mult_table = &div4_div_mult_table,
|
||||
};
|
||||
|
||||
enum {
|
||||
DIV4_SDH, DIV4_SD0, DIV4_SD1, DIV4_NR
|
||||
};
|
||||
|
||||
static struct clk div4_clks[DIV4_NR] = {
|
||||
[DIV4_SDH] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 8, 0x0dff, CLK_ENABLE_ON_INIT),
|
||||
[DIV4_SD0] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 4, 0x1de0, CLK_ENABLE_ON_INIT),
|
||||
[DIV4_SD1] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 0, 0x1de0, CLK_ENABLE_ON_INIT),
|
||||
};
|
||||
|
||||
/* DIV6 clocks */
|
||||
enum {
|
||||
DIV6_SD2, DIV6_SD3,
|
||||
DIV6_MMC0, DIV6_MMC1,
|
||||
DIV6_SSP, DIV6_SSPRS,
|
||||
DIV6_NR
|
||||
};
|
||||
|
||||
static struct clk div6_clks[DIV6_NR] = {
|
||||
[DIV6_SD2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0),
|
||||
[DIV6_SD3] = SH_CLK_DIV6(&pll1_div2_clk, SD3CKCR, 0),
|
||||
[DIV6_MMC0] = SH_CLK_DIV6(&pll1_div2_clk, MMC0CKCR, 0),
|
||||
[DIV6_MMC1] = SH_CLK_DIV6(&pll1_div2_clk, MMC1CKCR, 0),
|
||||
[DIV6_SSP] = SH_CLK_DIV6(&pll1_div2_clk, SSPCKCR, 0),
|
||||
[DIV6_SSPRS] = SH_CLK_DIV6(&pll1_div2_clk, SSPRSCKCR, 0),
|
||||
};
|
||||
|
||||
/* MSTP */
|
||||
enum {
|
||||
MSTP721, MSTP720,
|
||||
MSTP304,
|
||||
MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202,
|
||||
MSTP_NR
|
||||
};
|
||||
|
||||
enum { MSTP721, MSTP720,
|
||||
MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP_NR };
|
||||
static struct clk mstp_clks[MSTP_NR] = {
|
||||
[MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */
|
||||
[MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */
|
||||
[MSTP304] = SH_CLK_MSTP32(&cp_clk, SMSTPCR3, 4, 0), /* TPU0 */
|
||||
[MSTP216] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 16, 0), /* SCIFB2 */
|
||||
[MSTP207] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 7, 0), /* SCIFB1 */
|
||||
[MSTP206] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 6, 0), /* SCIFB0 */
|
||||
|
@ -64,6 +199,48 @@ static struct clk mstp_clks[MSTP_NR] = {
|
|||
};
|
||||
|
||||
static struct clk_lookup lookups[] = {
|
||||
|
||||
/* main clocks */
|
||||
CLKDEV_CON_ID("extal", &extal_clk),
|
||||
CLKDEV_CON_ID("extal_div2", &extal_div2_clk),
|
||||
CLKDEV_CON_ID("main", &main_clk),
|
||||
CLKDEV_CON_ID("pll1", &pll1_clk),
|
||||
CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk),
|
||||
CLKDEV_CON_ID("pll3", &pll3_clk),
|
||||
CLKDEV_CON_ID("zg", &zg_clk),
|
||||
CLKDEV_CON_ID("zx", &zx_clk),
|
||||
CLKDEV_CON_ID("zs", &zs_clk),
|
||||
CLKDEV_CON_ID("hp", &hp_clk),
|
||||
CLKDEV_CON_ID("i", &i_clk),
|
||||
CLKDEV_CON_ID("b", &b_clk),
|
||||
CLKDEV_CON_ID("lb", &lb_clk),
|
||||
CLKDEV_CON_ID("p", &p_clk),
|
||||
CLKDEV_CON_ID("cl", &cl_clk),
|
||||
CLKDEV_CON_ID("m2", &m2_clk),
|
||||
CLKDEV_CON_ID("imp", &imp_clk),
|
||||
CLKDEV_CON_ID("rclk", &rclk_clk),
|
||||
CLKDEV_CON_ID("oscclk", &oscclk_clk),
|
||||
CLKDEV_CON_ID("zb3", &zb3_clk),
|
||||
CLKDEV_CON_ID("zb3d2", &zb3d2_clk),
|
||||
CLKDEV_CON_ID("ddr", &ddr_clk),
|
||||
CLKDEV_CON_ID("mp", &mp_clk),
|
||||
CLKDEV_CON_ID("qspi", &qspi_clk),
|
||||
CLKDEV_CON_ID("cp", &cp_clk),
|
||||
|
||||
/* DIV4 */
|
||||
CLKDEV_CON_ID("sdh", &div4_clks[DIV4_SDH]),
|
||||
CLKDEV_CON_ID("sd0", &div4_clks[DIV4_SD0]),
|
||||
CLKDEV_CON_ID("sd1", &div4_clks[DIV4_SD1]),
|
||||
|
||||
/* DIV6 */
|
||||
CLKDEV_CON_ID("sd2", &div6_clks[DIV6_SD2]),
|
||||
CLKDEV_CON_ID("sd3", &div6_clks[DIV6_SD3]),
|
||||
CLKDEV_CON_ID("mmc0", &div6_clks[DIV6_MMC0]),
|
||||
CLKDEV_CON_ID("mmc1", &div6_clks[DIV6_MMC1]),
|
||||
CLKDEV_CON_ID("ssp", &div6_clks[DIV6_SSP]),
|
||||
CLKDEV_CON_ID("ssprs", &div6_clks[DIV6_SSPRS]),
|
||||
|
||||
/* MSTP */
|
||||
CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
|
||||
CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]),
|
||||
CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]),
|
||||
|
@ -74,13 +251,60 @@ static struct clk_lookup lookups[] = {
|
|||
CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]),
|
||||
};
|
||||
|
||||
#define R8A7790_CLOCK_ROOT(e, m, p0, p1, p30, p31) \
|
||||
extal_clk.rate = e * 1000 * 1000; \
|
||||
main_clk.parent = m; \
|
||||
SH_CLK_SET_RATIO(&pll1_clk_ratio, p1 / 2, 1); \
|
||||
if (mode & MD(19)) \
|
||||
SH_CLK_SET_RATIO(&pll3_clk_ratio, p31, 1); \
|
||||
else \
|
||||
SH_CLK_SET_RATIO(&pll3_clk_ratio, p30, 1)
|
||||
|
||||
|
||||
void __init r8a7790_clock_init(void)
|
||||
{
|
||||
void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
|
||||
u32 mode;
|
||||
int k, ret = 0;
|
||||
|
||||
BUG_ON(!modemr);
|
||||
mode = ioread32(modemr);
|
||||
iounmap(modemr);
|
||||
|
||||
switch (mode & (MD(14) | MD(13))) {
|
||||
case 0:
|
||||
R8A7790_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88);
|
||||
break;
|
||||
case MD(13):
|
||||
R8A7790_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66);
|
||||
break;
|
||||
case MD(14):
|
||||
R8A7790_CLOCK_ROOT(26, &extal_div2_clk, 200, 240, 122, 102);
|
||||
break;
|
||||
case MD(13) | MD(14):
|
||||
R8A7790_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88);
|
||||
break;
|
||||
}
|
||||
|
||||
if (mode & (MD(18)))
|
||||
SH_CLK_SET_RATIO(&lb_clk_ratio, 1, 36);
|
||||
else
|
||||
SH_CLK_SET_RATIO(&lb_clk_ratio, 1, 24);
|
||||
|
||||
if ((mode & (MD(3) | MD(2) | MD(1))) == MD(2))
|
||||
SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 16);
|
||||
else
|
||||
SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 20);
|
||||
|
||||
for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
|
||||
ret = clk_register(main_clks[k]);
|
||||
|
||||
if (!ret)
|
||||
ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
|
||||
|
||||
if (!ret)
|
||||
ret = sh_clk_div6_register(div6_clks, DIV6_NR);
|
||||
|
||||
if (!ret)
|
||||
ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
|
||||
|
||||
|
|
|
@ -228,6 +228,11 @@ enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
|
|||
|
||||
static struct clk div4_clks[DIV4_NR] = {
|
||||
[DIV4_I] = DIV4(FRQCRA, 20, 0xdff, CLK_ENABLE_ON_INIT),
|
||||
/*
|
||||
* ZG clock is dividing PLL0 frequency to supply SGX. Make sure not to
|
||||
* exceed maximum frequencies of 201.5MHz for VDD_DVFS=1.175 and
|
||||
* 239.2MHz for VDD_DVFS=1.315V.
|
||||
*/
|
||||
[DIV4_ZG] = SH_CLK_DIV4(&pll0_clk, FRQCRA, 16, 0xd7f, CLK_ENABLE_ON_INIT),
|
||||
[DIV4_M3] = DIV4(FRQCRA, 12, 0x1dff, CLK_ENABLE_ON_INIT),
|
||||
[DIV4_B] = DIV4(FRQCRA, 8, 0xdff, CLK_ENABLE_ON_INIT),
|
||||
|
@ -252,6 +257,101 @@ static struct clk twd_clk = {
|
|||
.ops = &twd_clk_ops,
|
||||
};
|
||||
|
||||
static struct sh_clk_ops zclk_ops, kicker_ops;
|
||||
static const struct sh_clk_ops *div4_clk_ops;
|
||||
|
||||
static int zclk_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!clk->parent || !__clk_get(clk->parent))
|
||||
return -ENODEV;
|
||||
|
||||
if (readl(FRQCRB) & (1 << 31))
|
||||
return -EBUSY;
|
||||
|
||||
if (rate == clk_get_rate(clk->parent)) {
|
||||
/* 1:1 - switch off divider */
|
||||
__raw_writel(__raw_readl(FRQCRB) & ~(1 << 28), FRQCRB);
|
||||
/* nullify the divider to prepare for the next time */
|
||||
ret = div4_clk_ops->set_rate(clk, rate / 2);
|
||||
if (!ret)
|
||||
ret = frqcr_kick();
|
||||
if (ret > 0)
|
||||
ret = 0;
|
||||
} else {
|
||||
/* Enable the divider */
|
||||
__raw_writel(__raw_readl(FRQCRB) | (1 << 28), FRQCRB);
|
||||
|
||||
ret = frqcr_kick();
|
||||
if (ret >= 0)
|
||||
/*
|
||||
* set the divider - call the DIV4 method, it will kick
|
||||
* FRQCRB too
|
||||
*/
|
||||
ret = div4_clk_ops->set_rate(clk, rate);
|
||||
if (ret < 0)
|
||||
goto esetrate;
|
||||
}
|
||||
|
||||
esetrate:
|
||||
__clk_put(clk->parent);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long zclk_round_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
unsigned long div_freq = div4_clk_ops->round_rate(clk, rate),
|
||||
parent_freq = clk_get_rate(clk->parent);
|
||||
|
||||
if (rate > div_freq && abs(parent_freq - rate) < rate - div_freq)
|
||||
return parent_freq;
|
||||
|
||||
return div_freq;
|
||||
}
|
||||
|
||||
static unsigned long zclk_recalc(struct clk *clk)
|
||||
{
|
||||
/*
|
||||
* Must recalculate frequencies in case PLL0 has been changed, even if
|
||||
* the divisor is unused ATM!
|
||||
*/
|
||||
unsigned long div_freq = div4_clk_ops->recalc(clk);
|
||||
|
||||
if (__raw_readl(FRQCRB) & (1 << 28))
|
||||
return div_freq;
|
||||
|
||||
return clk_get_rate(clk->parent);
|
||||
}
|
||||
|
||||
static int kicker_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
if (__raw_readl(FRQCRB) & (1 << 31))
|
||||
return -EBUSY;
|
||||
|
||||
return div4_clk_ops->set_rate(clk, rate);
|
||||
}
|
||||
|
||||
static void div4_clk_extend(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
div4_clk_ops = div4_clks[0].ops;
|
||||
|
||||
/* Add a kicker-busy check before changing the rate */
|
||||
kicker_ops = *div4_clk_ops;
|
||||
/* We extend the DIV4 clock with a 1:1 pass-through case */
|
||||
zclk_ops = *div4_clk_ops;
|
||||
|
||||
kicker_ops.set_rate = kicker_set_rate;
|
||||
zclk_ops.set_rate = zclk_set_rate;
|
||||
zclk_ops.round_rate = zclk_round_rate;
|
||||
zclk_ops.recalc = zclk_recalc;
|
||||
|
||||
for (i = 0; i < DIV4_NR; i++)
|
||||
div4_clks[i].ops = i == DIV4_Z ? &zclk_ops : &kicker_ops;
|
||||
}
|
||||
|
||||
enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
|
||||
DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
|
||||
DIV6_FSIA, DIV6_FSIB, DIV6_SUB,
|
||||
|
@ -450,7 +550,7 @@ static struct clk *late_main_clks[] = {
|
|||
};
|
||||
|
||||
enum { MSTP001,
|
||||
MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
|
||||
MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP112, MSTP100,
|
||||
MSTP219, MSTP218, MSTP217,
|
||||
MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
|
||||
MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP322,
|
||||
|
@ -471,6 +571,7 @@ static struct clk mstp_clks[MSTP_NR] = {
|
|||
[MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
|
||||
[MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX0 */
|
||||
[MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0), /* IIC0 */
|
||||
[MSTP112] = MSTP(&div4_clks[DIV4_ZG], SMSTPCR1, 12, 0), /* SGX */
|
||||
[MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
|
||||
[MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
|
||||
[MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */
|
||||
|
@ -513,6 +614,9 @@ static struct clk_lookup lookups[] = {
|
|||
CLKDEV_CON_ID("r_clk", &r_clk),
|
||||
CLKDEV_DEV_ID("smp_twd", &twd_clk), /* smp_twd */
|
||||
|
||||
/* DIV4 clocks */
|
||||
CLKDEV_DEV_ID("cpufreq-cpu0", &div4_clks[DIV4_Z]),
|
||||
|
||||
/* DIV6 clocks */
|
||||
CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
|
||||
CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
|
||||
|
@ -604,8 +708,11 @@ void __init sh73a0_clock_init(void)
|
|||
for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
|
||||
ret = clk_register(main_clks[k]);
|
||||
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
|
||||
if (!ret)
|
||||
div4_clk_extend();
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
|
||||
|
|
|
@ -24,16 +24,16 @@ struct clk name = { \
|
|||
}
|
||||
|
||||
#define SH_FIXED_RATIO_CLK(name, p, r) \
|
||||
static SH_FIXED_RATIO_CLKg(name, p, r);
|
||||
static SH_FIXED_RATIO_CLKg(name, p, r)
|
||||
|
||||
#define SH_FIXED_RATIO_CLK_SET(name, p, m, d) \
|
||||
SH_CLK_RATIO(name, m, d); \
|
||||
SH_FIXED_RATIO_CLK(name, p, name);
|
||||
SH_FIXED_RATIO_CLK(name, p, name)
|
||||
|
||||
#define SH_CLK_SET_RATIO(p, m, d) \
|
||||
{ \
|
||||
do { \
|
||||
(p)->mul = m; \
|
||||
(p)->div = d; \
|
||||
}
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#ifndef __ASM_R8A7778_H__
|
||||
#define __ASM_R8A7778_H__
|
||||
|
||||
#include <linux/mmc/sh_mobile_sdhi.h>
|
||||
#include <linux/sh_eth.h>
|
||||
|
||||
extern void r8a7778_add_standard_devices(void);
|
||||
|
@ -29,5 +30,6 @@ extern void r8a7778_init_irq_dt(void);
|
|||
extern void r8a7778_clock_init(void);
|
||||
extern void r8a7778_init_irq_extpin(int irlm);
|
||||
extern void r8a7778_pinmux_init(void);
|
||||
extern void r8a7778_sdhi_init(int id, struct sh_mobile_sdhi_info *info);
|
||||
|
||||
#endif /* __ASM_R8A7778_H__ */
|
||||
|
|
|
@ -81,12 +81,6 @@ static struct sh_timer_config sh_tmu1_platform_data = {
|
|||
.clocksource_rating = 200,
|
||||
};
|
||||
|
||||
/* Ether */
|
||||
static struct resource ether_resources[] = {
|
||||
DEFINE_RES_MEM(0xfde00000, 0x400),
|
||||
DEFINE_RES_IRQ(gic_iid(0x89)),
|
||||
};
|
||||
|
||||
#define r8a7778_register_tmu(idx) \
|
||||
platform_device_register_resndata( \
|
||||
&platform_bus, "sh_tmu", idx, \
|
||||
|
@ -95,6 +89,20 @@ static struct resource ether_resources[] = {
|
|||
&sh_tmu##idx##_platform_data, \
|
||||
sizeof(sh_tmu##idx##_platform_data))
|
||||
|
||||
/* Ether */
|
||||
static struct resource ether_resources[] = {
|
||||
DEFINE_RES_MEM(0xfde00000, 0x400),
|
||||
DEFINE_RES_IRQ(gic_iid(0x89)),
|
||||
};
|
||||
|
||||
void __init r8a7778_add_ether_device(struct sh_eth_plat_data *pdata)
|
||||
{
|
||||
platform_device_register_resndata(&platform_bus, "sh_eth", -1,
|
||||
ether_resources,
|
||||
ARRAY_SIZE(ether_resources),
|
||||
pdata, sizeof(*pdata));
|
||||
}
|
||||
|
||||
/* PFC/GPIO */
|
||||
static struct resource pfc_resources[] = {
|
||||
DEFINE_RES_MEM(0xfffc0000, 0x118),
|
||||
|
@ -139,6 +147,30 @@ void __init r8a7778_pinmux_init(void)
|
|||
r8a7778_register_gpio(2);
|
||||
r8a7778_register_gpio(3);
|
||||
r8a7778_register_gpio(4);
|
||||
};
|
||||
|
||||
/* SDHI */
|
||||
static struct resource sdhi_resources[] = {
|
||||
/* SDHI0 */
|
||||
DEFINE_RES_MEM(0xFFE4C000, 0x100),
|
||||
DEFINE_RES_IRQ(gic_iid(0x77)),
|
||||
/* SDHI1 */
|
||||
DEFINE_RES_MEM(0xFFE4D000, 0x100),
|
||||
DEFINE_RES_IRQ(gic_iid(0x78)),
|
||||
/* SDHI2 */
|
||||
DEFINE_RES_MEM(0xFFE4F000, 0x100),
|
||||
DEFINE_RES_IRQ(gic_iid(0x76)),
|
||||
};
|
||||
|
||||
void __init r8a7778_sdhi_init(int id,
|
||||
struct sh_mobile_sdhi_info *info)
|
||||
{
|
||||
BUG_ON(id < 0 || id > 2);
|
||||
|
||||
platform_device_register_resndata(
|
||||
&platform_bus, "sh_mobile_sdhi", id,
|
||||
sdhi_resources + (2 * id), 2,
|
||||
info, sizeof(*info));
|
||||
}
|
||||
|
||||
void __init r8a7778_add_standard_devices(void)
|
||||
|
@ -165,14 +197,6 @@ void __init r8a7778_add_standard_devices(void)
|
|||
r8a7778_register_tmu(1);
|
||||
}
|
||||
|
||||
void __init r8a7778_add_ether_device(struct sh_eth_plat_data *pdata)
|
||||
{
|
||||
platform_device_register_resndata(&platform_bus, "sh_eth", -1,
|
||||
ether_resources,
|
||||
ARRAY_SIZE(ether_resources),
|
||||
pdata, sizeof(*pdata));
|
||||
}
|
||||
|
||||
static struct renesas_intc_irqpin_config irqpin_platform_data = {
|
||||
.irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */
|
||||
.sense_bitfield_width = 2,
|
||||
|
|
|
@ -288,12 +288,7 @@ static struct sh_timer_config tmu00_platform_data = {
|
|||
};
|
||||
|
||||
static struct resource tmu00_resources[] = {
|
||||
[0] = {
|
||||
.name = "TMU00",
|
||||
.start = 0xfff60008,
|
||||
.end = 0xfff60013,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[0] = DEFINE_RES_MEM_NAMED(0xfff60008, 0xc, "TMU00"),
|
||||
[1] = {
|
||||
.start = intcs_evt2irq(0x0e80), /* TMU0_TUNI00 */
|
||||
.flags = IORESOURCE_IRQ,
|
||||
|
@ -318,12 +313,7 @@ static struct sh_timer_config tmu01_platform_data = {
|
|||
};
|
||||
|
||||
static struct resource tmu01_resources[] = {
|
||||
[0] = {
|
||||
.name = "TMU01",
|
||||
.start = 0xfff60014,
|
||||
.end = 0xfff6001f,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[0] = DEFINE_RES_MEM_NAMED(0xfff60014, 0xc, "TMU00"),
|
||||
[1] = {
|
||||
.start = intcs_evt2irq(0x0ea0), /* TMU0_TUNI01 */
|
||||
.flags = IORESOURCE_IRQ,
|
||||
|
@ -341,12 +331,7 @@ static struct platform_device tmu01_device = {
|
|||
};
|
||||
|
||||
static struct resource i2c0_resources[] = {
|
||||
[0] = {
|
||||
.name = "IIC0",
|
||||
.start = 0xe6820000,
|
||||
.end = 0xe6820425 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[0] = DEFINE_RES_MEM_NAMED(0xe6820000, 0x426, "IIC0"),
|
||||
[1] = {
|
||||
.start = gic_spi(167),
|
||||
.end = gic_spi(170),
|
||||
|
@ -355,12 +340,7 @@ static struct resource i2c0_resources[] = {
|
|||
};
|
||||
|
||||
static struct resource i2c1_resources[] = {
|
||||
[0] = {
|
||||
.name = "IIC1",
|
||||
.start = 0xe6822000,
|
||||
.end = 0xe6822425 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[0] = DEFINE_RES_MEM_NAMED(0xe6822000, 0x426, "IIC1"),
|
||||
[1] = {
|
||||
.start = gic_spi(51),
|
||||
.end = gic_spi(54),
|
||||
|
@ -369,12 +349,7 @@ static struct resource i2c1_resources[] = {
|
|||
};
|
||||
|
||||
static struct resource i2c2_resources[] = {
|
||||
[0] = {
|
||||
.name = "IIC2",
|
||||
.start = 0xe6824000,
|
||||
.end = 0xe6824425 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[0] = DEFINE_RES_MEM_NAMED(0xe6824000, 0x426, "IIC2"),
|
||||
[1] = {
|
||||
.start = gic_spi(171),
|
||||
.end = gic_spi(174),
|
||||
|
@ -383,12 +358,7 @@ static struct resource i2c2_resources[] = {
|
|||
};
|
||||
|
||||
static struct resource i2c3_resources[] = {
|
||||
[0] = {
|
||||
.name = "IIC3",
|
||||
.start = 0xe6826000,
|
||||
.end = 0xe6826425 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[0] = DEFINE_RES_MEM_NAMED(0xe6826000, 0x426, "IIC3"),
|
||||
[1] = {
|
||||
.start = gic_spi(183),
|
||||
.end = gic_spi(186),
|
||||
|
@ -397,12 +367,7 @@ static struct resource i2c3_resources[] = {
|
|||
};
|
||||
|
||||
static struct resource i2c4_resources[] = {
|
||||
[0] = {
|
||||
.name = "IIC4",
|
||||
.start = 0xe6828000,
|
||||
.end = 0xe6828425 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[0] = DEFINE_RES_MEM_NAMED(0xe6828000, 0x426, "IIC4"),
|
||||
[1] = {
|
||||
.start = gic_spi(187),
|
||||
.end = gic_spi(190),
|
||||
|
@ -623,12 +588,7 @@ static struct sh_dmae_pdata sh73a0_dmae_platform_data = {
|
|||
};
|
||||
|
||||
static struct resource sh73a0_dmae_resources[] = {
|
||||
{
|
||||
/* Registers including DMAOR and channels including DMARSx */
|
||||
.start = 0xfe000020,
|
||||
.end = 0xfe008a00 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
DEFINE_RES_MEM(0xfe000020, 0x89e0),
|
||||
{
|
||||
.name = "error_irq",
|
||||
.start = gic_spi(129),
|
||||
|
@ -727,18 +687,10 @@ static struct sh_dmae_pdata sh73a0_mpdma_platform_data = {
|
|||
|
||||
/* Resource order important! */
|
||||
static struct resource sh73a0_mpdma_resources[] = {
|
||||
{
|
||||
/* Channel registers and DMAOR */
|
||||
.start = 0xec618020,
|
||||
.end = 0xec61828f,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
/* DMARSx */
|
||||
.start = 0xec619000,
|
||||
.end = 0xec61900b,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
/* Channel registers and DMAOR */
|
||||
DEFINE_RES_MEM(0xec618020, 0x270),
|
||||
/* DMARSx */
|
||||
DEFINE_RES_MEM(0xec619000, 0xc),
|
||||
{
|
||||
.name = "error_irq",
|
||||
.start = gic_spi(181),
|
||||
|
@ -785,12 +737,7 @@ static struct platform_device pmu_device = {
|
|||
|
||||
/* an IPMMU module for ICB */
|
||||
static struct resource ipmmu_resources[] = {
|
||||
[0] = {
|
||||
.name = "IPMMU",
|
||||
.start = 0xfe951000,
|
||||
.end = 0xfe9510ff,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
DEFINE_RES_MEM_NAMED(0xfe951000, 0x100, "IPMMU"),
|
||||
};
|
||||
|
||||
static const char * const ipmmu_dev_names[] = {
|
||||
|
@ -982,11 +929,17 @@ void __init sh73a0_add_standard_devices(void)
|
|||
ARRAY_SIZE(sh73a0_late_devices));
|
||||
}
|
||||
|
||||
void __init sh73a0_init_delay(void)
|
||||
{
|
||||
shmobile_setup_delay(1196, 44, 46); /* Cortex-A9 @ 1196MHz */
|
||||
}
|
||||
|
||||
/* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */
|
||||
void __init __weak sh73a0_register_twd(void) { }
|
||||
|
||||
void __init sh73a0_earlytimer_init(void)
|
||||
{
|
||||
sh73a0_init_delay();
|
||||
sh73a0_clock_init();
|
||||
shmobile_earlytimer_init();
|
||||
sh73a0_register_twd();
|
||||
|
@ -1005,17 +958,14 @@ void __init sh73a0_add_early_devices(void)
|
|||
|
||||
#ifdef CONFIG_USE_OF
|
||||
|
||||
void __init sh73a0_init_delay(void)
|
||||
{
|
||||
shmobile_setup_delay(1196, 44, 46); /* Cortex-A9 @ 1196MHz */
|
||||
}
|
||||
|
||||
static const struct of_dev_auxdata sh73a0_auxdata_lookup[] __initconst = {
|
||||
{},
|
||||
};
|
||||
|
||||
void __init sh73a0_add_standard_devices_dt(void)
|
||||
{
|
||||
struct platform_device_info devinfo = { .name = "cpufreq-cpu0", .id = -1, };
|
||||
|
||||
/* clocks are setup late during boot in the case of DT */
|
||||
sh73a0_clock_init();
|
||||
|
||||
|
@ -1023,6 +973,9 @@ void __init sh73a0_add_standard_devices_dt(void)
|
|||
ARRAY_SIZE(sh73a0_devices_dt));
|
||||
of_platform_populate(NULL, of_default_bus_match_table,
|
||||
sh73a0_auxdata_lookup, NULL);
|
||||
|
||||
/* Instantiate cpufreq-cpu0 */
|
||||
platform_device_register_full(&devinfo);
|
||||
}
|
||||
|
||||
static const char *sh73a0_boards_compat_dt[] __initdata = {
|
||||
|
|
Loading…
Reference in New Issue