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

Commit f82f16d2 authored by Bob Liu's avatar Bob Liu
Browse files

bfin: reorg clock init steps for bf609



So that user can set the clocks through menuconfig.

Signed-off-by: default avatarBob Liu <lliubbo@gmail.com>
parent e70f4660
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -352,6 +352,11 @@ config MEM_MT48H32M16LFCJ_75
	depends on (BFIN526_EZBRD)
	default y

config MEM_MT47H64M16
	bool
	depends on (BFIN609_EZKIT)
	default y

source "arch/blackfin/mach-bf518/Kconfig"
source "arch/blackfin/mach-bf527/Kconfig"
source "arch/blackfin/mach-bf533/Kconfig"
+212 −0
Original line number Diff line number Diff line
@@ -6,6 +6,9 @@
 * Licensed under the GPL-2 or later.
 */

#ifndef __MEM_INIT_H__
#define __MEM_INIT_H__

#if defined(EBIU_SDGCTL)
#if defined(CONFIG_MEM_MT48LC16M16A2TG_75) || \
    defined(CONFIG_MEM_MT48LC64M4A2FB_7E) || \
@@ -277,3 +280,212 @@
#else
#define PLL_BYPASS       0
#endif

#ifdef CONFIG_BF60x

/* DMC status bits */
#define IDLE			0x1
#define MEMINITDONE		0x4
#define SRACK			0x8
#define PDACK			0x10
#define DPDACK			0x20
#define DLLCALDONE		0x2000
#define PENDREF			0xF0000
#define PHYRDPHASE		0xF00000
#define PHYRDPHASE_OFFSET	20

/* DMC control bits */
#define LPDDR			0x2
#define INIT			0x4
#define	SRREQ			0x8
#define PDREQ			0x10
#define DPDREQ			0x20
#define PREC			0x40
#define ADDRMODE		0x100
#define RDTOWR			0xE00
#define PPREF			0x1000
#define DLLCAL			0x2000

/* DMC DLL control bits */
#define DLLCALRDCNT		0xFF
#define DATACYC			0xF00
#define DATACYC_OFFSET		8

/* CGU Divisor bits */
#define CSEL_OFFSET		0
#define S0SEL_OFFSET		5
#define SYSSEL_OFFSET		8
#define S1SEL_OFFSET		13
#define DSEL_OFFSET		16
#define OSEL_OFFSET		22
#define ALGN			0x20000000
#define UPDT			0x40000000
#define LOCK			0x80000000

/* CGU Status bits */
#define PLLEN			0x1
#define PLLBP			0x2
#define PLOCK			0x4
#define CLKSALGN		0x8

/* CGU Control bits */
#define MSEL_MASK		0x7F00
#define DF_MASK			0x1

struct ddr_config {
	u32 ddr_clk;
	u32 dmc_ddrctl;
	u32 dmc_ddrcfg;
	u32 dmc_ddrtr0;
	u32 dmc_ddrtr1;
	u32 dmc_ddrtr2;
	u32 dmc_ddrmr;
	u32 dmc_ddrmr1;
};

