From b867d705b6217fed505dd44cf539699b8a81733d Mon Sep 17 00:00:00 2001 From: stroese Date: Fri, 23 May 2003 11:18:02 +0000 Subject: [PATCH] PPC405EP support added. --- common/cmd_boot.c | 4 +- common/cmd_reginfo.c | 2 +- cpu/ppc4xx/405gp_enet.c | 6 +- cpu/ppc4xx/405gp_pci.c | 2 +- cpu/ppc4xx/cpu.c | 40 +++++-- cpu/ppc4xx/cpu_init.c | 27 ++++- cpu/ppc4xx/miiphy.c | 2 +- cpu/ppc4xx/spd_sdram.c | 46 +++++++- cpu/ppc4xx/speed.c | 125 +++++++++++++++++++- cpu/ppc4xx/start.S | 177 +++++++++++++++++++++++++++- include/asm-ppc/processor.h | 1 + include/asm-ppc/u-boot.h | 3 +- include/cmd_reginfo.h | 2 +- include/ppc405.h | 276 +++++++++++++++++++++++++++++++++++++++++++- 14 files changed, 686 insertions(+), 27 deletions(-) diff --git a/common/cmd_boot.c b/common/cmd_boot.c index c2897a2..4e5ffb0 100644 --- a/common/cmd_boot.c +++ b/common/cmd_boot.c @@ -75,10 +75,10 @@ int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) print_num ("immr_base", bd->bi_immr_base ); #endif print_num ("bootflags", bd->bi_bootflags ); -#if defined(CONFIG_405GP) || defined(CONFIG_405CR) +#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405EP) print_str ("procfreq", strmhz(buf, bd->bi_procfreq)); print_str ("plb_busfreq", strmhz(buf, bd->bi_plb_busfreq)); -#if defined(CONFIG_405GP) +#if defined(CONFIG_405GP) || defined(CONFIG_405EP) print_str ("pci_busfreq", strmhz(buf, bd->bi_pci_busfreq)); #endif #else diff --git a/common/cmd_reginfo.c b/common/cmd_reginfo.c index 954e937..198b9c7 100644 --- a/common/cmd_reginfo.c +++ b/common/cmd_reginfo.c @@ -90,7 +90,7 @@ int do_reginfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) */ /* DBU[dave@cray.com] For the CRAY-L1, but should be generically 405gp */ -#elif defined (CONFIG_405GP) +#elif defined (CONFIG_405GP) || defined(CONFIG_405EP) printf("\n405GP registers; MSR=%x\n",mfmsr()); printf ("\nUniversal Interrupt Controller Regs\n" "uicsr uicsrs uicer uiccr uicpr uictr uicmsr uicvr uicvcr" diff --git a/cpu/ppc4xx/405gp_enet.c b/cpu/ppc4xx/405gp_enet.c index 49e9e42..af3c1b7 100644 --- a/cpu/ppc4xx/405gp_enet.c +++ b/cpu/ppc4xx/405gp_enet.c @@ -80,7 +80,7 @@ #include #include "vecnum.h" -#if defined(CONFIG_405GP) || defined(CONFIG_440) +#if defined(CONFIG_405GP) || defined(CONFIG_440) || defined(CONFIG_405EP) #define EMAC_RESET_TIMEOUT 1000 /* 1000 ms reset timeout */ #define PHY_AUTONEGOTIATE_TIMEOUT 2000 /* 2000 ms autonegotiate timeout */ @@ -705,7 +705,7 @@ void mal_err (unsigned long isr, unsigned long uic, unsigned long maldef, mtdcr (maltxdeir, 0xC0000000); mtdcr (malrxdeir, 0x80000000); -#if 1 /*sr */ +#ifdef INFO_405_ENET printf ("\nMAL error occured.... ISR = %lx UIC = = %lx MAL_DEF = %lx MAL_ERR= %lx \n", isr, uic, maldef, mal_errr); #else @@ -716,7 +716,7 @@ void mal_err (unsigned long isr, unsigned long uic, unsigned long maldef, */ printf ("M"); /* just to see something upon mal error */ #endif -#endif /*sr */ +#endif eth_init (bis_save); /* start again... */ } diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/405gp_pci.c index fbd4d6d..7289523 100644 --- a/cpu/ppc4xx/405gp_pci.c +++ b/cpu/ppc4xx/405gp_pci.c @@ -78,7 +78,7 @@ #include #include -#if defined(CONFIG_405GP) +#if defined(CONFIG_405GP) || defined(CONFIG_405EP) #ifdef CONFIG_PCI diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c index 8532d28..095a0aa 100644 --- a/cpu/ppc4xx/cpu.c +++ b/cpu/ppc4xx/cpu.c @@ -48,17 +48,24 @@ static int do_chip_reset( unsigned long sys0, unsigned long sys1 ); int checkcpu (void) { -#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_IOP480) || defined(CONFIG_440) +#if defined(CONFIG_405GP) || \ + defined(CONFIG_405CR) || \ + defined(CONFIG_IOP480) || \ + defined(CONFIG_440) || \ + defined(CONFIG_405EP) uint pvr = get_pvr(); #endif -#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_IOP480) +#if defined(CONFIG_405GP) || \ + defined(CONFIG_405CR) || \ + defined(CONFIG_IOP480) || \ + defined(CONFIG_405EP) DECLARE_GLOBAL_DATA_PTR; ulong clock = gd->cpu_clk; char buf[32]; #endif -#if defined(CONFIG_405GP) || defined(CONFIG_405CR) +#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405EP) PPC405_SYS_INFO sys_info; puts ("CPU: "); @@ -75,6 +82,9 @@ int checkcpu (void) #if CONFIG_405CR puts("IBM PowerPC 405CR Rev. "); #endif +#if CONFIG_405EP + puts("IBM PowerPC 405EP Rev. "); +#endif switch (pvr) { case PVR_405GP_RB: case PVR_405GPR_RB: @@ -98,6 +108,7 @@ int checkcpu (void) putc('A'); break; case PVR_405CR_RB: + case PVR_405EP_RB: putc('B'); break; default: @@ -110,7 +121,7 @@ int checkcpu (void) sys_info.freqPLB / sys_info.pllOpbDiv / 1000000, sys_info.freqPLB / sys_info.pllExtBusDiv / 1000000); -#if CONFIG_405GP +#if defined(CONFIG_405GP) if (mfdcr(strap) & PSR_PCI_ASYNC_EN) printf(" PCI async ext clock used, "); else @@ -120,15 +131,27 @@ int checkcpu (void) printf("internal PCI arbiter enabled\n"); else printf("external PCI arbiter enabled\n"); +#elif defined(CONFIG_405EP) + if (mfdcr(cpc0_boot) & CPC0_BOOT_SEP) + printf(" IIC Boot EEPROM enabled\n"); + else + printf(" IIC Boot EEPROM disabled\n"); + printf(" PCI async ext clock used, "); + if (mfdcr(cpc0_pci) & CPC0_PCI_ARBIT_EN) + printf("internal PCI arbiter enabled\n"); + else + printf("external PCI arbiter enabled\n"); #endif +#if defined(CONFIG_405EP) + printf(" 16 kB I-Cache 16 kB D-Cache"); +#else if ((pvr | 0x00000001) == PVR_405GPR_RB) { printf(" 16 kB I-Cache 16 kB D-Cache"); } else { printf(" 16 kB I-Cache 8 kB D-Cache"); } - - +#endif #endif /* defined(CONFIG_405GP) || defined(CONFIG_405CR) */ #ifdef CONFIG_IOP480 @@ -213,7 +236,10 @@ unsigned long get_tbclk (void) get_sys_info(&sys_info); return (sys_info.freqProcessor); -#elif defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405) +#elif defined(CONFIG_405GP) || \ + defined(CONFIG_405CR) || \ + defined(CONFIG_405) || \ + defined(CONFIG_405EP) PPC405_SYS_INFO sys_info; diff --git a/cpu/ppc4xx/cpu_init.c b/cpu/ppc4xx/cpu_init.c index 1d149bc..ac34092 100644 --- a/cpu/ppc4xx/cpu_init.c +++ b/cpu/ppc4xx/cpu_init.c @@ -40,6 +40,24 @@ void cpu_init_f (void) { +#if defined(CONFIG_405EP) + /* + * GPIO0 setup (select GPIO or alternate function) + */ + out32(GPIO0_OSRH, CFG_GPIO0_OSRH); /* output select */ + out32(GPIO0_OSRL, CFG_GPIO0_OSRL); + out32(GPIO0_ISR1H, CFG_GPIO0_ISR1H); /* input select */ + out32(GPIO0_ISR1L, CFG_GPIO0_ISR1L); + out32(GPIO0_TSRH, CFG_GPIO0_TSRH); /* three-state select */ + out32(GPIO0_TSRL, CFG_GPIO0_TSRL); + out32(GPIO0_TCR, CFG_GPIO0_TCR); /* enable output driver for outputs */ + + /* + * Set EMAC noise filter bits + */ + mtdcr(cpc0_epctl, CPC0_EPRCSR_E0NFE | CPC0_EPRCSR_E1NFE); +#endif /* CONFIG_405EP */ + /* * External Bus Controller (EBC) Setup */ @@ -119,12 +137,14 @@ cpu_init_f (void) */ int cpu_init_r (void) { -#ifdef CONFIG_405GP +#if defined(CONFIG_405GP) || defined(CONFIG_405EP) DECLARE_GLOBAL_DATA_PTR; bd_t *bd = gd->bd; unsigned long reg; +#if defined(CONFIG_405GP) uint pvr = get_pvr(); +#endif /* * Write Ethernetaddress into on-chip register @@ -145,6 +165,7 @@ int cpu_init_r (void) reg |= bd->bi_enetaddr[5]; out32 (EMAC_IAL, reg); +#if defined(CONFIG_405GP) /* * Set edge conditioning circuitry on PPC405GPr * for compatibility to existing PPC405GP designs. @@ -152,7 +173,7 @@ int cpu_init_r (void) if ((pvr & 0xfffffff0) == (PVR_405GPR_RB & 0xfffffff0)) { mtdcr(ecr, 0x60606000); } - -#endif /* CONFIG_405GP */ +#endif /* defined(CONFIG_405GP) */ +#endif /* defined(CONFIG_405GP) || defined(CONFIG_405EP) */ return (0); } diff --git a/cpu/ppc4xx/miiphy.c b/cpu/ppc4xx/miiphy.c index 51ba471..c5a90a9 100644 --- a/cpu/ppc4xx/miiphy.c +++ b/cpu/ppc4xx/miiphy.c @@ -48,7 +48,7 @@ #include <405_mal.h> #include -#if defined(CONFIG_405GP) || defined(CONFIG_440) +#if defined(CONFIG_405GP) || defined(CONFIG_440) || defined(CONFIG_405EP) /***********************************************************/ diff --git a/cpu/ppc4xx/spd_sdram.c b/cpu/ppc4xx/spd_sdram.c index 9c1cac5..76aee2e 100644 --- a/cpu/ppc4xx/spd_sdram.c +++ b/cpu/ppc4xx/spd_sdram.c @@ -118,9 +118,11 @@ long int spd_sdram(int(read_spd)(uint addr)) int bank_cnt; int sdram0_pmit=0x07c00000; +#ifndef CONFIG_405EP /* not on PPC405EP */ int sdram0_besr0=-1; int sdram0_besr1=-1; int sdram0_eccesr=-1; +#endif int sdram0_ecccfg; int sdram0_rtr=0; @@ -153,8 +155,46 @@ long int spd_sdram(int(read_spd)(uint addr)) * Calculate the bus period, we do it this * way to minimize stack utilization. */ +#ifndef CONFIG_405EP tmp = (mfdcr(pllmd) >> (31-6)) & 0xf; /* get FBDV bits */ tmp = CONFIG_SYS_CLK_FREQ * tmp; /* get plb freq */ +#else + { + unsigned long freqCPU; + unsigned long pllmr0; + unsigned long pllmr1; + unsigned long pllFbkDiv; + unsigned long pllPlbDiv; + unsigned long pllmr0_ccdv; + + /* + * Read PLL Mode registers + */ + pllmr0 = mfdcr (cpc0_pllmr0); + pllmr1 = mfdcr (cpc0_pllmr1); + + pllFbkDiv = ((pllmr1 & PLLMR1_FBMUL_MASK) >> 20); + if (pllFbkDiv == 0) { + pllFbkDiv = 16; + } + pllPlbDiv = ((pllmr0 & PLLMR0_CPU_TO_PLB_MASK) >> 16) + 1; + + /* + * Determine CPU clock frequency + */ + pllmr0_ccdv = ((pllmr0 & PLLMR0_CPU_DIV_MASK) >> 20) + 1; + if (pllmr1 & PLLMR1_SSCS_MASK) { + freqCPU = (CONFIG_SYS_CLK_FREQ * pllFbkDiv) / pllmr0_ccdv; + } else { + freqCPU = CONFIG_SYS_CLK_FREQ / pllmr0_ccdv; + } + + /* + * Determine PLB clock frequency + */ + tmp = freqCPU / pllPlbDiv; + } +#endif bus_period = sdram_HZ_to_ns(tmp); /* get sdram speed */ /* Make shure we are using SDRAM */ @@ -414,8 +454,12 @@ long int spd_sdram(int(read_spd)(uint addr)) sdram0_cfg = 0; mtsdram0( mem_mcopt1, sdram0_cfg ); +#ifndef CONFIG_405EP /* not on PPC405EP */ mtsdram0( mem_besra , sdram0_besr0 ); mtsdram0( mem_besrb , sdram0_besr1 ); + mtsdram0( mem_ecccf , sdram0_ecccfg ); + mtsdram0( mem_eccerr, sdram0_eccesr ); +#endif mtsdram0( mem_rtr , sdram0_rtr ); mtsdram0( mem_pmit , sdram0_pmit ); mtsdram0( mem_mb0cf , sdram0_b0cr ); @@ -423,8 +467,6 @@ long int spd_sdram(int(read_spd)(uint addr)) mtsdram0( mem_mb2cf , sdram0_b2cr ); mtsdram0( mem_mb3cf , sdram0_b3cr ); mtsdram0( mem_sdtr1 , sdram0_tr ); - mtsdram0( mem_ecccf , sdram0_ecccfg ); - mtsdram0( mem_eccerr, sdram0_eccesr ); /* SDRAM have a power on delay, 500 micro should do */ udelay(500); diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c index f075e3a..fdefbb6 100644 --- a/cpu/ppc4xx/speed.c +++ b/cpu/ppc4xx/speed.c @@ -257,11 +257,132 @@ void get_sys_info (sys_info_t * sysInfo) { } +#elif defined(CONFIG_405EP) +void get_sys_info (PPC405_SYS_INFO * sysInfo) +{ + unsigned long pllmr0; + unsigned long pllmr1; + unsigned long sysClkPeriodPs = ONE_BILLION / (CONFIG_SYS_CLK_FREQ / 1000); + unsigned long m; + unsigned long pllmr0_ccdv; + + /* + * Read PLL Mode registers + */ + pllmr0 = mfdcr (cpc0_pllmr0); + pllmr1 = mfdcr (cpc0_pllmr1); + + /* + * Determine forward divider A + */ + sysInfo->pllFwdDiv = 8 - ((pllmr1 & PLLMR1_FWDVA_MASK) >> 16); + + /* + * Determine forward divider B (should be equal to A) + */ + sysInfo->pllFwdDivB = 8 - ((pllmr1 & PLLMR1_FWDVB_MASK) >> 12); + + /* + * Determine FBK_DIV. + */ + sysInfo->pllFbkDiv = ((pllmr1 & PLLMR1_FBMUL_MASK) >> 20); + if (sysInfo->pllFbkDiv == 0) { + sysInfo->pllFbkDiv = 16; + } + + /* + * Determine PLB_DIV. + */ + sysInfo->pllPlbDiv = ((pllmr0 & PLLMR0_CPU_TO_PLB_MASK) >> 16) + 1; + + /* + * Determine PCI_DIV. + */ + sysInfo->pllPciDiv = (pllmr0 & PLLMR0_PCI_TO_PLB_MASK) + 1; + + /* + * Determine EXTBUS_DIV. + */ + sysInfo->pllExtBusDiv = ((pllmr0 & PLLMR0_EXB_TO_PLB_MASK) >> 8) + 2; + + /* + * Determine OPB_DIV. + */ + sysInfo->pllOpbDiv = ((pllmr0 & PLLMR0_OPB_TO_PLB_MASK) >> 12) + 1; + + /* + * Determine the M factor + */ + m = sysInfo->pllFbkDiv * sysInfo->pllFwdDivB; + + /* + * Determine VCO clock frequency + */ + sysInfo->freqVCOMhz = (1000000 * m) / sysClkPeriodPs; + + /* + * Determine CPU clock frequency + */ + pllmr0_ccdv = ((pllmr0 & PLLMR0_CPU_DIV_MASK) >> 20) + 1; + if (pllmr1 & PLLMR1_SSCS_MASK) { + sysInfo->freqProcessor = (CONFIG_SYS_CLK_FREQ * sysInfo->pllFbkDiv) + / pllmr0_ccdv; + } else { + sysInfo->freqProcessor = CONFIG_SYS_CLK_FREQ / pllmr0_ccdv; + } + + /* + * Determine PLB clock frequency + */ + sysInfo->freqPLB = sysInfo->freqProcessor / sysInfo->pllPlbDiv; + + if (!((sysInfo->freqVCOMhz >= VCO_MIN) && (sysInfo->freqVCOMhz <= VCO_MAX))) { + printf ("\nInvalid VCO frequency calculated : %ld MHz \a\n", + sysInfo->freqVCOMhz); + printf ("It must be between %d-%d MHz \a\n", VCO_MIN, VCO_MAX); + printf ("PLL Mode reg 0 : %8.8lx\a\n", pllmr0); + printf ("PLL Mode reg 1 : %8.8lx\a\n", pllmr1); + hang (); + } +} + + +/******************************************** + * get_OPB_freq + * return OPB bus freq in Hz + *********************************************/ +ulong get_OPB_freq (void) +{ + ulong val = 0; + + PPC405_SYS_INFO sys_info; + + get_sys_info (&sys_info); + val = sys_info.freqPLB / sys_info.pllOpbDiv; + + return val; +} + + +/******************************************** + * get_PCI_freq + * return PCI bus freq in Hz + *********************************************/ +ulong get_PCI_freq (void) +{ + ulong val; + PPC405_SYS_INFO sys_info; + + get_sys_info (&sys_info); + val = sys_info.freqPLB / sys_info.pllPciDiv; + return val; +} + #endif int get_clocks (void) { -#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) || defined(CONFIG_405) +#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) || defined(CONFIG_405) || defined(CONFIG_405EP) DECLARE_GLOBAL_DATA_PTR; sys_info_t sys_info; @@ -290,7 +411,7 @@ ulong get_bus_freq (ulong dummy) { ulong val; -#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405) || defined(CONFIG_440) +#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405) || defined(CONFIG_440) || defined(CONFIG_405EP) sys_info_t sys_info; get_sys_info (&sys_info); diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S index c334f93..afe8635 100644 --- a/cpu/ppc4xx/start.S +++ b/cpu/ppc4xx/start.S @@ -297,7 +297,7 @@ _start_440: mflr r1 mtspr srr0,r1 rfi -#endif +#endif /* CONFIG_440 */ /* * r3 - 1st arg to board_init(): IMMP pointer @@ -504,7 +504,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,6 +551,17 @@ _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 @@ -693,6 +704,7 @@ _start: #endif /* CONFIG_405GP || CONFIG_405CR */ +/*****************************************************************************/ .globl _start_of_vectors _start_of_vectors: @@ -1437,3 +1449,164 @@ trap_reloc: stw r0, 4(r7) blr + + +/**************************************************************************/ +/* PPC405EP specific stuff */ +/**************************************************************************/ +#ifdef CONFIG_405EP +ppc405ep_init: + /* + !----------------------------------------------------------------------- + ! Check FPGA for PCI internal/external arbitration + ! If board is set to internal arbitration, update cpc0_pci + !----------------------------------------------------------------------- + */ + addi r3,0,CPC0_PCI_HOST_CFG_EN +#ifdef CONFIG_BUBINGA405EP + 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_BUBINGA405EP + /* + !----------------------------------------------------------------------- + ! 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_BUBINGA405EP */ + + 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 */ diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index dc04a8f..9c88b49 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -465,6 +465,7 @@ #define PVR_405GPR_RB 0x50910951 #define PVR_440GP_RB 0x40120440 #define PVR_440GP_RC 0x40120481 +#define PVR_405EP_RB 0x51210950 #define PVR_601 0x00010000 #define PVR_602 0x00050000 #define PVR_603 0x00030000 diff --git a/include/asm-ppc/u-boot.h b/include/asm-ppc/u-boot.h index 5e8f4b5..db563a5 100644 --- a/include/asm-ppc/u-boot.h +++ b/include/asm-ppc/u-boot.h @@ -57,7 +57,8 @@ typedef struct bd_info { #if defined(CONFIG_405GP) || \ defined(CONFIG_405CR) || \ defined(CONFIG_440) || \ - defined(CONFIG_405) + defined(CONFIG_405) || \ + defined(CONFIG_405EP) unsigned char bi_s_version[4]; /* Version of this structure */ unsigned char bi_r_version[32]; /* Version of the ROM (IBM) */ unsigned int bi_procfreq; /* CPU (Internal) Freq, in Hz */ diff --git a/include/cmd_reginfo.h b/include/cmd_reginfo.h index 6a67b36..8d71e7e 100644 --- a/include/cmd_reginfo.h +++ b/include/cmd_reginfo.h @@ -24,7 +24,7 @@ #ifndef _CMD_REGINFO_H_ #define _CMD_REGINFO_H_ -#if (defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_405GP)) && \ +#if (defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_405GP) || defined(CONFIG_405EP)) && \ (CONFIG_COMMANDS & CFG_CMD_REGINFO) #define CMD_TBL_REGINFO MK_CMD_TBL_ENTRY( \ "reginfo", 3, 2, 1, do_reginfo, \ diff --git a/include/ppc405.h b/include/ppc405.h index c99d591..243a22d 100644 --- a/include/ppc405.h +++ b/include/ppc405.h @@ -151,11 +151,13 @@ #define memcfga (SDRAM_DCR_BASE+0x0) /* Memory configuration address reg */ #define memcfgd (SDRAM_DCR_BASE+0x1) /* Memory configuration data reg */ /* values for memcfga register - indirect addressing of these regs */ +#ifndef CONFIG_405EP #define mem_besra 0x00 /* bus error syndrome reg a */ #define mem_besrsa 0x04 /* bus error syndrome reg set a */ #define mem_besrb 0x08 /* bus error syndrome reg b */ #define mem_besrsb 0x0c /* bus error syndrome reg set b */ #define mem_bear 0x10 /* bus error address reg */ +#endif #define mem_mcopt1 0x20 /* memory controller options 1 */ #define mem_rtr 0x30 /* refresh timer reg */ #define mem_pmit 0x34 /* power management idle timer */ @@ -164,8 +166,10 @@ #define mem_mb2cf 0x48 /* memory bank 2 configuration */ #define mem_mb3cf 0x4c /* memory bank 3 configuration */ #define mem_sdtr1 0x80 /* timing reg 1 */ +#ifndef CONFIG_405EP #define mem_ecccf 0x94 /* ECC configuration */ #define mem_eccerr 0x98 /* ECC error status */ +#endif /****************************************************************************** * Decompression Controller @@ -227,6 +231,255 @@ #define pbesr1 0x22 /* periph bus error status reg 1 */ #define epcr 0x23 /* external periph control reg */ +#ifdef CONFIG_405EP +/****************************************************************************** + * Control + ******************************************************************************/ +#define CNTRL_DCR_BASE 0x0f0 +#define cpc0_pllmr0 (CNTRL_DCR_BASE+0x0) /* PLL mode register 0 */ +#define cpc0_boot (CNTRL_DCR_BASE+0x1) /* Clock status register */ +#define cpc0_epctl (CNTRL_DCR_BASE+0x3) /* EMAC to PHY control register */ +#define cpc0_pllmr1 (CNTRL_DCR_BASE+0x4) /* PLL mode register 1 */ +#define cpc0_ucr (CNTRL_DCR_BASE+0x5) /* UART control register */ +#define cpc0_pci (CNTRL_DCR_BASE+0x9) /* PCI control register */ + +#define CPC0_PLLMR0 (CNTRL_DCR_BASE+0x0) /* PLL mode 0 register */ +#define CPC0_BOOT (CNTRL_DCR_BASE+0x1) /* Chip Clock Status register */ +#define CPC0_CR1 (CNTRL_DCR_BASE+0x2) /* Chip Control 1 register */ +#define CPC0_EPRCSR (CNTRL_DCR_BASE+0x3) /* EMAC PHY Rcv Clk Src register*/ +#define CPC0_PLLMR1 (CNTRL_DCR_BASE+0x4) /* PLL mode 1 register */ +#define CPC0_UCR (CNTRL_DCR_BASE+0x5) /* UART Control register */ +#define CPC0_SRR (CNTRL_DCR_BASE+0x6) /* Soft Reset register */ +#define CPC0_JTAGID (CNTRL_DCR_BASE+0x7) /* JTAG ID register */ +#define CPC0_SPARE (CNTRL_DCR_BASE+0x8) /* Spare DCR */ +#define CPC0_PCI (CNTRL_DCR_BASE+0x9) /* PCI Control register */ + +/* Bit definitions */ +#define PLLMR0_CPU_DIV_MASK 0x00300000 /* CPU clock divider */ +#define PLLMR0_CPU_DIV_BYPASS 0x00000000 +#define PLLMR0_CPU_DIV_2 0x00100000 +#define PLLMR0_CPU_DIV_3 0x00200000 +#define PLLMR0_CPU_DIV_4 0x00300000 + +#define PLLMR0_CPU_TO_PLB_MASK 0x00030000 /* CPU:PLB Frequency Divisor */ +#define PLLMR0_CPU_PLB_DIV_1 0x00000000 +#define PLLMR0_CPU_PLB_DIV_2 0x00010000 +#define PLLMR0_CPU_PLB_DIV_3 0x00020000 +#define PLLMR0_CPU_PLB_DIV_4 0x00030000 + +#define PLLMR0_OPB_TO_PLB_MASK 0x00003000 /* OPB:PLB Frequency Divisor */ +#define PLLMR0_OPB_PLB_DIV_1 0x00000000 +#define PLLMR0_OPB_PLB_DIV_2 0x00001000 +#define PLLMR0_OPB_PLB_DIV_3 0x00002000 +#define PLLMR0_OPB_PLB_DIV_4 0x00003000 + +#define PLLMR0_EXB_TO_PLB_MASK 0x00000300 /* External Bus:PLB Divisor */ +#define PLLMR0_EXB_PLB_DIV_2 0x00000000 +#define PLLMR0_EXB_PLB_DIV_3 0x00000100 +#define PLLMR0_EXB_PLB_DIV_4 0x00000200 +#define PLLMR0_EXB_PLB_DIV_5 0x00000300 + +#define PLLMR0_MAL_TO_PLB_MASK 0x00000030 /* MAL:PLB Divisor */ +#define PLLMR0_MAL_PLB_DIV_1 0x00000000 +#define PLLMR0_MAL_PLB_DIV_2 0x00000010 +#define PLLMR0_MAL_PLB_DIV_3 0x00000020 +#define PLLMR0_MAL_PLB_DIV_4 0x00000030 + +#define PLLMR0_PCI_TO_PLB_MASK 0x00000003 /* PCI:PLB Frequency Divisor */ +#define PLLMR0_PCI_PLB_DIV_1 0x00000000 +#define PLLMR0_PCI_PLB_DIV_2 0x00000001 +#define PLLMR0_PCI_PLB_DIV_3 0x00000002 +#define PLLMR0_PCI_PLB_DIV_4 0x00000003 + +#define PLLMR1_SSCS_MASK 0x80000000 /* Select system clock source */ +#define PLLMR1_PLLR_MASK 0x40000000 /* PLL reset */ +#define PLLMR1_FBMUL_MASK 0x00F00000 /* PLL feedback multiplier value */ +#define PLLMR1_FBMUL_DIV_16 0x00000000 +#define PLLMR1_FBMUL_DIV_1 0x00100000 +#define PLLMR1_FBMUL_DIV_2 0x00200000 +#define PLLMR1_FBMUL_DIV_3 0x00300000 +#define PLLMR1_FBMUL_DIV_4 0x00400000 +#define PLLMR1_FBMUL_DIV_5 0x00500000 +#define PLLMR1_FBMUL_DIV_6 0x00600000 +#define PLLMR1_FBMUL_DIV_7 0x00700000 +#define PLLMR1_FBMUL_DIV_8 0x00800000 +#define PLLMR1_FBMUL_DIV_9 0x00900000 +#define PLLMR1_FBMUL_DIV_10 0x00A00000 +#define PLLMR1_FBMUL_DIV_11 0x00B00000 +#define PLLMR1_FBMUL_DIV_12 0x00C00000 +#define PLLMR1_FBMUL_DIV_13 0x00D00000 +#define PLLMR1_FBMUL_DIV_14 0x00E00000 +#define PLLMR1_FBMUL_DIV_15 0x00F00000 + +#define PLLMR1_FWDVA_MASK 0x00070000 /* PLL forward divider A value */ +#define PLLMR1_FWDVA_DIV_8 0x00000000 +#define PLLMR1_FWDVA_DIV_7 0x00010000 +#define PLLMR1_FWDVA_DIV_6 0x00020000 +#define PLLMR1_FWDVA_DIV_5 0x00030000 +#define PLLMR1_FWDVA_DIV_4 0x00040000 +#define PLLMR1_FWDVA_DIV_3 0x00050000 +#define PLLMR1_FWDVA_DIV_2 0x00060000 +#define PLLMR1_FWDVA_DIV_1 0x00070000 +#define PLLMR1_FWDVB_MASK 0x00007000 /* PLL forward divider B value */ +#define PLLMR1_TUNING_MASK 0x000003FF /* PLL tune bits */ + +/* Defines for CPC0_EPRCSR register */ +#define CPC0_EPRCSR_E0NFE 0x80000000 +#define CPC0_EPRCSR_E1NFE 0x40000000 +#define CPC0_EPRCSR_E1RPP 0x00000080 +#define CPC0_EPRCSR_E0RPP 0x00000040 +#define CPC0_EPRCSR_E1ERP 0x00000020 +#define CPC0_EPRCSR_E0ERP 0x00000010 +#define CPC0_EPRCSR_E1PCI 0x00000002 +#define CPC0_EPRCSR_E0PCI 0x00000001 + +/* Defines for CPC0_PCI Register */ +#define CPC0_PCI_SPE 0x00000010 /* PCIINT/WE select */ +#define CPC0_PCI_HOST_CFG_EN 0x00000008 /* PCI host config Enable */ +#define CPC0_PCI_ARBIT_EN 0x00000001 /* PCI Internal Arb Enabled*/ + +/* Defines for CPC0_BOOR Register */ +#define CPC0_BOOT_SEP 0x00000002 /* serial EEPROM present */ + +/* Defines for CPC0_PLLMR1 Register fields */ +#define PLL_ACTIVE 0x80000000 +#define CPC0_PLLMR1_SSCS 0x80000000 +#define PLL_RESET 0x40000000 +#define CPC0_PLLMR1_PLLR 0x40000000 + /* Feedback multiplier */ +#define PLL_FBKDIV 0x00F00000 +#define CPC0_PLLMR1_FBDV 0x00F00000 +#define PLL_FBKDIV_16 0x00000000 +#define PLL_FBKDIV_1 0x00100000 +#define PLL_FBKDIV_2 0x00200000 +#define PLL_FBKDIV_3 0x00300000 +#define PLL_FBKDIV_4 0x00400000 +#define PLL_FBKDIV_5 0x00500000 +#define PLL_FBKDIV_6 0x00600000 +#define PLL_FBKDIV_7 0x00700000 +#define PLL_FBKDIV_8 0x00800000 +#define PLL_FBKDIV_9 0x00900000 +#define PLL_FBKDIV_10 0x00A00000 +#define PLL_FBKDIV_11 0x00B00000 +#define PLL_FBKDIV_12 0x00C00000 +#define PLL_FBKDIV_13 0x00D00000 +#define PLL_FBKDIV_14 0x00E00000 +#define PLL_FBKDIV_15 0x00F00000 + /* Forward A divisor */ +#define PLL_FWDDIVA 0x00070000 +#define CPC0_PLLMR1_FWDVA 0x00070000 +#define PLL_FWDDIVA_8 0x00000000 +#define PLL_FWDDIVA_7 0x00010000 +#define PLL_FWDDIVA_6 0x00020000 +#define PLL_FWDDIVA_5 0x00030000 +#define PLL_FWDDIVA_4 0x00040000 +#define PLL_FWDDIVA_3 0x00050000 +#define PLL_FWDDIVA_2 0x00060000 +#define PLL_FWDDIVA_1 0x00070000 + /* Forward B divisor */ +#define PLL_FWDDIVB 0x00007000 +#define CPC0_PLLMR1_FWDVB 0x00007000 +#define PLL_FWDDIVB_8 0x00000000 +#define PLL_FWDDIVB_7 0x00001000 +#define PLL_FWDDIVB_6 0x00002000 +#define PLL_FWDDIVB_5 0x00003000 +#define PLL_FWDDIVB_4 0x00004000 +#define PLL_FWDDIVB_3 0x00005000 +#define PLL_FWDDIVB_2 0x00006000 +#define PLL_FWDDIVB_1 0x00007000 + /* PLL tune bits */ +#define PLL_TUNE_MASK 0x000003FF +#define PLL_TUNE_2_M_3 0x00000133 /* 2 <= M <= 3 */ +#define PLL_TUNE_4_M_6 0x00000134 /* 3 < M <= 6 */ +#define PLL_TUNE_7_M_10 0x00000138 /* 6 < M <= 10 */ +#define PLL_TUNE_11_M_14 0x0000013C /* 10 < M <= 14 */ +#define PLL_TUNE_15_M_40 0x0000023E /* 14 < M <= 40 */ +#define PLL_TUNE_VCO_LOW 0x00000000 /* 500MHz <= VCO <= 800MHz */ +#define PLL_TUNE_VCO_HI 0x00000080 /* 800MHz < VCO <= 1000MHz */ + +/* Defines for CPC0_PLLMR0 Register fields */ + /* CPU divisor */ +#define PLL_CPUDIV 0x00300000 +#define CPC0_PLLMR0_CCDV 0x00300000 +#define PLL_CPUDIV_1 0x00000000 +#define PLL_CPUDIV_2 0x00100000 +#define PLL_CPUDIV_3 0x00200000 +#define PLL_CPUDIV_4 0x00300000 + /* PLB divisor */ +#define PLL_PLBDIV 0x00030000 +#define CPC0_PLLMR0_CBDV 0x00030000 +#define PLL_PLBDIV_1 0x00000000 +#define PLL_PLBDIV_2 0x00010000 +#define PLL_PLBDIV_3 0x00020000 +#define PLL_PLBDIV_4 0x00030000 + /* OPB divisor */ +#define PLL_OPBDIV 0x00003000 +#define CPC0_PLLMR0_OPDV 0x00003000 +#define PLL_OPBDIV_1 0x00000000 +#define PLL_OPBDIV_2 0x00001000 +#define PLL_OPBDIV_3 0x00002000 +#define PLL_OPBDIV_4 0x00003000 + /* EBC divisor */ +#define PLL_EXTBUSDIV 0x00000300 +#define CPC0_PLLMR0_EPDV 0x00000300 +#define PLL_EXTBUSDIV_2 0x00000000 +#define PLL_EXTBUSDIV_3 0x00000100 +#define PLL_EXTBUSDIV_4 0x00000200 +#define PLL_EXTBUSDIV_5 0x00000300 + /* MAL divisor */ +#define PLL_MALDIV 0x00000030 +#define CPC0_PLLMR0_MPDV 0x00000030 +#define PLL_MALDIV_1 0x00000000 +#define PLL_MALDIV_2 0x00000010 +#define PLL_MALDIV_3 0x00000020 +#define PLL_MALDIV_4 0x00000030 + /* PCI divisor */ +#define PLL_PCIDIV 0x00000003 +#define CPC0_PLLMR0_PPFD 0x00000003 +#define PLL_PCIDIV_1 0x00000000 +#define PLL_PCIDIV_2 0x00000001 +#define PLL_PCIDIV_3 0x00000002 +#define PLL_PCIDIV_4 0x00000003 + +/* + *------------------------------------------------------------------------------- + * PLL settings for 266MHz CPU, 133MHz PLB/SDRAM, 66MHz EBC, 33MHz PCI, + * assuming a 33.3MHz input clock to the 405EP. + *------------------------------------------------------------------------------- + */ +#define PLLMR0_266_133_66 (PLL_CPUDIV_1 | PLL_PLBDIV_2 | \ + PLL_OPBDIV_2 | PLL_EXTBUSDIV_2 | \ + PLL_MALDIV_1 | PLL_PCIDIV_4) +#define PLLMR1_266_133_66 (PLL_FBKDIV_8 | \ + PLL_FWDDIVA_3 | PLL_FWDDIVB_3 | \ + PLL_TUNE_15_M_40 | PLL_TUNE_VCO_LOW) + +#define PLLMR0_133_66_66_33 (PLL_CPUDIV_1 | PLL_PLBDIV_1 | \ + PLL_OPBDIV_2 | PLL_EXTBUSDIV_4 | \ + PLL_MALDIV_1 | PLL_PCIDIV_4) +#define PLLMR1_133_66_66_33 (PLL_FBKDIV_4 | \ + PLL_FWDDIVA_6 | PLL_FWDDIVB_6 | \ + PLL_TUNE_15_M_40 | PLL_TUNE_VCO_LOW) +#define PLLMR0_200_100_50_33 (PLL_CPUDIV_1 | PLL_PLBDIV_2 | \ + PLL_OPBDIV_2 | PLL_EXTBUSDIV_3 | \ + PLL_MALDIV_1 | PLL_PCIDIV_4) +#define PLLMR1_200_100_50_33 (PLL_FBKDIV_6 | \ + PLL_FWDDIVA_4 | PLL_FWDDIVB_4 | \ + PLL_TUNE_15_M_40 | PLL_TUNE_VCO_LOW) +#define PLLMR0_266_133_66_33 (PLL_CPUDIV_1 | PLL_PLBDIV_2 | \ + PLL_OPBDIV_2 | PLL_EXTBUSDIV_4 | \ + PLL_MALDIV_1 | PLL_PCIDIV_4) +#define PLLMR1_266_133_66_33 (PLL_FBKDIV_8 | \ + PLL_FWDDIVA_3 | PLL_FWDDIVB_3 | \ + PLL_TUNE_15_M_40 | PLL_TUNE_VCO_LOW) + +/* + * PLL Voltage Controlled Oscillator (VCO) definitions + * Maximum and minimum values (in MHz) for correct PLL operation. + */ +#define VCO_MIN 500 +#define VCO_MAX 1000 +#else /* #ifdef CONFIG_405EP */ /****************************************************************************** * Control ******************************************************************************/ @@ -236,7 +489,8 @@ #define cntrl1 (CNTRL_DCR_BASE+0x2) /* Control 1 register */ #define reset (CNTRL_DCR_BASE+0x3) /* reset register */ #define strap (CNTRL_DCR_BASE+0x4) /* strap register */ -#define ecr (0xAA) /* edge conditioning register (405GPr) */ + +#define ecr (0xaa) /* edge conditioner register (405gpr) */ /* Bit definitions */ #define PLLMR_FWD_DIV_MASK 0xE0000000 /* Forward Divisor */ @@ -300,6 +554,7 @@ */ #define VCO_MIN 400 #define VCO_MAX 800 +#endif /* #ifdef CONFIG_405EP */ /****************************************************************************** * Memory Access Layer @@ -364,6 +619,25 @@ #define ocmdsarc (OCM_DCR_BASE+0x02) /* OCM D-side address compare reg */ #define ocmdscntl (OCM_DCR_BASE+0x03) /* OCM D-side control reg */ +/****************************************************************************** + * GPIO macro register defines + ******************************************************************************/ +#define GPIO_BASE 0xEF600700 +#define GPIO0_OR (GPIO_BASE+0x0) +#define GPIO0_TCR (GPIO_BASE+0x4) +#define GPIO0_OSRH (GPIO_BASE+0x8) +#define GPIO0_OSRL (GPIO_BASE+0xC) +#define GPIO0_TSRH (GPIO_BASE+0x10) +#define GPIO0_TSRL (GPIO_BASE+0x14) +#define GPIO0_ODR (GPIO_BASE+0x18) +#define GPIO0_IR (GPIO_BASE+0x1C) +#define GPIO0_RR1 (GPIO_BASE+0x20) +#define GPIO0_RR2 (GPIO_BASE+0x24) +#define GPIO0_ISR1H (GPIO_BASE+0x30) +#define GPIO0_ISR1L (GPIO_BASE+0x34) +#define GPIO0_ISR2H (GPIO_BASE+0x38) +#define GPIO0_ISR2L (GPIO_BASE+0x3C) + /* * Macro for accessing the indirect EBC register