9
0
Fork 0

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:
Sascha Hauer 2009-05-13 16:41:49 +02:00
parent c651bda2d5
commit 287700795c
2 changed files with 91 additions and 126 deletions

View File

@ -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

View File

@ -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);