#if defined(CONFIG_MEM_MT47H64M16)
static struct ddr_config ddr_config_table[] __attribute__((section(".data_l1"))) = {
	[0] = {
		.ddr_clk    = 125,
		.dmc_ddrctl = 0x00000904,
		.dmc_ddrcfg = 0x00000422,
		.dmc_ddrtr0 = 0x20705212,
		.dmc_ddrtr1 = 0x201003CF,
		.dmc_ddrtr2 = 0x00320107,
		.dmc_ddrmr  = 0x00000422,
		.dmc_ddrmr1 = 0x4,
	},
	[1] = {
		.ddr_clk    = 133,
		.dmc_ddrctl = 0x00000904,
		.dmc_ddrcfg = 0x00000422,
		.dmc_ddrtr0 = 0x20806313,
		.dmc_ddrtr1 = 0x2013040D,
		.dmc_ddrtr2 = 0x00320108,
		.dmc_ddrmr  = 0x00000632,
		.dmc_ddrmr1 = 0x4,
	},
	[2] = {
		.ddr_clk    = 150,
		.dmc_ddrctl = 0x00000904,
		.dmc_ddrcfg = 0x00000422,
		.dmc_ddrtr0 = 0x20A07323,
		.dmc_ddrtr1 = 0x20160492,
		.dmc_ddrtr2 = 0x00320209,
		.dmc_ddrmr  = 0x00000632,
		.dmc_ddrmr1 = 0x4,
	},
	[3] = {
		.ddr_clk    = 166,
		.dmc_ddrctl = 0x00000904,
		.dmc_ddrcfg = 0x00000422,
		.dmc_ddrtr0 = 0x20A07323,
		.dmc_ddrtr1 = 0x2016050E,
		.dmc_ddrtr2 = 0x00320209,
		.dmc_ddrmr  = 0x00000632,
		.dmc_ddrmr1 = 0x4,
	},
	[4] = {
		.ddr_clk    = 200,
		.dmc_ddrctl = 0x00000904,
		.dmc_ddrcfg = 0x00000422,
		.dmc_ddrtr0 = 0x20a07323,
		.dmc_ddrtr1 = 0x2016050f,
		.dmc_ddrtr2 = 0x00320509,
		.dmc_ddrmr  = 0x00000632,
		.dmc_ddrmr1 = 0x4,
	},
	[5] = {
		.ddr_clk    = 225,
		.dmc_ddrctl = 0x00000904,
		.dmc_ddrcfg = 0x00000422,
		.dmc_ddrtr0 = 0x20E0A424,
		.dmc_ddrtr1 = 0x302006DB,
		.dmc_ddrtr2 = 0x0032020D,
		.dmc_ddrmr  = 0x00000842,
		.dmc_ddrmr1 = 0x4,
	},
	[6] = {
		.ddr_clk    = 250,
		.dmc_ddrctl = 0x00000904,
		.dmc_ddrcfg = 0x00000422,
		.dmc_ddrtr0 = 0x20E0A424,
		.dmc_ddrtr1 = 0x3020079E,
		.dmc_ddrtr2 = 0x0032020D,
		.dmc_ddrmr  = 0x00000842,
		.dmc_ddrmr1 = 0x4,
	},
};
#endif

static inline void dmc_enter_self_refresh(void)
{
	if (bfin_read_DMC0_STAT() & MEMINITDONE) {
		bfin_write_DMC0_CTL(bfin_read_DMC0_CTL() | SRREQ);
		while (!(bfin_read_DMC0_STAT() & SRACK))
			continue;
	}
}

static inline void dmc_exit_self_refresh(void)
{
	if (bfin_read_DMC0_STAT() & MEMINITDONE) {
		bfin_write_DMC0_CTL(bfin_read_DMC0_CTL() & ~SRREQ);
		while (bfin_read_DMC0_STAT() & SRACK)
			continue;
	}
}

static inline void init_cgu(u32 cgu_div, u32 cgu_ctl)
{
	dmc_enter_self_refresh();

	/* Don't set the same value of MSEL and DF to CGU_CTL */
	if ((bfin_read32(CGU0_CTL) & (MSEL_MASK | DF_MASK))
		!= cgu_ctl) {
		bfin_write32(CGU0_DIV, cgu_div);
		bfin_write32(CGU0_CTL, cgu_ctl);
		while ((bfin_read32(CGU0_STAT) & (CLKSALGN | PLLBP)) ||
			!(bfin_read32(CGU0_STAT) & PLOCK))
			continue;
	}

	bfin_write32(CGU0_DIV, cgu_div | UPDT);
	while (bfin_read32(CGU0_STAT) & CLKSALGN)
		continue;

	dmc_exit_self_refresh();
}

static inline void init_dmc(u32 dmc_clk)
{
	int i, dlldatacycle, dll_ctl;

	for (i = 0; i < 7; i++) {
		if (ddr_config_table[i].ddr_clk == dmc_clk) {
			bfin_write_DMC0_CFG(ddr_config_table[i].dmc_ddrcfg);
			bfin_write_DMC0_TR0(ddr_config_table[i].dmc_ddrtr0);
			bfin_write_DMC0_TR1(ddr_config_table[i].dmc_ddrtr1);
			bfin_write_DMC0_TR2(ddr_config_table[i].dmc_ddrtr2);
			bfin_write_DMC0_MR(ddr_config_table[i].dmc_ddrmr);
			bfin_write_DMC0_EMR1(ddr_config_table[i].dmc_ddrmr1);
			bfin_write_DMC0_CTL(ddr_config_table[i].dmc_ddrctl);
			break;
		}
	}

	while (!(bfin_read_DMC0_STAT() & MEMINITDONE))
		continue;

	dlldatacycle = (bfin_read_DMC0_STAT() & PHYRDPHASE) >> PHYRDPHASE_OFFSET;
	dll_ctl = bfin_read_DMC0_DLLCTL();
	dll_ctl &= ~DATACYC;
	bfin_write_DMC0_DLLCTL(dll_ctl | (dlldatacycle << DATACYC_OFFSET));

	while (!(bfin_read_DMC0_STAT() & DLLCALDONE))
		continue;
}
#endif

