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

Commit 7c141c1c authored by Bob Liu's avatar Bob Liu
Browse files

blackfin: bf60x: make clock changeable in kernel menuconfig



Add clock changeable support in kernel menuconfig for bf60x.

Signed-off-by: default avatarBob Liu <lliubbo@gmail.com>
parent 1c400939
Loading
Loading
Loading
Loading
+40 −5
Original line number Diff line number Diff line
@@ -435,7 +435,7 @@ config BFIN_KERNEL_CLOCK

config PLL_BYPASS
	bool "Bypass PLL"
	depends on BFIN_KERNEL_CLOCK
	depends on BFIN_KERNEL_CLOCK && (!BF60x)
	default n

config CLKIN_HALF
@@ -454,7 +454,7 @@ config VCO_MULT
	default "20" if (BFIN537_STAMP || BFIN527_EZKIT || BFIN527_EZKIT_V2 || BFIN548_EZKIT || BFIN548_BLUETECHNIX_CM || BFIN538_EZKIT)
	default "22" if BFIN533_BLUETECHNIX_CM
	default "20" if (BFIN537_BLUETECHNIX_CM_E || BFIN537_BLUETECHNIX_CM_U || BFIN527_BLUETECHNIX_CM || BFIN561_BLUETECHNIX_CM)
	default "20" if BFIN561_EZKIT
	default "20" if (BFIN561_EZKIT || BF609)
	default "16" if (H8606_HVSISTEMAS || BLACKSTAMP || BFIN526_EZBRD || BFIN518F_EZBRD)
	default "25" if BFIN527_AD7160EVAL
	help
@@ -486,12 +486,45 @@ config SCLK_DIV
	int "System Clock Divider"
	depends on BFIN_KERNEL_CLOCK
	range 1 15
	default 5
	default 4
	help
	  This sets the frequency of the system clock (including SDRAM or DDR).
	  This sets the frequency of the system clock (including SDRAM or DDR) on
	  !BF60x else it set the clock for system buses and provides the
	  source from which SCLK0 and SCLK1 are derived.
	  This can be between 1 and 15
	  System Clock = (PLL frequency) / (this setting)

config SCLK0_DIV
	int "System Clock0 Divider"
	depends on BFIN_KERNEL_CLOCK && BF60x
	range 1 15
	default 1
	help
	  This sets the frequency of the system clock0 for PVP and all other
	  peripherals not clocked by SCLK1.
	  This can be between 1 and 15
	  System Clock0 = (System Clock) / (this setting)

config SCLK1_DIV
	int "System Clock1 Divider"
	depends on BFIN_KERNEL_CLOCK && BF60x
	range 1 15
	default 1
	help
	  This sets the frequency of the system clock1 (including SPORT, SPI and ACM).
	  This can be between 1 and 15
	  System Clock1 = (System Clock) / (this setting)

config DCLK_DIV
	int "DDR Clock Divider"
	depends on BFIN_KERNEL_CLOCK && BF60x
	range 1 15
	default 2
	help
	  This sets the frequency of the DDR memory.
	  This can be between 1 and 15
	  DDR Clock = (PLL frequency) / (this setting)

choice
	prompt "DDR SDRAM Chip Type"
	depends on BFIN_KERNEL_CLOCK
@@ -507,7 +540,7 @@ endchoice

choice
	prompt "DDR/SDRAM Timing"
	depends on BFIN_KERNEL_CLOCK
	depends on BFIN_KERNEL_CLOCK && !BF60x
	default BFIN_KERNEL_CLOCK_MEMINIT_CALC
	help
	  This option allows you to specify Blackfin SDRAM/DDR Timing parameters
@@ -589,6 +622,7 @@ config MAX_VCO_HZ
	default 600000000 if BF548
	default 533333333 if BF549
	default 600000000 if BF561
	default 800000000 if BF609

config MIN_VCO_HZ
	int
@@ -596,6 +630,7 @@ config MIN_VCO_HZ

config MAX_SCLK_HZ
	int
	default 200000000 if BF609
	default 133333333

