Add support for AMCC Bamboo PPC440EP eval board
[platform/kernel/u-boot.git] / cpu / ppc4xx / start.S
index baaaba4..788c71c 100644 (file)
        GOT_ENTRY(_end_of_vectors)
        GOT_ENTRY(transfer_to_handler)
 
+       GOT_ENTRY(__init_end)
        GOT_ENTRY(_end)
-       GOT_ENTRY(.bss)
+       GOT_ENTRY(__bss_start)
        END_GOT
 
 /*
@@ -165,7 +166,12 @@ _start_440:
        mtspr   srr1,r0
        mtspr   csrr0,r0
        mtspr   csrr1,r0
-
+#if defined (CONFIG_440_GX) /* NOTE: 440GX adds machine check status regs */
+       mtspr   mcsrr0,r0
+       mtspr   mcsrr1,r0
+       mfspr   r1, mcsr
+       mtspr   mcsr,r1
+#endif
        /*----------------------------------------------------------------*/
        /* Initialize debug */
        /*----------------------------------------------------------------*/
@@ -297,7 +303,7 @@ _start_440:
        mflr    r1
        mtspr   srr0,r1
        rfi
-#endif
+#endif /* CONFIG_440 */
 
 /*
  * r3 - 1st arg to board_init(): IMMP pointer
@@ -334,9 +340,23 @@ _start:
        mtspr   tcr,r0                  /* disable all */
        mtspr   esr,r0                  /* clear exception syndrome register */
        mtxer   r0                      /* clear integer exception register */
+#if !defined(CONFIG_440_GX)
        lis     r1,0x0002               /* set CE bit (Critical Exceptions) */
        ori     r1,r1,0x1000            /* set ME bit (Machine Exceptions) */
        mtmsr   r1                      /* change MSR */
+#elif !defined(CONFIG_440_EP) && !defined(CONFIG_440_GR)
+       bl      __440gx_msr_set
+       b       __440gx_msr_continue
+
+__440gx_msr_set:
+       lis     r1, 0x0002              /* set CE bit (Critical Exceptions) */
+       ori     r1,r1,0x1000    /* set ME bit (Machine Exceptions) */
+       mtspr   srr1,r1
+       mflr    r1
+       mtspr   srr0,r1
+       rfi
+__440gx_msr_continue:
+#endif
 
        /*----------------------------------------------------------------*/
        /* Debug setup -- some (not very good) ice's need an event*/
@@ -357,6 +377,26 @@ _start:
        /* Setup the internal SRAM */
        /*----------------------------------------------------------------*/
        li      r0,0
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+       /* Clear Dcache to use as RAM */
+        addis   r3,r0,CFG_INIT_RAM_ADDR@h
+        ori     r3,r3,CFG_INIT_RAM_ADDR@l
+        addis   r4,r0,CFG_INIT_RAM_END@h
+        ori     r4,r4,CFG_INIT_RAM_END@l
+       rlwinm. r5,r4,0,27,31
+       rlwinm  r5,r4,27,5,31
+       beq     ..d_ran
+       addi    r5,r5,0x0001
+..d_ran:
+       mtctr   r5
+..d_ag:
+       dcbz    r0,r3
+       addi    r3,r3,32
+       bdnz    ..d_ag
+#else
+#if defined (CONFIG_440_GX)
+       mtdcr   l2_cache_cfg,r0         /* Ensure L2 Cache is off */
+#endif
        mtdcr   isram0_sb1cr,r0         /* Disable bank 1 */
 
        li      r2,0x7fff
@@ -369,8 +409,23 @@ _start:
        mtdcr   isram0_pmeg,r1
 
        lis     r1,0x8000               /* BAS = 8000_0000 */
+#if defined(CONFIG_440_GX)
+       ori     r1,r1,0x0980            /* first 64k */
+       mtdcr   isram0_sb0cr,r1
+       lis     r1,0x8001
+       ori     r1,r1,0x0980            /* second 64k */
+       mtdcr   isram0_sb1cr,r1
+       lis     r1, 0x8002
+       ori     r1,r1, 0x0980           /* third 64k */
+       mtdcr   isram0_sb2cr,r1
+       lis     r1, 0x8003
+       ori     r1,r1, 0x0980           /* fourth 64k */
+       mtdcr   isram0_sb3cr,r1
+#else
        ori     r1,r1,0x0380            /* 8k rw */
        mtdcr   isram0_sb0cr,r1