#endif /*__MEM_INIT_H__*/
+0 −1
Original line number Diff line number Diff line
@@ -2665,7 +2665,6 @@
#define DEVSZ_1G                0x400         /* DMC External Bank Size = 1Gbit */
#define DEVSZ_2G                0x500         /* DMC External Bank Size = 2Gbit */


/* =========================
        L2CTL Registers
   ========================= */
+7 −132
Original line number Diff line number Diff line
@@ -16,23 +16,14 @@
#include <asm/dpmc.h>

#ifdef CONFIG_BF60x
#define CSEL_P			0
#define S0SEL_P			5
#define SYSSEL_P		8
#define S1SEL_P			13
#define DSEL_P			16
#define OSEL_P			22
#define ALGN_P			29
#define UPDT_P			30
#define LOCK_P			31

#define CGU_CTL_VAL ((CONFIG_VCO_MULT << 8) | CLKIN_HALF)
#define CGU_DIV_VAL \
	((CONFIG_CCLK_DIV   << CSEL_P)   | \
	(CONFIG_SCLK_DIV << SYSSEL_P)   | \
	(CONFIG_SCLK0_DIV  << S0SEL_P)  | \
	(CONFIG_SCLK1_DIV  << S1SEL_P)  | \
	(CONFIG_DCLK_DIV   << DSEL_P))
	((CONFIG_CCLK_DIV   << CSEL_OFFSET)   | \
	(CONFIG_SCLK_DIV << SYSSEL_OFFSET)   | \
	(CONFIG_SCLK0_DIV  << S0SEL_OFFSET)  | \
	(CONFIG_SCLK1_DIV  << S1SEL_OFFSET)  | \
	(CONFIG_DCLK_DIV   << DSEL_OFFSET))

#define CONFIG_BFIN_DCLK (((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_DCLK_DIV) / 1000000)
#if ((CONFIG_BFIN_DCLK != 125) && \
@@ -41,89 +32,7 @@
	(CONFIG_BFIN_DCLK != 225) && (CONFIG_BFIN_DCLK != 250))
#error "DCLK must be in (125, 133, 150, 166, 200, 225, 250)MHz"
#endif
struct ddr_config {
	u32 ddr_clk;
	u32 dmc_ddrctl;
	u32 dmc_ddrcfg;
	u32 dmc_ddrtr0;
	u32 dmc_ddrtr1;
	u32 dmc_ddrtr2;
	u32 dmc_ddrmr;
	u32 dmc_ddrmr1;
};

