pcm038: initialize PLLs in one step
We used to initialize the PLLs on PCM038 in two steps. The first was to initialize a basic setup so that all peripheral clocks run at their final speed and the second step was to push the processor to full speed after the PMIC has been initialized for the higher voltage. Do this in one step instead to get an easier setup. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
c651bda2d5
commit
287700795c
|
@ -104,6 +104,9 @@ config MACH_PCM038
|
|||
select HAS_CFI
|
||||
select ARCH_IMX27
|
||||
select MACH_HAS_LOWLEVEL_INIT
|
||||
select SPI
|
||||
select DRIVER_SPI_IMX
|
||||
select DRIVER_SPI_MC13783
|
||||
help
|
||||
Say Y here if you are using Phytec's phyCORE-i.MX27 (pcm038) equipped
|
||||
with a Freescale i.MX27 Processor
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <environment.h>
|
||||
#include <asm/arch/imx-regs.h>
|
||||
#include <fec.h>
|
||||
#include <notifier.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/armlinux.h>
|
||||
#include <asm/mach-types.h>
|
||||
|
@ -110,9 +111,6 @@ static struct device_d nand_dev = {
|
|||
static int pcm038_devices_init(void)
|
||||
{
|
||||
int i;
|
||||
struct device_d *nand, *dev;
|
||||
char *envdev = "no";
|
||||
|
||||
unsigned int mode[] = {
|
||||
PD0_AIN_FEC_TXD0,
|
||||
PD1_AIN_FEC_TXD1,
|
||||
|
@ -164,17 +162,100 @@ static int pcm038_devices_init(void)
|
|||
for (i = 0; i < ARRAY_SIZE(mode); i++)
|
||||
imx_gpio_mode(mode[i]);
|
||||
|
||||
PCCR0 |= PCCR0_CSPI1_EN;
|
||||
PCCR1 |= PCCR1_PERCLK2_EN;
|
||||
|
||||
spi_register_board_info(pcm038_spi_board_info, ARRAY_SIZE(pcm038_spi_board_info));
|
||||
register_device(&spi_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
device_initcall(pcm038_devices_init);
|
||||
|
||||
static struct device_d pcm038_serial_device = {
|
||||
.name = "imx_serial",
|
||||
.id = "cs0",
|
||||
.map_base = IMX_UART1_BASE,
|
||||
.size = 4096,
|
||||
.type = DEVICE_TYPE_CONSOLE,
|
||||
};
|
||||
|
||||
static int pcm038_power_init(void)
|
||||
{
|
||||
struct device_d *nand, *dev;
|
||||
char *envdev = "no";
|
||||
int i = 0;
|
||||
int ret;
|
||||
|
||||
ret = pmic_power();
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* wait for good power level */
|
||||
udelay(1000);
|
||||
|
||||
#define CSCR_VAL CSCR_USB_DIV(3) | \
|
||||
CSCR_SD_CNT(3) | \
|
||||
CSCR_MSHC_SEL | \
|
||||
CSCR_H264_SEL | \
|
||||
CSCR_SSI1_SEL | \
|
||||
CSCR_SSI2_SEL | \
|
||||
CSCR_MCU_SEL | \
|
||||
CSCR_ARM_SRC_MPLL | \
|
||||
CSCR_SP_SEL | \
|
||||
CSCR_ARM_DIV(0) | \
|
||||
CSCR_FPM_EN | \
|
||||
CSCR_SPEN | \
|
||||
CSCR_MPEN
|
||||
|
||||
CSCR &= ~CSCR_MCU_SEL;
|
||||
|
||||
/*
|
||||
* pll clock initialization - see section 3.4.3 of the i.MX27 manual
|
||||
*/
|
||||
MPCTL0 = IMX_PLL_PD(0) |
|
||||
IMX_PLL_MFD(51) |
|
||||
IMX_PLL_MFI(7) |
|
||||
IMX_PLL_MFN(35); /* MPLL = 2 * 26 * 3.83654 MHz = 199.5 MHz */
|
||||
|
||||
SPCTL0 = IMX_PLL_PD(1) |
|
||||
IMX_PLL_MFD(12) |
|
||||
IMX_PLL_MFI(9) |
|
||||
IMX_PLL_MFN(3); /* SPLL = 2 * 26 * 4.61538 MHz = 240 MHz */
|
||||
|
||||
/*
|
||||
* ARM clock = (399 MHz / 2) / (ARM divider = 1) = 200 MHz
|
||||
* AHB clock = (399 MHz / 3) / (AHB divider = 2) = 66.5 MHz
|
||||
* System clock (HCLK) = 133 MHz
|
||||
*/
|
||||
|
||||
CSCR = CSCR_VAL | CSCR_AHB_DIV(1) | CSCR_MPLL_RESTART | CSCR_SPLL_RESTART;
|
||||
|
||||
udelay(1000);
|
||||
|
||||
/* clock gating enable */
|
||||
GPCR = 0x00050f08;
|
||||
|
||||
PCDR0 = 0x130410c3;
|
||||
PCDR1 = 0x09030911;
|
||||
|
||||
/* Clocks have changed. Notify clients */
|
||||
clock_notifier_call_chain();
|
||||
|
||||
out:
|
||||
register_device(&pcm038_serial_device);
|
||||
register_device(&cfi_dev);
|
||||
register_device(&nand_dev);
|
||||
register_device(&sdram_dev);
|
||||
#if 0
|
||||
register_device(&sram_dev);
|
||||
#endif
|
||||
PCCR0 |= PCCR0_CSPI1_EN;
|
||||
PCCR1 |= PCCR1_PERCLK2_EN;
|
||||
|
||||
spi_register_board_info(pcm038_spi_board_info, ARRAY_SIZE(pcm038_spi_board_info));
|
||||
register_device(&spi_dev);
|
||||
/* Register the fec device after the PLL re-initialisation
|
||||
* as the fec depends on the (now higher) ipg clock
|
||||
*/
|
||||
register_device(&fec_dev);
|
||||
|
||||
switch ((GPCR & GPCR_BOOT_MASK) >> GPCR_BOOT_SHIFT) {
|
||||
case GPCR_BOOT_8BIT_NAND_2k:
|
||||
|
@ -210,67 +291,6 @@ static int pcm038_devices_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
device_initcall(pcm038_devices_init);
|
||||
|
||||
static struct device_d pcm038_serial_device = {
|
||||
.name = "imx_serial",
|
||||
.id = "cs0",
|
||||
.map_base = IMX_UART1_BASE,
|
||||
.size = 4096,
|
||||
.type = DEVICE_TYPE_CONSOLE,
|
||||
};
|
||||
|
||||
static int pcm038_console_init(void)
|
||||
{
|
||||
register_device(&pcm038_serial_device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
console_initcall(pcm038_console_init);
|
||||
|
||||
static int pcm038_power_init(void)
|
||||
{
|
||||
#ifdef CONFIG_DRIVER_SPI_MC13783
|
||||
int i = 0;
|
||||
int ret;
|
||||
|
||||
ret = pmic_power();
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
CSCR |= CSCR_UPDATE_DIS;
|
||||
|
||||
MPCTL0 = IMX_PLL_PD(0) |
|
||||
IMX_PLL_MFD(51) |
|
||||
IMX_PLL_MFI(7) |
|
||||
IMX_PLL_MFN(35);
|
||||
|
||||
/* wait for good power level */
|
||||
while (i++ < 128) {
|
||||
while (CCSR & CCSR_32K_SR);
|
||||
while (!(CCSR & CCSR_32K_SR));
|
||||
}
|
||||
i = 0;
|
||||
|
||||
CSCR |= CSCR_MPLL_RESTART;
|
||||
|
||||
while (!(MPCTL1 & MPCTL1_LF));
|
||||
|
||||
PCDR1 = 0x09030911;
|
||||
|
||||
out:
|
||||
#else
|
||||
#warning no pmic support enabled. your pcm038 will run on low speed
|
||||
#endif
|
||||
|
||||
/* Register the fec device after the PLL re-initialisation
|
||||
* as the fec depends on the (now higher) ipg clock
|
||||
*/
|
||||
register_device(&fec_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
late_initcall(pcm038_power_init);
|
||||
|
||||
#ifdef CONFIG_NAND_IMX_BOOT
|
||||
|
@ -280,61 +300,3 @@ void __bare_init nand_boot(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
static int pll_init(void)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
#define CSCR_VAL CSCR_USB_DIV(3) | \
|
||||
CSCR_SD_CNT(3) | \
|
||||
CSCR_MSHC_SEL | \
|
||||
CSCR_H264_SEL | \
|
||||
CSCR_SSI1_SEL | \
|
||||
CSCR_SSI2_SEL | \
|
||||
CSCR_MCU_SEL | \
|
||||
CSCR_SP_SEL | \
|
||||
CSCR_ARM_SRC_MPLL | \
|
||||
CSCR_ARM_DIV(0) | \
|
||||
CSCR_FPM_EN | \
|
||||
CSCR_SPEN | \
|
||||
CSCR_MPEN
|
||||
|
||||
CSCR = CSCR_VAL | CSCR_AHB_DIV(3);
|
||||
|
||||
/*
|
||||
* pll clock initialization - see section 3.4.3 of the i.MX27 manual
|
||||
*/
|
||||
MPCTL0 = IMX_PLL_PD(1) |
|
||||
IMX_PLL_MFD(51) |
|
||||
IMX_PLL_MFI(7) |
|
||||
IMX_PLL_MFN(35); /* MPLL = 2 * 26 * 3.83654 MHz = 199.5 MHz */
|
||||
|
||||
SPCTL0 = IMX_PLL_PD(1) |
|
||||
IMX_PLL_MFD(12) |
|
||||
IMX_PLL_MFI(9) |
|
||||
IMX_PLL_MFN(3); /* SPLL = 2 * 26 * 4.61538 MHz = 240 MHz */
|
||||
|
||||
/*
|
||||
* ARM clock = (399 MHz / 2) / (ARM divider = 1) = 200 MHz
|
||||
* AHB clock = (399 MHz / 3) / (AHB divider = 2) = 66.5 MHz
|
||||
* System clock (HCLK) = 133 MHz
|
||||
*/
|
||||
|
||||
CSCR = CSCR_VAL | CSCR_AHB_DIV(1) | CSCR_MPLL_RESTART | CSCR_SPLL_RESTART;
|
||||
|
||||
while (i++ < 1000) {
|
||||
while (CCSR & CCSR_32K_SR);
|
||||
while (!(CCSR & CCSR_32K_SR));
|
||||
}
|
||||
|
||||
/* clock gating enable */
|
||||
GPCR = 0x00050f08;
|
||||
|
||||
/* peripheral clock divider */
|
||||
PCDR0 = 0x130410c3; /* FIXME */
|
||||
PCDR1 = 0x09030908; /* PERDIV1=08 @133 MHz */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
core_initcall(pll_init);
|
||||
|
||||
|
|
Loading…
Reference in New Issue