+#endif
+#endif
 
        /*----------------------------------------------------------------*/
        /* Setup the stack in internal SRAM */
@@ -504,7 +559,7 @@ _start:
 #endif /* CONFIG_IOP480 */
 
 /*****************************************************************************/
-#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405)
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405) || defined(CONFIG_405EP)
        /*----------------------------------------------------------------------- */
        /* Clear and set up some registers. */
        /*----------------------------------------------------------------------- */
@@ -551,26 +606,37 @@ _start:
        bl      ext_bus_cntlr_init
 #endif
 
+#if defined(CONFIG_405EP)
+       /*----------------------------------------------------------------------- */
+       /* DMA Status, clear to come up clean */
+       /*----------------------------------------------------------------------- */
+       addis   r3,r0, 0xFFFF         /* Clear all existing DMA status */
+       ori     r3,r3, 0xFFFF
+       mtdcr   dmasr, r3
+
+       bl      ppc405ep_init         /* do ppc405ep specific init */
+#endif /* CONFIG_405EP */
+
 #if defined(CFG_OCM_DATA_ADDR) && defined(CFG_OCM_DATA_SIZE)
        /********************************************************************
         * Setup OCM - On Chip Memory
         *******************************************************************/
        /* Setup OCM */
-       lis     r0, 0x7FFF
-       ori     r0, r0, 0xFFFF
-       mfdcr   r3, ocmiscntl           /* get instr-side IRAM config */
-       mfdcr   r4, ocmdscntl   /* get data-side IRAM config */
-       and     r3, r3, r0      /* disable data-side IRAM */
-       and     r4, r4, r0      /* disable data-side IRAM */
-       mtdcr   ocmiscntl, r3   /* set instr-side IRAM config */
-       mtdcr   ocmdscntl, r4   /* set data-side IRAM config */
-       isync
+       lis     r0, 0x7FFF
+       ori     r0, r0, 0xFFFF
+       mfdcr   r3, ocmiscntl           /* get instr-side IRAM config */
+       mfdcr   r4, ocmdscntl   /* get data-side IRAM config */
+       and     r3, r3, r0      /* disable data-side IRAM */
+       and     r4, r4, r0      /* disable data-side IRAM */
+       mtdcr   ocmiscntl, r3   /* set instr-side IRAM config */
+       mtdcr   ocmdscntl, r4   /* set data-side IRAM config */
+       isync
 
        addis   r3, 0, CFG_OCM_DATA_ADDR@h /* OCM location */
        mtdcr   ocmdsarc, r3
        addis   r4, 0, 0xC000           /* OCM data area enabled */
        mtdcr   ocmdscntl, r4
-       isync
+       isync
 #endif
 
        /*----------------------------------------------------------------------- */
@@ -685,14 +751,16 @@ _start:
 
        GET_GOT                 /* initialize GOT access                        */
 
-               bl      cpu_init_f      /* run low-level CPU init code     (from Flash) */
+       bl      cpu_init_f      /* run low-level CPU init code     (from Flash) */
 
        /* NEVER RETURNS! */
        bl      board_init_f    /* run first part of init code (from Flash)     */
 
-#endif /* CONFIG_405GP || CONFIG_405CR */
+#endif /* CONFIG_405GP || CONFIG_405CR || CONFIG_405 || CONFIG_405EP */
+       /*----------------------------------------------------------------------- */
 
 
+/*****************************************************************************/
        .globl  _start_of_vectors
 _start_of_vectors:
 
@@ -703,7 +771,7 @@ _start_of_vectors:
 #endif
 
 /* Machine check */
-       STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
+       CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
 
 /* Data Storage exception. */
        STD_EXCEPTION(0x300, DataStorage, UnknownException)
@@ -756,61 +824,7 @@ ProgramCheck:
        STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
        STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
        STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