struct ddr_config ddr_config_table[] __attribute__((section(".data_l1"))) = {
	[0] = {
		.ddr_clk    = 125,
		.dmc_ddrctl = 0x00000904,
		.dmc_ddrcfg = 0x00000422,
		.dmc_ddrtr0 = 0x20705212,
		.dmc_ddrtr1 = 0x201003CF,
		.dmc_ddrtr2 = 0x00320107,
		.dmc_ddrmr  = 0x00000422,
		.dmc_ddrmr1 = 0x4,
	},
	[1] = {
		.ddr_clk    = 133,
		.dmc_ddrctl = 0x00000904,
		.dmc_ddrcfg = 0x00000422,
		.dmc_ddrtr0 = 0x20806313,
		.dmc_ddrtr1 = 0x2013040D,
		.dmc_ddrtr2 = 0x00320108,
		.dmc_ddrmr  = 0x00000632,
		.dmc_ddrmr1 = 0x4,
	},
	[2] = {
		.ddr_clk    = 150,
		.dmc_ddrctl = 0x00000904,
		.dmc_ddrcfg = 0x00000422,
		.dmc_ddrtr0 = 0x20A07323,
		.dmc_ddrtr1 = 0x20160492,
		.dmc_ddrtr2 = 0x00320209,
		.dmc_ddrmr  = 0x00000632,
		.dmc_ddrmr1 = 0x4,
	},
	[3] = {
		.ddr_clk    = 166,
		.dmc_ddrctl = 0x00000904,
		.dmc_ddrcfg = 0x00000422,
		.dmc_ddrtr0 = 0x20A07323,
		.dmc_ddrtr1 = 0x2016050E,
		.dmc_ddrtr2 = 0x00320209,
		.dmc_ddrmr  = 0x00000632,
		.dmc_ddrmr1 = 0x4,
	},
	[4] = {
		.ddr_clk    = 200,
		.dmc_ddrctl = 0x00000904,
		.dmc_ddrcfg = 0x00000422,
		.dmc_ddrtr0 = 0x20a07323,
		.dmc_ddrtr1 = 0x2016050f,
		.dmc_ddrtr2 = 0x00320509,
		.dmc_ddrmr  = 0x00000632,
		.dmc_ddrmr1 = 0x4,
	},
	[5] = {
		.ddr_clk    = 225,
		.dmc_ddrctl = 0x00000904,
		.dmc_ddrcfg = 0x00000422,
		.dmc_ddrtr0 = 0x20E0A424,
		.dmc_ddrtr1 = 0x302006DB,
		.dmc_ddrtr2 = 0x0032020D,
		.dmc_ddrmr  = 0x00000842,
		.dmc_ddrmr1 = 0x4,
	},
	[6] = {
		.ddr_clk    = 250,
		.dmc_ddrctl = 0x00000904,
		.dmc_ddrcfg = 0x00000422,
		.dmc_ddrtr0 = 0x20E0A424,
		.dmc_ddrtr1 = 0x3020079E,
		.dmc_ddrtr2 = 0x0032020D,
		.dmc_ddrmr  = 0x00000842,
		.dmc_ddrmr1 = 0x4,
	},
};
#else
#define SDGCTL_WIDTH (1 << 31)	/* SDRAM external data path width */
#define PLL_CTL_VAL \
@@ -144,43 +53,9 @@ void init_clocks(void)
	 * in the middle of reprogramming things, and that'll screw us up.
	 * For example, any automatic DMAs left by U-Boot for splash screens.
	 */

#ifdef CONFIG_BF60x
	int i, dlldatacycle, dll_ctl;
	bfin_write32(CGU0_DIV, CGU_DIV_VAL);
	bfin_write32(CGU0_CTL, CGU_CTL_VAL);
	while ((bfin_read32(CGU0_STAT) & 0x8) || !(bfin_read32(CGU0_STAT) & 0x4))
		continue;

	bfin_write32(CGU0_DIV, CGU_DIV_VAL | (1 << UPDT_P));
	while (bfin_read32(CGU0_STAT) & (1 << 3))
		continue;

	for (i = 0; i < 7; i++) {
		if (ddr_config_table[i].ddr_clk == CONFIG_BFIN_DCLK) {
			bfin_write_DDR0_CFG(ddr_config_table[i].dmc_ddrcfg);
			bfin_write_DDR0_TR0(ddr_config_table[i].dmc_ddrtr0);
			bfin_write_DDR0_TR1(ddr_config_table[i].dmc_ddrtr1);
			bfin_write_DDR0_TR2(ddr_config_table[i].dmc_ddrtr2);
			bfin_write_DDR0_MR(ddr_config_table[i].dmc_ddrmr);
			bfin_write_DDR0_EMR1(ddr_config_table[i].dmc_ddrmr1);
			bfin_write_DDR0_CTL(ddr_config_table[i].dmc_ddrctl);
			break;
		}
	}

	do_sync();
	while (!(bfin_read_DDR0_STAT() & 0x4))
		continue;

	dlldatacycle = (bfin_read_DDR0_STAT() & 0x00f00000) >> 20;
	dll_ctl = bfin_read_DDR0_DLLCTL();
	dll_ctl &= 0x0ff;
	bfin_write_DDR0_DLLCTL(dll_ctl | (dlldatacycle << 8));

	do_sync();
	while (!(bfin_read_DDR0_STAT() & 0x2000))
		continue;
	init_cgu(CGU_DIV_VAL, CGU_CTL_VAL);
	init_dmc(CONFIG_BFIN_DCLK);
#else
	size_t i;
	for (i = 0; i < MAX_DMA_CHANNELS; ++i) {