config MIN_SCLK_HZ
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ extern unsigned long get_sclk(void);
#ifdef CONFIG_BF60x
extern unsigned long get_sclk0(void);
extern unsigned long get_sclk1(void);
extern unsigned long get_dramclk(void);
extern unsigned long get_dclk(void);
#endif
extern unsigned long sclk_to_usecs(unsigned long sclk);
extern unsigned long usecs_to_sclk(unsigned long usecs);
+5 −19
Original line number Diff line number Diff line
@@ -892,9 +892,6 @@ void __init setup_arch(char **cmdline_p)
{
	u32 mmr;
	unsigned long sclk, cclk;
#ifdef CONFIG_BF60x
	struct clk *clk;
#endif

	native_machine_early_platform_add_devices();

@@ -959,24 +956,8 @@ void __init setup_arch(char **cmdline_p)
					~HYST_NONEGPIO_MASK) | HYST_NONEGPIO);
#endif

#ifdef CONFIG_BF60x
	clk = clk_get(NULL, "CCLK");
	if (!IS_ERR(clk)) {
		cclk = clk_get_rate(clk);
		clk_put(clk);
	} else
		cclk = 0;

	clk = clk_get(NULL, "SCLK0");
	if (!IS_ERR(clk)) {
		sclk = clk_get_rate(clk);
		clk_put(clk);
	} else
		sclk = 0;
#else
	cclk = get_cclk();
	sclk = get_sclk();
#endif

	if ((ANOMALY_05000273 || ANOMALY_05000274) && (cclk >> 1) < sclk)
		panic("ANOMALY 05000273 or 05000274: CCLK must be >= 2*SCLK");
@@ -1062,8 +1043,13 @@ void __init setup_arch(char **cmdline_p)

	printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n");

#ifdef CONFIG_BF60x
	printk(KERN_INFO "Processor Speed: %lu MHz core clock, %lu MHz SCLk, %lu MHz SCLK0, %lu MHz SCLK1 and %lu MHz DCLK\n",
		cclk / 1000000, sclk / 1000000, get_sclk0() / 1000000, get_sclk1() / 1000000, get_dclk() / 1000000);
#else
	printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n",
	       cclk / 1000000, sclk / 1000000);
#endif

	setup_bootmem_allocator();

+1 −1
Original line number Diff line number Diff line
@@ -351,7 +351,7 @@ static struct clk dclk = {
	.rate       = 500000000,
	.mask       = CGU0_DIV_DSEL_MASK,
	.shift       = CGU0_DIV_DSEL_SHIFT,
	.parent     = &pll_clk,
	.parent     = &sys_clkin,
	.ops	    = &sys_clk_ops,
};

+150 −3
Original line number Diff line number Diff line
@@ -15,10 +15,121 @@
#include <asm/mem_init.h>
#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))

#define CONFIG_BFIN_DCLK (((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_DCLK_DIV) / 1000000)
#if ((CONFIG_BFIN_DCLK != 125) && \
	(CONFIG_BFIN_DCLK != 133) && (CONFIG_BFIN_DCLK != 150) && \
	(CONFIG_BFIN_DCLK != 166) && (CONFIG_BFIN_DCLK != 200) && \
	(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 \
	(((CONFIG_VCO_MULT & 63) << 9) | CLKIN_HALF | \
		(PLL_BYPASS << 8) | (ANOMALY_05000305 ? 0 : 0x8000))
#endif

__attribute__((l1_text))
static void do_sync(void)
@@ -34,7 +145,43 @@ void init_clocks(void)
	 * For example, any automatic DMAs left by U-Boot for splash screens.
	 */

#if 0
#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;
#else
	size_t i;
	for (i = 0; i < MAX_DMA_CHANNELS; ++i) {
		struct dma_register *dma = dma_io_base_addr[i];
@@ -92,9 +239,9 @@ void init_clocks(void)
#ifdef CONFIG_MEM_EBIU_DDRQUE
	bfin_write_EBIU_DDRQUE(CONFIG_MEM_EBIU_DDRQUE);
#endif
#endif
#endif
	do_sync();
	bfin_read16(0);

#endif
}