-
-       . = 0xc00
-/*
- * r0 - SYSCALL number
- * r3-... arguments
- */
-SystemCall:
-       addis   r11,r0,0                /* get functions table addr */
-       ori     r11,r11,0               /* Note: this code is patched in trap_init */
-       addis   r12,r0,0                /* get number of functions */
-       ori     r12,r12,0
-
-       cmplw   0, r0, r12
-       bge     1f
-
-       rlwinm  r0,r0,2,0,31            /* fn_addr = fn_tbl[r0] */
-       add     r11,r11,r0
-       lwz     r11,0(r11)
-
-       li      r12,0xd00-4*3           /* save LR & SRRx */
-       mflr    r0
-       stw     r0,0(r12)
-       mfspr   r0,SRR0
-       stw     r0,4(r12)
-       mfspr   r0,SRR1
-       stw     r0,8(r12)
-
-       li      r12,0xc00+_back-SystemCall
-       mtlr    r12
-       mtspr   SRR0,r11
-
-1:     SYNC
-       rfi
-
-_back:
-
-       mfmsr   r11                     /* Disable interrupts */
-       li      r12,0
-       ori     r12,r12,MSR_EE
-       andc    r11,r11,r12
-       SYNC                            /* Some chip revs need this... */
-       mtmsr   r11
-       SYNC
-
-       li      r12,0xd00-4*3           /* restore regs */
-       lwz     r11,0(r12)
-       mtlr    r11
-       lwz     r11,4(r12)
-       mtspr   SRR0,r11
-       lwz     r11,8(r12)
-       mtspr   SRR1,r11
-
-       SYNC
-       rfi
-
+       STD_EXCEPTION(0xc00, SystemCall, UnknownException)
        STD_EXCEPTION(0xd00, SingleStep, UnknownException)
 
        STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
@@ -961,7 +975,12 @@ invalidate_icache:
 invalidate_dcache:
        addi    r6,0,0x0000             /* clear GPR 6 */
        /* Do loop for # of dcache congruence classes. */
+#if defined(CONFIG_440_GX) || defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+       lis     r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha       /* TBS for large sized cache */
+       ori     r7, r7, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
+#else
        addi    r7,r0, (CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)
+#endif
                                        /* NOTE: dccci invalidates both */
        mtctr   r7                      /* ways in the D cache */
 ..dcloop:
@@ -982,8 +1001,15 @@ flush_dcache:
        mtdccr  r10
 
        /* do loop for # of congruence classes. */
+#if defined(CONFIG_440_GX) || defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+       lis     r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@ha       /* TBS: for large cache sizes */
+       ori     r10,r10,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)@l
+       lis     r11,(CFG_DCACHE_SIZE / 2)@ha /* D cache set size - 2 way sets */
+       ori     r11,r11,(CFG_DCACHE_SIZE / 2)@l /* D cache set size - 2 way sets */
+#else
        addi    r10,r0,(CFG_DCACHE_SIZE / CFG_CACHELINE_SIZE / 2)
        addi    r11,r0,(CFG_DCACHE_SIZE / 2) /* D cache set size - 2 way sets */
+#endif
        mtctr   r10
        addi    r10,r0,(0xE000-0x10000) /* start at 0xFFFFE000 */
        add     r11,r10,r11             /* add to get to other side of cache line */
@@ -1202,6 +1228,15 @@ ppcSync:
  */
        .globl  relocate_code
 relocate_code:
+#if defined(CONFIG_440_EP) || defined(CONFIG_440_GR)
+       dccci   0,0                         /* Invalidate data cache, now no longer our stack */
+       sync
+       addi    r1,r0,0x0000        /* Tlb entry #0 */
+       tlbre   r0,r1,0x0002            /* Read contents */
+       ori     r0,r0,0x0c00        /* Or in the inhibit, write through bit */
+       tlbwe   r0,r1,0x0002            /* Save it out */
+       isync
+#endif
        mr      r1,  r3         /* Set new stack pointer                */
        mr      r9,  r4         /* Save copy of Init Data pointer       */
        mr      r10, r5         /* Save copy of Destination Address     */
@@ -1209,8 +1244,8 @@ relocate_code:
        mr      r3,  r5                         /* Destination Address  */
        lis     r4, CFG_MONITOR_BASE@h          /* Source      Address  */
        ori     r4, r4, CFG_MONITOR_BASE@l
-       lis     r5, CFG_MONITOR_LEN@h           /* Length in Bytes      */
-       ori     r5, r5, CFG_MONITOR_LEN@l
+       lwz     r5, GOT(__init_end)
+       sub     r5, r5, r4
        li      r6, CFG_CACHELINE_SIZE          /* Cache Line Size      */
 
        /*
@@ -1325,7 +1360,7 @@ clear_bss:
        /*
         * Now clear BSS segment
         */
-       lwz     r3,GOT(.bss)
+       lwz     r3,GOT(__bss_start)
        lwz     r4,GOT(_end)
 
        cmplw   0, r3, r4
@@ -1343,12 +1378,6 @@ clear_bss:
        mr      r4, r10         /* Destination Address          */
        bl      board_init_r
 
-       /* Problems accessing "end" in C, so do it here */
-       .globl  get_endaddr
-get_endaddr:
-       lwz     r3,GOT(_end)
-       blr
-
        /*
         * Copy exception vector code to low memory
         *
@@ -1360,7 +1389,7 @@ trap_init:
        lwz     r7, GOT(_start)
        lwz     r8, GOT(_end_of_vectors)
 
-       rlwinm  r9, r7, 0, 18, 31       /* _start & 0x3FFF      */
+       li      r9, 0x100               /* reset vector always at 0x100 */
 
        cmplw   0, r7, r8
        bgelr                           /* return if r7>=r8 - just in case */
@@ -1423,3 +1452,244 @@ trap_reloc:
        stw     r0, 4(r7)
 
        blr
