Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b67172ec authored by Olof Johansson's avatar Olof Johansson
Browse files

Merge tag 'renesas-soc-for-v3.11' of...

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
parents 620fa619 413bfd0e
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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
+359 −16
Original line number Diff line number Diff line
@@ -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);

+8 −3
Original line number Diff line number Diff line
@@ -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]),
+143 −13
Original line number Diff line number Diff line
@@ -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]);

+3 −1
Original line number Diff line number Diff line
@@ -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 */
Loading