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

Commit 08b93ec1 authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Simon Horman
Browse files

ARM: shmobile: r8a7778: use fixed ratio clock



R-Car M1 has many clocks, and it is possible to
read/use clock ratio of these clocks from FRQMRx.
But, these ratio are fixed value and
these are decided by MD pin status.

This patch reads MD pin status,
and used fixed ratio clock for other clocks.
It was tesed on bock-w board.

Signed-off-by: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarSimon Horman <horms+renesas@verge.net.au>
parent 0f704e12
Loading
Loading
Loading
Loading
+136 −13
Original line number Original line Diff line number Diff line
@@ -23,9 +23,23 @@
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 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/io.h>
#include <linux/sh_clk.h>
#include <linux/sh_clk.h>
#include <linux/clkdev.h>
#include <linux/clkdev.h>
#include <mach/clock.h>
#include <mach/common.h>
#include <mach/common.h>


#define MSTPCR0		IOMEM(0xffc80030)
#define MSTPCR0		IOMEM(0xffc80030)
@@ -37,6 +51,9 @@
#define MSTPCR4		IOMEM(0xffc80050)
#define MSTPCR4		IOMEM(0xffc80050)
#define MSTPCR5		IOMEM(0xffc80054)
#define MSTPCR5		IOMEM(0xffc80054)
#define MSTPCR6		IOMEM(0xffc80058)
#define MSTPCR6		IOMEM(0xffc80058)
#define MODEMR		0xFFCC0020

#define MD(nr)	BIT(nr)


/* ioremap() through clock mapping mandatory to avoid
/* ioremap() through clock mapping mandatory to avoid
 * collision with ARM coherent DMA virtual memory range.
 * collision with ARM coherent DMA virtual memory range.
@@ -47,14 +64,42 @@ static struct clk_mapping cpg_mapping = {
	.len	= 0x80,
	.len	= 0x80,
};
};


static struct clk clkp = {
static struct clk extal_clk = {
	.rate   = 62500000, /* FIXME: shortcut */
	/* .rate will be updated on r8a7778_clock_init() */
	.flags  = CLK_ENABLE_ON_INIT,
	.mapping = &cpg_mapping,
	.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[] = {
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 {
enum {
@@ -64,15 +109,15 @@ enum {
	MSTP_NR };
	MSTP_NR };


static struct clk mstp_clks[MSTP_NR] = {
static struct clk mstp_clks[MSTP_NR] = {
	[MSTP114] = SH_CLK_MSTP32(&clkp, MSTPCR1, 14, 0), /* Ether */
	[MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */
	[MSTP026] = SH_CLK_MSTP32(&clkp, MSTPCR0, 26, 0), /* SCIF0 */
	[MSTP026] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 26, 0), /* SCIF0 */
	[MSTP025] = SH_CLK_MSTP32(&clkp, MSTPCR0, 25, 0), /* SCIF1 */
	[MSTP025] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 25, 0), /* SCIF1 */
	[MSTP024] = SH_CLK_MSTP32(&clkp, MSTPCR0, 24, 0), /* SCIF2 */
	[MSTP024] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 24, 0), /* SCIF2 */
	[MSTP023] = SH_CLK_MSTP32(&clkp, MSTPCR0, 23, 0), /* SCIF3 */
	[MSTP023] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 23, 0), /* SCIF3 */
	[MSTP022] = SH_CLK_MSTP32(&clkp, MSTPCR0, 22, 0), /* SCIF4 */
	[MSTP022] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 22, 0), /* SCIF4 */
	[MSTP021] = SH_CLK_MSTP32(&clkp, MSTPCR0, 21, 0), /* SCIF5 */
	[MSTP021] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 21, 0), /* SCIF5 */
	[MSTP016] = SH_CLK_MSTP32(&clkp, MSTPCR0, 16, 0), /* TMU0 */
	[MSTP016] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 16, 0), /* TMU0 */
	[MSTP015] = SH_CLK_MSTP32(&clkp, MSTPCR0, 15, 0), /* TMU1 */
	[MSTP015] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 15, 0), /* TMU1 */
};
};


static struct clk_lookup lookups[] = {
static struct clk_lookup lookups[] = {
@@ -90,8 +135,86 @@ static struct clk_lookup lookups[] = {


void __init r8a7778_clock_init(void)
void __init r8a7778_clock_init(void)
{
{
	void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE);
	u32 mode;
	int k, ret = 0;
	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++)
	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
		ret = clk_register(main_clks[k]);
		ret = clk_register(main_clks[k]);