Commit f9fec77e authored by Alexander Potashev's avatar Alexander Potashev

RT75957. twr-k70f120m: configure DDR memory controller

Take the DDR controller configuration (including memory timings) from
the Freescale's sample code package (KINETIS_120MHZ_SC.zip).

Move `struct kinetis_sim_regs` to
`include/asm-arm/arch-kinetis/kinetis.h`, because the SIM registers
have to be updated in order to properly configure the DDR controller for
the given external memory chip.

DDR works in the asynchronous mode.

Set the DDR clock to 150 MHz (using the PLL1).

For the board with external DDR memory, the DDR configuration code
should be enabled using the CONFIG_KINETIS_DDR configuration option in
the U-Boot configuration file.
parent 34d45f55
This diff is collapsed.
......@@ -90,6 +90,7 @@
#define KINETIS_PCLK_RATE_MAX (50 * 1000 * 1000) /* 50 MHz */
#define KINETIS_FLEXBUS_RATE_MAX (50 * 1000 * 1000) /* 50 MHz */
#define KINETIS_FLASH_RATE_MAX (25 * 1000 * 1000) /* 25 MHz */
#define KINETIS_DDR_RATE_MAX 0 /* DDR not supported */
#undef KINETIS_MCG_PLLREFSEL /* No support for multiple oscillators */
......@@ -107,6 +108,7 @@
#define KINETIS_PCLK_RATE_MAX (60 * 1000 * 1000) /* 60 MHz */
#define KINETIS_FLEXBUS_RATE_MAX (50 * 1000 * 1000) /* 50 MHz */
#define KINETIS_FLASH_RATE_MAX (25 * 1000 * 1000) /* 25 MHz */
#define KINETIS_DDR_RATE_MAX (150 * 1000 * 1000) /* 150 MHz */
#define KINETIS_MCG_PLLREFSEL 0 /* PLL0 input: EXTAL0 through OSC0 */
......@@ -148,6 +150,42 @@
(KINETIS_MCG_PLL_IN_RATE / KINETIS_PLL_PRDIV * KINETIS_PLL_VDIV / \
KINETIS_PLL_VCO_DIV)
#if !defined(CONFIG_KINETIS_K60_100MHZ)
/*
* Verify the PRDIV divider value for PLL1
*/
#if !defined(KINETIS_PLL1_PRDIV)
#error KINETIS_PLL1_PRDIV is not defined
#elif KINETIS_PLL1_PRDIV < 1 || KINETIS_PLL1_PRDIV > KINETIS_PLL_PRDIV_MAX
#error KINETIS_PLL1_PRDIV should be between 1 and KINETIS_PLL_PRDIV_MAX
#endif
/*
* Verify the VDIV multiplier value for PLL1
*/
#if !defined(KINETIS_PLL1_VDIV)
#error KINETIS_PLL1_VDIV is not defined
#elif KINETIS_PLL1_VDIV < KINETIS_PLL_VDIV_MIN || \
KINETIS_PLL1_VDIV > KINETIS_PLL_VDIV_MAX
#error KINETIS_PLL1_VDIV should be set to an integer in the allowed range
#endif
/*
* Verify the PLL reference clock rate for PLL1
*/
#if ((KINETIS_MCG_PLL_IN_RATE / KINETIS_PLL1_PRDIV) < KINETIS_PLL_REF_MIN) || \
((KINETIS_MCG_PLL_IN_RATE / KINETIS_PLL1_PRDIV) > KINETIS_PLL_REF_MAX)
#error The PLL1 reference clock should be in the defined range
#endif
/*
* PLL1 output rate
*/
#define KINETIS_PLL1OUT_RATE \
(KINETIS_MCG_PLL_IN_RATE / KINETIS_PLL1_PRDIV * KINETIS_PLL1_VDIV / \
KINETIS_PLL_VCO_DIV)
#endif /* !defined(CONFIG_KINETIS_K60_100MHZ) */
/*
* Core/system clock rate
*/
......@@ -180,6 +218,16 @@
#error KINETIS_FLASH_RATE exceeds the limit for this MCU
#endif
#ifdef CONFIG_KINETIS_DDR
/*
* DDR clock rate
*/
#define KINETIS_DDR_RATE KINETIS_PLL1OUT_RATE
#if KINETIS_DDR_RATE > KINETIS_DDR_RATE_MAX
#error KINETIS_DDR_RATE exceeds the limit for this MCU
#endif
#endif /* CONFIG_KINETIS_DDR */
/*
* Oscillator (OSC) registers
*/
......@@ -236,6 +284,20 @@
#define KINETIS_MCG_C6_VDIV_BITS 0
/* PLL Select */
#define KINETIS_MCG_C6_PLLS_MSK (1 << 6)
/*
* MCG Control 11 Register
*/
/* PLL1 External Reference Divider */
#define KINETIS_MCG_C11_PRDIV_BITS 0
/* PLL1 Stop Enable */
#define KINETIS_MCG_C11_PLLSTEN1_MSK (1 << 5)
/* PLL1 Clock Enable */
#define KINETIS_MCG_C11_PLLCLKEN1_MSK (1 << 6)
/*
* MCG Control 12 Register
*/
/* VCO1 Divider */
#define KINETIS_MCG_C12_VDIV1_BITS 0
/*
* MCG Status Register
*/
......@@ -254,6 +316,11 @@
#define KINETIS_MCG_S_PLLST_MSK (1 << 5)
/* Indicates whether the PLL has acquired lock */
#define KINETIS_MCG_S_LOCK_MSK (1 << 6)
/*
* MCG Status 2 Register
*/
/* This bit indicates whether PLL1 has acquired lock */
#define KINETIS_MCG_S2_LOCK1_MSK (1 << 6)
/*
* SIM registers
......@@ -270,50 +337,6 @@
/* Clock 4 output divider value (for the flash clock) */
#define KINETIS_SIM_CLKDIV1_OUTDIV4_BITS 16
/*
* Limits for the `kinetis_periph_enable()` function:
* 1. The number of SIM_SCGC[] registers
* 2. The number of bits in those registers
*/
#define KINETIS_SIM_CG_NUMREGS 7
#define KINETIS_SIM_CG_NUMBITS 32
/*
* System Integration Module (SIM) register map
*
* This map actually covers two hardware modules:
* 1. SIM low-power logic, at 0x40047000
* 2. System integration module (SIM), at 0x40048000
*/
struct kinetis_sim_regs {
u32 sopt1; /* System Options Register 1 */
u32 rsv0[1024];
u32 sopt2; /* System Options Register 2 */
u32 rsv1;
u32 sopt4; /* System Options Register 4 */
u32 sopt5; /* System Options Register 5 */
u32 sopt6; /* System Options Register 6 */
u32 sopt7; /* System Options Register 7 */
u32 rsv2[2];
u32 sdid; /* System Device Identification Register */
u32 scgc[7]; /* System Clock Gating Control Registers 1...7 */
u32 clkdiv1; /* System Clock Divider Register 1 */
u32 clkdiv2; /* System Clock Divider Register 2 */
u32 fcfg1; /* Flash Configuration Register 1 */
u32 fcfg2; /* Flash Configuration Register 2 */
u32 uidh; /* Unique Identification Register High */
u32 uidmh; /* Unique Identification Register Mid-High */
u32 uidml; /* Unique Identification Register Mid Low */
u32 uidl; /* Unique Identification Register Low */
};
/*
* SIM registers base
*/
#define KINETIS_SIM_BASE (KINETIS_AIPS0PERIPH_BASE + 0x00047000)
#define KINETIS_SIM ((volatile struct kinetis_sim_regs *) \
KINETIS_SIM_BASE)
/*
* Multipurpose Clock Generator (MCG) register map
*
......@@ -332,6 +355,13 @@ struct kinetis_mcg_regs {
u8 rsv1;
u8 atcvh; /* MCG Auto Trim Compare Value High Register */
u8 atcvl; /* MCG Auto Trim Compare Value Low Register */
u8 c7; /* MCG Control 7 Register */
u8 c8; /* MCG Control 8 Register */
u8 rsv2;
u8 c10; /* MCG Control 10 Register */
u8 c11; /* MCG Control 11 Register */
u8 c12; /* MCG Control 12 Register */
u8 status2; /* MCG Status 2 Register */
};
/*
......@@ -466,6 +496,39 @@ static void clock_pbe_to_pee(void)
KINETIS_MCG_S_CLKST_PLL);
}
#ifdef CONFIG_KINETIS_DDR
/*
* Configure the DDR clock for the DDR asynchronous mode
*/
static void clock_setup_ddr_async(void)
{
/*
* Configure the PLL1 input divider.
* Also, enable the PLL1 clock during Normal Stop.
* The input for the PLL1 is OSC0 (50 MHz from the PHY clock).
*/
KINETIS_MCG->c11 =
((KINETIS_PLL1_PRDIV - 1) << KINETIS_MCG_C11_PRDIV_BITS) |
KINETIS_MCG_C11_PLLSTEN1_MSK;
/*
* Set the PLL multiplication factor
*/
KINETIS_MCG->c12 = (KINETIS_PLL1_VDIV - KINETIS_PLL_VDIV_MIN) <<
KINETIS_MCG_C12_VDIV1_BITS;
/*
* Enable the PLL1
*/
KINETIS_MCG->c11 |= KINETIS_MCG_C11_PLLCLKEN1_MSK;
/*
* Wait for the PLL1 to acquire lock
*/
while (!(KINETIS_MCG->status2 & KINETIS_MCG_S2_LOCK1_MSK));
}
#endif /* CONFIG_KINETIS_DDR */
/*
* Set-up clocks
*/
......@@ -515,6 +578,13 @@ static void clock_setup(void)
*/
clock_pbe_to_pee();
#ifdef CONFIG_KINETIS_DDR
/*
* Configure the DDR clock for the DDR asynchronous mode
*/
clock_setup_ddr_async();
#endif /* CONFIG_KINETIS_DDR */
/*
* TBD: Configure the USB clock via KINETIS_SIM->sopt2::PLLFLLSEL
*/
......@@ -548,6 +618,13 @@ void clock_init(void)
* The MAC internal module clock is OSC0ERCLK
*/
clock_val[CLOCK_MACCLK] = KINETIS_EXTAL_RATE;
#ifdef CONFIG_KINETIS_DDR
/*
* Set the DDR clock rate
*/
clock_val[CLOCK_DDRCLK] = KINETIS_DDR_RATE;
#endif /* CONFIG_KINETIS_DDR */
}
/*
......
......@@ -88,6 +88,55 @@ typedef u32 kinetis_clock_gate_t;
#define KINETIS_CG_PORTE KINETIS_MKCG(4, 13) /* SIM_SCGC5[13] */
/* ENET */
#define KINETIS_CG_ENET KINETIS_MKCG(1, 0) /* SIM_SCGC2[0] */
/* DDR */
#define KINETIS_CG_DDR KINETIS_MKCG(2, 14) /* SIM_SCGC3[14] */
/*
* Limits for the `kinetis_periph_enable()` function:
* 1. The number of SIM_SCGC[] registers
* 2. The number of bits in those registers
*/
#define KINETIS_SIM_CG_NUMREGS 7
#define KINETIS_SIM_CG_NUMBITS 32
/*
* System Integration Module (SIM) register map
*
* This map actually covers two hardware modules:
* 1. SIM low-power logic, at 0x40047000
* 2. System integration module (SIM), at 0x40048000
*/
struct kinetis_sim_regs {
u32 sopt1; /* System Options Register 1 */
u32 rsv0[1024];
u32 sopt2; /* System Options Register 2 */
u32 rsv1;
u32 sopt4; /* System Options Register 4 */
u32 sopt5; /* System Options Register 5 */
u32 sopt6; /* System Options Register 6 */
u32 sopt7; /* System Options Register 7 */
u32 rsv2[2];
u32 sdid; /* System Device Identification Register */
u32 scgc[KINETIS_SIM_CG_NUMREGS]; /* Clock Gating Regs 1...7 */
u32 clkdiv1; /* System Clock Divider Register 1 */
u32 clkdiv2; /* System Clock Divider Register 2 */
u32 fcfg1; /* Flash Configuration Register 1 */
u32 fcfg2; /* Flash Configuration Register 2 */
u32 uidh; /* Unique Identification Register High */
u32 uidmh; /* Unique Identification Register Mid-High */
u32 uidml; /* Unique Identification Register Mid Low */
u32 uidl; /* Unique Identification Register Low */
u32 clkdiv3; /* System Clock Divider Register 3 */
u32 clkdiv4; /* System Clock Divider Register 4 */
u32 mcr; /* Misc Control Register */
};
/*
* SIM registers base
*/
#define KINETIS_SIM_BASE (KINETIS_AIPS0PERIPH_BASE + 0x00047000)
#define KINETIS_SIM ((volatile struct kinetis_sim_regs *) \
KINETIS_SIM_BASE)
/*
* Enable or disable the clock on a peripheral device (timers, UARTs, USB, etc)
......@@ -102,6 +151,9 @@ enum clock {
CLOCK_CCLK, /* Core clock frequency expressed in Hz */
CLOCK_PCLK, /* Bus clock frequency expressed in Hz */
CLOCK_MACCLK, /* MAC module clock frequency expressed in Hz */
#ifdef CONFIG_KINETIS_DDR
CLOCK_DDRCLK, /* DDR clock frequency expressed in Hz */
#endif /* CONFIG_KINETIS_DDR */
CLOCK_END /* for internal usage */
};
......
......@@ -148,6 +148,7 @@
*
* There is no DDR controller on the K60N512 MCU.
*/
#undef CONFIG_KINETIS_DDR
#define CONFIG_NR_DRAM_BANKS 1
#define CONFIG_SYS_RAM_CS 0
#define CONFIG_SYS_RAM_BASE 0x60000000
......
......@@ -102,6 +102,10 @@
#define KINETIS_PLL_PRDIV 5
/* PLL multiplier: 10*24/2 = 120 MHz */
#define KINETIS_PLL_VDIV 24
/* PLL1 input divider: 50/5 = 10 MHz */
#define KINETIS_PLL1_PRDIV 5
/* PLL1 multiplier: 10*30/2 = 150 MHz */
#define KINETIS_PLL1_VDIV 30
/*
* Number of clock ticks in 1 sec
*/
......@@ -147,6 +151,7 @@
/*
* Configuration of the external DDR2 SDRAM memory
*/
#define CONFIG_KINETIS_DDR
#define CONFIG_NR_DRAM_BANKS 1
#define CONFIG_SYS_RAM_CS 0
#define CONFIG_SYS_RAM_BASE 0x80000000
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment