From 02fa3b2743b3f37381b6af4ee4362422b9011c8b Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Wed, 6 Oct 2004 17:33:54 +0000 Subject: epia-m support git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1655 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/southbridge/ricoh/rl5c476/rl5c476.c | 255 ++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 src/southbridge/ricoh/rl5c476/rl5c476.c (limited to 'src/southbridge/ricoh/rl5c476/rl5c476.c') diff --git a/src/southbridge/ricoh/rl5c476/rl5c476.c b/src/southbridge/ricoh/rl5c476/rl5c476.c new file mode 100644 index 0000000000..c6cb55cba3 --- /dev/null +++ b/src/southbridge/ricoh/rl5c476/rl5c476.c @@ -0,0 +1,255 @@ +/* + * (C) Copyright 2004 Nick Barker + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + + +#include +#include +#include +#include +#include +#include +#include +#include "rl5c476.h" +#include "chip.h" + +static void udelay(int i){ + for(; i > 0 ; i--) + inb(0x80); + +} + +static void +dump_south(void) +{ + device_t dev0; + dev0 = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, 0); + dev0 = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, dev0); + int i,j; + + for(i = 0; i < 256; i += 16) { + printk_debug("0x%x: ", i); + for(j = 0; j < 16; j++) { + printk_debug("%02x ", pci_read_config8(dev0, i+j)); + } + printk_debug("\n"); + } + printk_debug("Card32\n"); + for(i = 0 ; i < 256 ; i+=16){ + printk_debug("0x%x: ",i); + for(j = 0 ; j < 16 ; j++){ + printk_debug(" %02x",*(unsigned char *)(0x80000000+i+j)); + } + printk_debug("\n"); + } + printk_debug("Card16\n"); + for(i = 0; i < 256; i += 16) { + printk_debug("0x%x: ", i); + for(j = 0; j < 16; j++) { + printk_debug("%02x ", *(unsigned char *)(0x80000800+ i+j)); + } + printk_debug("\n"); + } + printk_debug("CF Config\n"); + for(i = 0 ; i < 256 ; i+=16){ + printk_debug("0x%x: ",i); + for(j=0 ; j < 16 ; j++){ + printk_debug("%02x ",*(unsigned char *)(0x81000200 + i + j)); + } + printk_debug("\n"); + } +} + + +static void rl5c476_init(struct southbridge_rl5c476_config *conf) +{ + //unsigned char enables; + device_t dev; + pc16reg_t *pc16; + int i; + + printk_debug("rl5c476 init\n"); + /* cardbus controller function 1 for CF Socket */ + dev = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, 0); + + if (!dev ){ + // probably an epia-m rather than mii + printk_debug("No rl5c476 found\n"); + return; + } + + /* setup pci header manually because 'pci_device.c' doesn't know how to handle + * pci to cardbus bridges - (header type 2 I think) + */ + + + /* initialize function zero - pcmcia socket so it behaves itself */ + /* FIXME - statically put control memory at 0xe0000000 for now + * one day the pci_device allocator might do this */ + pci_write_config32(dev,0x10,0xe0000000); + pci_write_config8(dev,0x0d,0x20); + pci_write_config8(dev,0x19,0x02); + pci_write_config8(dev,0x1a,0x02); + pci_write_config8(dev,0x1b,0x20); + //pci_write_config8(dev,0x3c,0); + pci_write_config8(dev,0x82,0x00a0); + pci_write_config16(dev,0x04,0x07); + + + /* get second function - i.e. compact flash socket */ + dev = dev_find_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, dev); + + + /* FIXME - control structure statically declared at 0xe0008000 for now */ + pci_write_config32(dev,0x10,0xe0008000); + pci_write_config8(dev,0x0d,0x20); + pci_write_config8(dev,0x19,0x03); + pci_write_config8(dev,0x1a,0x03); + pci_write_config8(dev,0x1b,0x20); + + //pci_write_config8(dev,0x3c,0x0); + pci_write_config16(dev,0x3e,0x0780); + pci_write_config16(dev,0x82,0x00a0); + + pci_write_config16(dev,0x04,0x07); + + + /* pick up where 16 bit card control structure is */ + pc16 = (pc16reg_t *)(0xe0008800); + + /* disable memory and io windows and turn off socket power */ + pc16->pwctrl = 0; + + /* disable irq lines */ + pc16->igctrl = 0; + + /* disable memory and I/O windows */ + pc16->awinen = 0; + + /* reset card, configure for I/O and set IRQ line */ + pc16->igctrl = 0x69; + + + // set io window 0 for 1e8 - 1ef + pc16->iostl0 = 0xe8; + pc16->iosth0 = 1; + + pc16->iospl0 = 0xef; + pc16->iosph0 = 1; + + // add io offset of 8 so that CF card will decode 0x1e8 as 0x1f0 i.e. the first byte of + // a 16 byte aligned, 16 byte window etc + pc16->ioffl0 = 0x8; + pc16->ioffh0 = 0; + + // set io window 1 for 3ed - 3ee + pc16->iostl1 = 0xed; + pc16->iosth1 = 3; + + pc16->iospl1 = 0xee; + pc16->iosph1 = 3; + + pc16->ioffl1 = 0x0; + pc16->ioffh1 = 0; + + + // FIXME statically declare CF config window at 0xe1000000 + pc16->smstl0 = 0; + pc16->smsth0 = 0; + pc16->smspl0 = 0; + pc16->smsph0 = 0x80; + pc16->moffl0 = 0; + pc16->moffh0 = 0x40; + pc16->smpga0 = 0xe1; + + // set I/O width for Auto Data width + pc16->ioctrl = 0x22; + + + // enable I/O window 0 and 1 + pc16->awinen = 0xc1; + + + pc16->miscc1 = 1; + + // apply power and enable outputs + pc16->pwctrl = 0xb0; + + + // delay could be optimised, but this works + udelay(100000); + + pc16->igctrl = 0x69; + + unsigned char *cptr; + cptr = (unsigned char *)(0xe1000200); + printk_debug("CF Config = %x\n",*cptr); + + // FIX Me 16 bit CF always have first config byte at 0x200 into Config structure, + // but CF+ May Not according to spec - should locate through reading tuple data, + // but this will do for now !!! + + + // set CF to decode 16 IO bytes on any 16 byte boundary - rely on the io + // windows of the bridge set up above to map those bytes into the + // addresses for ide controller 3 (0x1e8 - 0x1ef and 0x3ed - 0x3ee) + *cptr = 0x41; + + +} + +static void southbridge_init(struct chip *chip, enum chip_pass pass) +{ + + struct southbridge_rl5c476_config *conf = + (struct southbridge_rl5c476_config *)chip->chip_info; + + switch (pass) { + case CONF_PASS_PRE_PCI: + //rl5c476_pci_enable(conf); + break; + + case CONF_PASS_POST_PCI: + rl5c476_init(conf); + + break; + + case CONF_PASS_PRE_BOOT: + //dump_south(); + break; + + default: + /* nothing yet */ + break; + } +} + +static void enumerate(struct chip *chip) +{ + extern struct device_operations default_pci_ops_bus; + chip_enumerate(chip); + chip->dev->ops = &default_pci_ops_bus; +} + +struct chip_control southbridge_ricoh_rl5c476_control = { + .enumerate = enumerate, + .enable = southbridge_init, + .name = "RICOH RL5C476" +}; -- cgit v1.2.3