+
+
+/**************************************************************************/
+/* PPC405EP specific stuff                                                */
+/**************************************************************************/
+#ifdef CONFIG_405EP
+ppc405ep_init:
+
+#ifdef CONFIG_BUBINGA
+       /*
+        * Initialize EBC chip selects 1 & 4 and GPIO pins (for alternate
+        * function) to support FPGA and NVRAM accesses below.
+        */
+
+       lis     r3,GPIO0_OSRH@h         /* config GPIO output select */
+       ori     r3,r3,GPIO0_OSRH@l
+       lis     r4,CFG_GPIO0_OSRH@h
+       ori     r4,r4,CFG_GPIO0_OSRH@l
+       stw     r4,0(r3)
+       lis     r3,GPIO0_OSRL@h
+       ori     r3,r3,GPIO0_OSRL@l
+       lis     r4,CFG_GPIO0_OSRL@h
+       ori     r4,r4,CFG_GPIO0_OSRL@l
+       stw     r4,0(r3)
+
+       lis     r3,GPIO0_ISR1H@h        /* config GPIO input select */
+       ori     r3,r3,GPIO0_ISR1H@l
+       lis     r4,CFG_GPIO0_ISR1H@h
+       ori     r4,r4,CFG_GPIO0_ISR1H@l
+       stw     r4,0(r3)
+       lis     r3,GPIO0_ISR1L@h
+       ori     r3,r3,GPIO0_ISR1L@l
+       lis     r4,CFG_GPIO0_ISR1L@h
+       ori     r4,r4,CFG_GPIO0_ISR1L@l
+       stw     r4,0(r3)
+
+       lis     r3,GPIO0_TSRH@h         /* config GPIO three-state select */
+       ori     r3,r3,GPIO0_TSRH@l
+       lis     r4,CFG_GPIO0_TSRH@h
+       ori     r4,r4,CFG_GPIO0_TSRH@l
+       stw     r4,0(r3)
+       lis     r3,GPIO0_TSRL@h
+       ori     r3,r3,GPIO0_TSRL@l
+       lis     r4,CFG_GPIO0_TSRL@h
+       ori     r4,r4,CFG_GPIO0_TSRL@l
+       stw     r4,0(r3)
+
+       lis     r3,GPIO0_TCR@h          /* config GPIO driver output enables */
+       ori     r3,r3,GPIO0_TCR@l
+       lis     r4,CFG_GPIO0_TCR@h
+       ori     r4,r4,CFG_GPIO0_TCR@l
+       stw     r4,0(r3)
+
+       li      r3,pb1ap                /* program EBC bank 1 for RTC access */
+       mtdcr   ebccfga,r3
+       lis     r3,CFG_EBC_PB1AP@h
+       ori     r3,r3,CFG_EBC_PB1AP@l
+       mtdcr   ebccfgd,r3
+       li      r3,pb1cr
+       mtdcr   ebccfga,r3
+       lis     r3,CFG_EBC_PB1CR@h
+       ori     r3,r3,CFG_EBC_PB1CR@l
+       mtdcr   ebccfgd,r3
+
+       li      r3,pb1ap                /* program EBC bank 1 for RTC access */
+       mtdcr   ebccfga,r3
+       lis     r3,CFG_EBC_PB1AP@h
+       ori     r3,r3,CFG_EBC_PB1AP@l
+       mtdcr   ebccfgd,r3
+       li      r3,pb1cr
+       mtdcr   ebccfga,r3
+       lis     r3,CFG_EBC_PB1CR@h
+       ori     r3,r3,CFG_EBC_PB1CR@l
+       mtdcr   ebccfgd,r3
+
+       li      r3,pb4ap                /* program EBC bank 4 for FPGA access */
+       mtdcr   ebccfga,r3
+       lis     r3,CFG_EBC_PB4AP@h
+       ori     r3,r3,CFG_EBC_PB4AP@l
+       mtdcr   ebccfgd,r3
+       li      r3,pb4cr
+       mtdcr   ebccfga,r3
+       lis     r3,CFG_EBC_PB4CR@h
+       ori     r3,r3,CFG_EBC_PB4CR@l
+       mtdcr   ebccfgd,r3
+#endif
+
+       addi    r3,0,CPC0_PCI_HOST_CFG_EN
+#ifdef CONFIG_BUBINGA
+       /*
+       !-----------------------------------------------------------------------
+       ! Check FPGA for PCI internal/external arbitration
+       !   If board is set to internal arbitration, update cpc0_pci
+       !-----------------------------------------------------------------------
+       */
+       addis   r5,r0,FPGA_REG1@h      /* set offset for FPGA_REG1 */
+       ori     r5,r5,FPGA_REG1@l
+       lbz     r5,0x0(r5)              /* read to get PCI arb selection */
+       andi.   r6,r5,FPGA_REG1_PCI_INT_ARB  /* using internal arbiter ?*/
+       beq     ..pci_cfg_set             /* if not set, then bypass reg write*/
+#endif
+       ori     r3,r3,CPC0_PCI_ARBIT_EN
+..pci_cfg_set:
+       mtdcr   CPC0_PCI, r3             /* Enable internal arbiter*/
+
+       /*
+       !-----------------------------------------------------------------------
+       ! Check to see if chip is in bypass mode.
+       ! If so, write stored CPC0_PLLMR0 and CPC0_PLLMR1 values and perform a
+       ! CPU reset   Otherwise, skip this step and keep going.
+       ! Note:  Running BIOS in bypass mode is not supported since PLB speed
+       !        will not be fast enough for the SDRAM (min 66MHz)
+       !-----------------------------------------------------------------------
+       */
+       mfdcr   r5, CPC0_PLLMR1
+       rlwinm  r4,r5,1,0x1            /* get system clock source (SSCS) */
+       cmpi    cr0,0,r4,0x1
+
+       beq    pll_done                   /* if SSCS =b'1' then PLL has */
+                                         /* already been set */
+                                         /* and CPU has been reset */
+                                         /* so skip to next section */
+
+#ifdef CONFIG_BUBINGA
+       /*
+       !-----------------------------------------------------------------------
+       ! Read NVRAM to get value to write in PLLMR.
+       ! If value has not been correctly saved, write default value
+       ! Default config values (assuming on-board 33MHz SYS_CLK) are above.
+       ! See CPU_DEFAULT_200 and CPU_DEFAULT_266 above.
+       !
+       ! WARNING:  This code assumes the first three words in the nvram_t
+       !           structure in openbios.h.  Changing the beginning of
+       !           the structure will break this code.
+       !
+       !-----------------------------------------------------------------------
+       */
+       addis   r3,0,NVRAM_BASE@h
+       addi    r3,r3,NVRAM_BASE@l
+
+       lwz     r4, 0(r3)
+       addis   r5,0,NVRVFY1@h
+       addi    r5,r5,NVRVFY1@l
+       cmp     cr0,0,r4,r5            /* Compare 1st NVRAM Magic number*/
+       bne     ..no_pllset
+       addi    r3,r3,4
+       lwz     r4, 0(r3)
+       addis   r5,0,NVRVFY2@h
+       addi    r5,r5,NVRVFY2@l
+       cmp     cr0,0,r4,r5            /* Compare 2 NVRAM Magic number */
+       bne     ..no_pllset
+       addi    r3,r3,8                 /* Skip over conf_size */
+       lwz     r4, 4(r3)               /* Load PLLMR1 value from NVRAM */
+       lwz     r3, 0(r3)               /* Load PLLMR0 value from NVRAM */
+       rlwinm  r5,r4,1,0x1             /* get system clock source (SSCS) */
+       cmpi     cr0,0,r5,1             /* See if PLL is locked */
+       beq     pll_write
+..no_pllset:
+#endif /* CONFIG_BUBINGA */
+
+       addis   r3,0,PLLMR0_DEFAULT@h       /* PLLMR0 default value */
+       ori     r3,r3,PLLMR0_DEFAULT@l     /* */
+       addis   r4,0,PLLMR1_DEFAULT@h       /* PLLMR1 default value */
+       ori     r4,r4,PLLMR1_DEFAULT@l     /* */
+
+       b       pll_write                 /* Write the CPC0_PLLMR with new value */
+
+pll_done:
+       /*
+       !-----------------------------------------------------------------------
+       ! Clear Soft Reset Register
+       ! This is needed to enable PCI if not booting from serial EPROM
+       !-----------------------------------------------------------------------
+               */
+       addi    r3, 0, 0x0
+       mtdcr   CPC0_SRR, r3
+
+       addis    r3,0,0x0010
+       mtctr   r3
+pci_wait:
+       bdnz    pci_wait
+
+       blr                               /* return to main code */
+
+/*
+!-----------------------------------------------------------------------------
+! Function:     pll_write
+! Description:  Updates the value of the CPC0_PLLMR according to CMOS27E documentation
+!               That is:
+!                         1.  Pll is first disabled (de-activated by putting in bypass mode)
+!                         2.  PLL is reset
+!                         3.  Clock dividers are set while PLL is held in reset and bypassed
+!                         4.  PLL Reset is cleared
+!                         5.  Wait 100us for PLL to lock
+!                         6.  A core reset is performed
+! Input: r3 = Value to write to CPC0_PLLMR0
+! Input: r4 = Value to write to CPC0_PLLMR1
+! Output r3 = none
+!-----------------------------------------------------------------------------
+*/
+pll_write:
+       mfdcr  r5, CPC0_UCR
+       andis. r5,r5,0xFFFF
+       ori    r5,r5,0x0101              /* Stop the UART clocks */
+       mtdcr  CPC0_UCR,r5               /* Before changing PLL */
+
+       mfdcr  r5, CPC0_PLLMR1
+       rlwinm r5,r5,0,0x7FFFFFFF        /* Disable PLL */
+       mtdcr   CPC0_PLLMR1,r5
+       oris   r5,r5,0x4000              /* Set PLL Reset */
+       mtdcr   CPC0_PLLMR1,r5
+
+       mtdcr   CPC0_PLLMR0,r3           /* Set clock dividers */
+       rlwinm r5,r4,0,0x3FFFFFFF        /* Reset & Bypass new PLL dividers */
+       oris   r5,r5,0x4000              /* Set PLL Reset */
+       mtdcr   CPC0_PLLMR1,r5           /* Set clock dividers */
+       rlwinm r5,r5,0,0xBFFFFFFF        /* Clear PLL Reset */
+       mtdcr   CPC0_PLLMR1,r5
+
+               /*
+       ! Wait min of 100us for PLL to lock.
+       ! See CMOS 27E databook for more info.
+       ! At 200MHz, that means waiting 20,000 instructions
+                */
+       addi    r3,0,20000              /* 2000 = 0x4e20 */
+       mtctr   r3
+pll_wait:
+       bdnz    pll_wait
+
+       oris   r5,r5,0x8000             /* Enable PLL */
+       mtdcr   CPC0_PLLMR1,r5          /* Engage */
+
+       /*
+        * Reset CPU to guarantee timings are OK
+        * Not sure if this is needed...
+        */
+       addis r3,0,0x1000
+       mtspr dbcr0,r3               /* This will cause a CPU core reset, and */
+                                    /* execution will continue from the poweron */
+                                    /* vector of 0xfffffffc */
+#endif /* CONFIG_405EP */