diff options
Diffstat (limited to 'os/rpcg/archrpcg.c')
| -rw-r--r-- | os/rpcg/archrpcg.c | 428 |
1 files changed, 428 insertions, 0 deletions
diff --git a/os/rpcg/archrpcg.c b/os/rpcg/archrpcg.c new file mode 100644 index 00000000..8da2cab1 --- /dev/null +++ b/os/rpcg/archrpcg.c @@ -0,0 +1,428 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" + +#include <draw.h> +#include <memdraw.h> +#include <cursor.h> +#include "screen.h" + +#include "../port/netif.h" +#include "../mpc/etherif.h" +#include "../port/flashif.h" +#include "archrpcg.h" + +/* + * board-specific support for the 850/823 RPCG board + */ + +enum { + /* sccr */ + COM3= IBIT(1)|IBIT(2), /* clock output disabled */ + TBS = IBIT(6), /* =0, time base is OSCCLK/{4,16}; =1, time base is GCLK2/16 */ + RTSEL = IBIT(8), /* =0, select main oscillator (OSCM); =1, select external crystal (EXTCLK) */ + RTDIV = IBIT(7), /* =0, divide by 4; =1, divide by 512 */ + CRQEN = IBIT(9), /* =1, switch to high frequency when CPM active */ + PRQEN = IBIT(10), /* =1, switch to high frequency when interrupt pending */ + EDBF2 = IBIT(14), /* =1, CLKOUT is GCLK2/2 */ + + /* plprcr */ + CSRC = IBIT(21), /* =0, clock is DFNH; =1, clock is DFNL */ +}; + +/* + * called early in main.c, after machinit: + * using board and architecture specific registers, initialise + * 8xx registers that need it and complete initialisation of the Mach structure. + */ +void +archinit(void) +{ + IMM *io; + int mf, i; + + m->bcsr = KADDR(PHYSBCSR); + m->bcsr[0] &= ~EnableEnet; + io = m->iomem; /* run by reset code: no need to lock */ + m->clockgen = 8000000; /* crystal frequency */ + m->oscclk = m->clockgen/MHz; + io->plprcrk = KEEP_ALIVE_KEY; + io->plprcr &= ~CSRC; /* general system clock is DFNH */ + mf = (io->plprcr >> 20)+1; /* use timing set by bootstrap */ + m->cpuhz = m->clockgen*mf; + m->speed = m->cpuhz/MHz; + io->plprcrk = ~KEEP_ALIVE_KEY; + io->sccrk = KEEP_ALIVE_KEY; + io->sccr |= COM3 | TBS | CRQEN | PRQEN; + io->sccrk = ~KEEP_ALIVE_KEY; + if(0){ + /* reset PCMCIA in case monitor hasn't */ + io->pgcr[1] = 1<<7; /* OP2 high to disable PCMCIA */ + io->per = 0; + io->pscr = ~0; + for(i=0; i<8; i++) + io->pcmr[i].base = io->pcmr[i].option = 0; + } +} + +static ulong +banksize(int x, ulong *pa) +{ + IMM *io; + + io = m->iomem; + if((io->memc[x].base & 1) == 0) + return 0; /* bank not valid */ + *pa = io->memc[x].base & ~0x7FFF; + return -(io->memc[x].option&~0x7FFF); +} + +/* + * initialise the kernel's memory configuration: + * there are two banks (base0, npage0) and (base1, npage1). + * initialise any other values in conf that are board-specific. + */ +void +archconfinit(void) +{ + ulong nbytes, pa, ktop; + + conf.nscc = 2; + conf.nocts2 = 1; /* TO DO: check this */ + + conf.npage0 = 0; + nbytes = banksize(DRAM1CS, &pa); + if(nbytes){ + conf.npage0 = nbytes/BY2PG; + conf.base0 = pa; + } + + conf.npage1 = 0; + + /* the following assumes the kernel text and/or data is in bank 0 */ + ktop = PGROUND((ulong)end); + ktop = PADDR(ktop) - conf.base0; + conf.npage0 -= ktop/BY2PG; + conf.base0 += ktop; + + /* check for NVRAM */ + if(m->bcsr[0] & NVRAMBattGood){ + conf.nvramsize = banksize(NVRAMCS, &pa); + conf.nvrambase = KADDR(pa); + } +} + +void +cpuidprint(void) +{ + ulong v; + int i; + + print("PVR: "); + switch(m->cputype){ + case 0x01: print("MPC601"); break; + case 0x03: print("MPC603"); break; + case 0x04: print("MPC604"); break; + case 0x06: print("MPC603e"); break; + case 0x07: print("MPC603e-v7"); break; + case 0x50: print("MPC8xx"); break; + default: print("PowerPC version #%x", m->cputype); break; + } + print(", revision #%lux\n", getpvr()&0xffff); + print("IMMR: "); + v = getimmr() & 0xFFFF; + switch(v>>8){ + case 0x00: print("MPC860/821"); break; + case 0x20: print("MPC823"); break; + case 0x21: print("MPC823A"); break; + default: print("Type #%lux", v>>8); break; + } + print(", mask #%lux\n", v&0xFF); + print("plprcr=%8.8lux sccr=%8.8lux bcsr=%8.8lux\n", m->iomem->plprcr, m->iomem->sccr, m->bcsr[0]); + print("%lud MHz system\n", m->cpuhz/MHz); + print("%lud pages\n", (conf.npage0-conf.base0)/BY2PG); + print("%ludK NVRAM\n", conf.nvramsize/1024); + print("\n"); + for(i=0; i<nelem(m->iomem->pcmr); i++) + print("%d: %8.8lux %8.8lux\n", i, m->iomem->memc[i].base, m->iomem->memc[i].option); +} + +/* + * provide value for #r/switch (devrtc.c) + */ +int +archoptionsw(void) +{ + return (m->bcsr[0]&DipSwitchMask)>>4; +} + +/* + * invoked by clock.c:/^clockintr + */ +static void +twinkle(void) +{ + if(m->ticks%MS2TK(1000) == 0) + m->bcsr[0] ^= LedOff; +} + +void (*archclocktick)(void) = twinkle; + +/* + * invoked by ../port/taslock.c:/^ilock: + * reset watchdog timer here, if there is one and it is enabled + * (qboot currently disables it on the FADS board) + */ +void +clockcheck(void) +{ +} + +/* + * for devflash.c:/^flashreset + * retrieve flash type, virtual base and length and return 0; + * return -1 on error (no flash) + */ +int +archflashreset(int bank, Flash *f) +{ + if(bank != 0) + return -1; + f->type = "AMD29F0x0"; +// f->type = "cfi16"; + f->addr = KADDR(PHYSFLASH); + f->size = 4*1024*1024; + f->width = 4; + f->interleave = 1; + return 0; +} + +int +archether(int ctlrno, Ether *ether) +{ + if(isaconfig("ether", ctlrno, ether) == 0) + return -1; + return 1; +} + +/* + * enable the clocks for the given SCC ether and reveal them to the caller. + * do anything else required to prepare the transceiver (eg, set full-duplex, reset loopback). + */ +int +archetherenable(int cpmid, int *rcs, int *tcs, int mbps, int fullduplex) +{ + IMM *io; + + if(cpmid != CPscc2) + return -1; + USED(mbps); + USED(fullduplex); + io = ioplock(); + m->bcsr[0] = (m->bcsr[0] & ~(EnableXcrLB|DisableColTest)) | EnableEnet; + eieio(); + io->papar |= SIBIT(6)|SIBIT(4); /* enable CLK2 and CLK4 */ + io->padir &= ~(SIBIT(6)|SIBIT(4)); + iopunlock(); + *rcs = CLK4; + *tcs = CLK2; + return 0; +} + +/* + * do anything extra required to enable the UART on the given CPM port + */ +void +archenableuart(int id, int irda) +{ + USED(id, irda); +} + +/* + * do anything extra required to disable the UART on the given CPM port + */ +void +archdisableuart(int id) +{ + USED(id); +} + +/* + * enable the external USB transceiver + * speed is 12MHz if highspeed is non-zero; 1.5MHz if zero + * master is non-zero if the node is acting as USB Host and should provide power + */ +void +archenableusb(int highspeed, int master) +{ + ioplock(); + if(master) + m->bcsr[0] |= EnableUSBPwr; + else + m->bcsr[0] &= ~EnableUSBPwr; + m->bcsr[0] &= ~DisableUSB; + if(highspeed) + m->bcsr[0] |= HighSpdUSB; + else + m->bcsr[0] &= ~HighSpdUSB; + iopunlock(); +} + +/* + * shut down the USB transceiver + */ +void +archdisableusb(void) +{ + ioplock(); + m->bcsr[0] |= DisableUSB; + m->bcsr[0] &= ~EnableUSBPwr; + iopunlock(); +} + +/* + * set the external infrared transceiver to the given speed + */ +void +archsetirxcvr(int highspeed) +{ + USED(highspeed); +} + +/* + * force hardware reset/reboot + */ +void +archreboot(void) +{ + IMM *io; + + io = m->iomem; + io->plprcrk = KEEP_ALIVE_KEY; + io->plprcr |= 1<<7; /* checkstop reset enable */ + io->plprcrk = ~KEEP_ALIVE_KEY; + eieio(); + io->sdcr = 1; + eieio(); + io->lccr = 0; /* switch LCD off */ + eieio(); + firmware(0); +} + +/* + * board-specific PCMCIA support: assumes slot B on 82xFADS + */ +int +pcmslotavail(int slotno) +{ + return slotno == 1; +} + +void +pcmenable(void) +{ + ioplock(); + m->bcsr[0] = m->bcsr[0] & ~(VPPMask|VCCMask); /* power off */ + eieio(); + m->bcsr[0] |= VCC5V | VPPVCC; /* apply Vcc */ + eieio(); + m->iomem->pgcr[1] = 0; /* OP2 low to enable PCMCIA */ + iopunlock(); +iprint("B=%8.8lux\n", m->bcsr[0]); +} + +int +pcmpowered(int) +{ + ulong r; + + r = m->bcsr[0]&VCCMask; + if(r == VCC5V) + return 5; + if(r == VCC3V) + return 3; + return 0; +} + +void +pcmsetvcc(int, int v) +{ + if(v == 5) + v = VCC5V; + else if(v == 3) + v = VCC3V; + else + v = VCC0V; + ioplock(); + m->bcsr[0] = (m->bcsr[0] & ~VCCMask) | v; + iopunlock(); +} + +void +pcmsetvpp(int, int v) +{ + if(v == 5 || v == 3) + v = VPPVCC; + else if(v == 12) + v = VPP12V; + else if(v == 0) + v = VPP0V; + else + v = VPPHiZ; + ioplock(); + m->bcsr[0] = (m->bcsr[0] & ~VPPMask) | v; + iopunlock(); +} + +void +pcmpower(int slotno, int on) +{ + if(!on){ + pcmsetvcc(slotno, 0); /* turn off card power */ + pcmsetvpp(slotno, -1); /* turn off programming voltage (Hi-Z) */ + }else + pcmsetvcc(slotno, 5); +} + +/* + * enable/disable the LCD panel's backlight + */ +void +archbacklight(int on) +{ + USED(on); +} + +/* + * set parameters to describe the screen + */ +int +archlcdmode(Mode *m) +{ + m->x = 640; + m->y = 480; + m->d = 3; + m->lcd.freq = 25000000; + m->lcd.ac = 0; + m->lcd.vpw = 1; + m->lcd.wbf = 33; + m->lcd.wbl = 228; + m->lcd.flags = IsColour | IsTFT | OELow | VsyncLow | ClockLow; + return -1; /* there isn't a screen */ +} + +/* + * there isn't a keyboard port + */ +void +archkbdinit(void) +{ +} + +void +archflashwp(Flash*, int) +{ +} |
