aboutsummaryrefslogtreecommitdiff
path: root/arch/mips/pmc-sierra
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/mips/pmc-sierra
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/mips/pmc-sierra')
-rw-r--r--arch/mips/pmc-sierra/yosemite/Makefile8
-rw-r--r--arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c171
-rw-r--r--arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h69
-rw-r--r--arch/mips/pmc-sierra/yosemite/dbg_io.c180
-rw-r--r--arch/mips/pmc-sierra/yosemite/ht-irq.c53
-rw-r--r--arch/mips/pmc-sierra/yosemite/ht.c454
-rw-r--r--arch/mips/pmc-sierra/yosemite/i2c-yosemite.c188
-rw-r--r--arch/mips/pmc-sierra/yosemite/i2c-yosemite.h96
-rw-r--r--arch/mips/pmc-sierra/yosemite/irq-handler.S93
-rw-r--r--arch/mips/pmc-sierra/yosemite/irq.c167
-rw-r--r--arch/mips/pmc-sierra/yosemite/prom.c141
-rw-r--r--arch/mips/pmc-sierra/yosemite/py-console.c114
-rw-r--r--arch/mips/pmc-sierra/yosemite/setup.c235
-rw-r--r--arch/mips/pmc-sierra/yosemite/setup.h32
-rw-r--r--arch/mips/pmc-sierra/yosemite/smp.c172
15 files changed, 2173 insertions, 0 deletions
diff --git a/arch/mips/pmc-sierra/yosemite/Makefile b/arch/mips/pmc-sierra/yosemite/Makefile
new file mode 100644
index 00000000000..ae96a71a308
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the PMC-Sierra Titan
+#
+
+obj-y += irq-handler.o irq.o i2c-yosemite.o prom.o py-console.o setup.o
+
+obj-$(CONFIG_KGDB) += dbg_io.o
+obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
new file mode 100644
index 00000000000..b067988614c
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
@@ -0,0 +1,171 @@
+/*
+ * arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
+ *
+ * Copyright (C) 2003 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Description:
+ *
+ * This code reads the ATMEL 24CXX EEPROM. The PMC-Sierra Yosemite board uses the ATMEL
+ * 24C32/24C64 which uses two byte addressing as compared to 24C16. Note that this program
+ * uses the serial port like /dev/ttyS0, to communicate with the EEPROM. Hence, you are
+ * expected to have a connectivity from the EEPROM to the serial port. This program does
+ * __not__ communicate using the I2C protocol
+ */
+
+#include "atmel_read_eeprom.h"
+
+static void delay(int delay)
+{
+ while (delay--);
+}
+
+static void send_bit(unsigned char bit)
+{
+ scl_lo;
+ delay(TXX);
+ if (bit)
+ sda_hi;
+ else
+ sda_lo;
+
+ delay(TXX);
+ scl_hi;
+ delay(TXX);
+}
+
+static void send_ack(void)
+{
+ send_bit(0);
+}
+
+static void send_byte(unsigned char byte)
+{
+ int i = 0;
+
+ for (i = 7; i >= 0; i--)
+ send_bit((byte >> i) & 0x01);
+}
+
+static void send_start(void)
+{
+ sda_hi;
+ delay(TXX);
+ scl_hi;
+ delay(TXX);
+ sda_lo;
+ delay(TXX);
+}
+
+static void send_stop(void)
+{
+ sda_lo;
+ delay(TXX);
+ scl_hi;
+ delay(TXX);
+ sda_hi;
+ delay(TXX);
+}
+
+static void do_idle(void)
+{
+ sda_hi;
+ scl_hi;
+ vcc_off;
+}
+
+static int recv_bit(void)
+{
+ int status;
+
+ scl_lo;
+ delay(TXX);
+ sda_hi;
+ delay(TXX);
+ scl_hi;
+ delay(TXX);
+
+ return 1;
+}
+
+static unsigned char recv_byte(void) {
+ int i;
+ unsigned char byte=0;
+
+ for (i=7;i>=0;i--)
+ byte |= (recv_bit() << i);
+
+ return byte;
+}
+
+static int recv_ack(void)
+{
+ unsigned int ack;
+
+ ack = (unsigned int)recv_bit();
+ scl_lo;
+
+ if (ack) {
+ do_idle();
+ printk(KERN_ERR "Error reading the Atmel 24C32/24C64 EEPROM \n");
+ return -1;
+ }
+
+ return ack;
+}
+
+/*
+ * This function does the actual read of the EEPROM. It needs the buffer into which the
+ * read data is copied, the size of the EEPROM being read and the buffer size
+ */
+int read_eeprom(char *buffer, int eeprom_size, int size)
+{
+ int i = 0, err;
+
+ send_start();
+ send_byte(W_HEADER);
+ recv_ack();
+
+ /* EEPROM with size of more then 2K need two byte addressing */
+ if (eeprom_size > 2048) {
+ send_byte(0x00);
+ recv_ack();
+ }
+
+ send_start();
+ send_byte(R_HEADER);
+ err = recv_ack();
+ if (err == -1)
+ return err;
+
+ for (i = 0; i < size; i++) {
+ *buffer++ = recv_byte();
+ send_ack();
+ }
+
+ /* Note : We should do some check if the buffer contains correct information */
+
+ send_stop();
+}
diff --git a/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
new file mode 100644
index 00000000000..d27566d99ff
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.h
@@ -0,0 +1,69 @@
+/*
+ * arch/mips/pmc-sierra/yosemite/atmel_read_eeprom.c
+ *
+ * Copyright (C) 2003 PMC-Sierra Inc.
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Header file for atmel_read_eeprom.c
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <asm/pci.h>
+#include <asm/io.h>
+#include <linux/init.h>
+#include <asm/termios.h>
+#include <asm/ioctls.h>
+#include <linux/ioctl.h>
+#include <linux/fcntl.h>
+
+#define DEFAULT_PORT "/dev/ttyS0" /* Port to open */
+#define TXX 0 /* Dummy loop for spinning */
+
+#define BLOCK_SEL 0x00
+#define SLAVE_ADDR 0xa0
+#define READ_BIT 0x01
+#define WRITE_BIT 0x00
+#define R_HEADER SLAVE_ADDR + BLOCK_SEL + READ_BIT
+#define W_HEADER SLAVE_ADDR + BLOCK_SEL + WRITE_BIT
+
+/*
+ * Clock, Voltages and Data
+ */
+#define vcc_off (ioctl(fd, TIOCSBRK, 0))
+#define vcc_on (ioctl(fd, TIOCCBRK, 0))
+#define sda_hi (ioctl(fd, TIOCMBIS, &dtr))
+#define sda_lo (ioctl(fd, TIOCMBIC, &dtr))
+#define scl_lo (ioctl(fd, TIOCMBIC, &rts))
+#define scl_hi (ioctl(fd, TIOCMBIS, &rts))
+
+const char rts = TIOCM_RTS;
+const char dtr = TIOCM_DTR;
+int fd;
+
diff --git a/arch/mips/pmc-sierra/yosemite/dbg_io.c b/arch/mips/pmc-sierra/yosemite/dbg_io.c
new file mode 100644
index 00000000000..0f659c9106a
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/dbg_io.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Support for KGDB for the Yosemite board. We make use of single serial
+ * port to be used for KGDB as well as console. The second serial port
+ * seems to be having a problem. Single IRQ is allocated for both the
+ * ports. Hence, the interrupt routing code needs to figure out whether
+ * the interrupt came from channel A or B.
+ */
+
+#include <asm/serial.h>
+
+/*
+ * Baud rate, Parity, Data and Stop bit settings for the
+ * serial port on the Yosemite. Note that the Early printk
+ * patch has been added. So, we should be all set to go
+ */
+#define YOSEMITE_BAUD_2400 2400
+#define YOSEMITE_BAUD_4800 4800
+#define YOSEMITE_BAUD_9600 9600
+#define YOSEMITE_BAUD_19200 19200
+#define YOSEMITE_BAUD_38400 38400
+#define YOSEMITE_BAUD_57600 57600
+#define YOSEMITE_BAUD_115200 115200
+
+#define YOSEMITE_PARITY_NONE 0
+#define YOSEMITE_PARITY_ODD 0x08
+#define YOSEMITE_PARITY_EVEN 0x18
+#define YOSEMITE_PARITY_MARK 0x28
+#define YOSEMITE_PARITY_SPACE 0x38
+
+#define YOSEMITE_DATA_5BIT 0x0
+#define YOSEMITE_DATA_6BIT 0x1
+#define YOSEMITE_DATA_7BIT 0x2
+#define YOSEMITE_DATA_8BIT 0x3
+
+#define YOSEMITE_STOP_1BIT 0x0
+#define YOSEMITE_STOP_2BIT 0x4
+
+/* This is crucial */
+#define SERIAL_REG_OFS 0x1
+
+#define SERIAL_RCV_BUFFER 0x0
+#define SERIAL_TRANS_HOLD 0x0
+#define SERIAL_SEND_BUFFER 0x0
+#define SERIAL_INTR_ENABLE (1 * SERIAL_REG_OFS)
+#define SERIAL_INTR_ID (2 * SERIAL_REG_OFS)
+#define SERIAL_DATA_FORMAT (3 * SERIAL_REG_OFS)
+#define SERIAL_LINE_CONTROL (3 * SERIAL_REG_OFS)
+#define SERIAL_MODEM_CONTROL (4 * SERIAL_REG_OFS)
+#define SERIAL_RS232_OUTPUT (4 * SERIAL_REG_OFS)
+#define SERIAL_LINE_STATUS (5 * SERIAL_REG_OFS)
+#define SERIAL_MODEM_STATUS (6 * SERIAL_REG_OFS)
+#define SERIAL_RS232_INPUT (6 * SERIAL_REG_OFS)
+#define SERIAL_SCRATCH_PAD (7 * SERIAL_REG_OFS)
+
+#define SERIAL_DIVISOR_LSB (0 * SERIAL_REG_OFS)
+#define SERIAL_DIVISOR_MSB (1 * SERIAL_REG_OFS)
+
+/*
+ * Functions to READ and WRITE to serial port 0
+ */
+#define SERIAL_READ(ofs) (*((volatile unsigned char*) \
+ (TITAN_SERIAL_BASE + ofs)))
+
+#define SERIAL_WRITE(ofs, val) ((*((volatile unsigned char*) \
+ (TITAN_SERIAL_BASE + ofs))) = val)
+
+/*
+ * Functions to READ and WRITE to serial port 1
+ */
+#define SERIAL_READ_1(ofs) (*((volatile unsigned char*) \
+ (TITAN_SERIAL_BASE_1 + ofs)
+
+#define SERIAL_WRITE_1(ofs, val) ((*((volatile unsigned char*) \
+ (TITAN_SERIAL_BASE_1 + ofs))) = val)
+
+/*
+ * Second serial port initialization
+ */
+void init_second_port(void)
+{
+ /* Disable Interrupts */
+ SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x0);
+ SERIAL_WRITE_1(SERIAL_INTR_ENABLE, 0x0);
+
+ {
+ unsigned int divisor;
+
+ SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x80);
+ divisor = TITAN_SERIAL_BASE_BAUD / YOSEMITE_BAUD_115200;
+ SERIAL_WRITE_1(SERIAL_DIVISOR_LSB, divisor & 0xff);
+
+ SERIAL_WRITE_1(SERIAL_DIVISOR_MSB,
+ (divisor & 0xff00) >> 8);
+ SERIAL_WRITE_1(SERIAL_LINE_CONTROL, 0x0);
+ }
+
+ SERIAL_WRITE_1(SERIAL_DATA_FORMAT, YOSEMITE_DATA_8BIT |
+ YOSEMITE_PARITY_NONE | YOSEMITE_STOP_1BIT);
+
+ /* Enable Interrupts */
+ SERIAL_WRITE_1(SERIAL_INTR_ENABLE, 0xf);
+}
+
+/* Initialize the serial port for KGDB debugging */
+void debugInit(unsigned int baud, unsigned char data, unsigned char parity,
+ unsigned char stop)
+{
+ /* Disable Interrupts */
+ SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x0);
+ SERIAL_WRITE(SERIAL_INTR_ENABLE, 0x0);
+
+ {
+ unsigned int divisor;
+
+ SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x80);
+
+ divisor = TITAN_SERIAL_BASE_BAUD / baud;
+ SERIAL_WRITE(SERIAL_DIVISOR_LSB, divisor & 0xff);
+
+ SERIAL_WRITE(SERIAL_DIVISOR_MSB, (divisor & 0xff00) >> 8);
+ SERIAL_WRITE(SERIAL_LINE_CONTROL, 0x0);
+ }
+
+ SERIAL_WRITE(SERIAL_DATA_FORMAT, data | parity | stop);
+}
+
+static int remoteDebugInitialized = 0;
+
+unsigned char getDebugChar(void)
+{
+ if (!remoteDebugInitialized) {
+ remoteDebugInitialized = 1;
+ debugInit(YOSEMITE_BAUD_115200,
+ YOSEMITE_DATA_8BIT,
+ YOSEMITE_PARITY_NONE, YOSEMITE_STOP_1BIT);
+ }
+
+ while ((SERIAL_READ(SERIAL_LINE_STATUS) & 0x1) == 0);
+ return SERIAL_READ(SERIAL_RCV_BUFFER);
+}
+
+int putDebugChar(unsigned char byte)
+{
+ if (!remoteDebugInitialized) {
+ remoteDebugInitialized = 1;
+ debugInit(YOSEMITE_BAUD_115200,
+ YOSEMITE_DATA_8BIT,
+ YOSEMITE_PARITY_NONE, YOSEMITE_STOP_1BIT);
+ }
+
+ while ((SERIAL_READ(SERIAL_LINE_STATUS) & 0x20) == 0);
+ SERIAL_WRITE(SERIAL_SEND_BUFFER, byte);
+
+ return 1;
+}
diff --git a/arch/mips/pmc-sierra/yosemite/ht-irq.c b/arch/mips/pmc-sierra/yosemite/ht-irq.c
new file mode 100644
index 00000000000..d22c9ffe491
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/ht-irq.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <asm/pci.h>
+
+/*
+ * HT Bus fixup for the Titan
+ * XXX IRQ values need to change based on the board layout
+ */
+void __init titan_ht_pcibios_fixup_bus(struct pci_bus *bus)
+{
+ struct pci_bus *current_bus = bus;
+ struct pci_dev *devices;
+ struct list_head *devices_link;
+
+ list_for_each(devices_link, &(current_bus->devices)) {
+ devices = pci_dev_b(devices_link);
+ if (devices == NULL)
+ continue;
+ }
+
+ /*
+ * PLX and SPKT related changes go here
+ */
+
+}
diff --git a/arch/mips/pmc-sierra/yosemite/ht.c b/arch/mips/pmc-sierra/yosemite/ht.c
new file mode 100644
index 00000000000..dad228d3a22
--- /dev/null
+++ b/arch/mips/pmc-sierra/yosemite/ht.c
@@ -0,0 +1,454 @@
+/*
+ * Copyright 2003 PMC-Sierra
+ * Author: Manish Lachwani (lachwani@pmc-sierra.com)
+ *
+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/version.h>
+#include <asm/pci.h>
+#include <asm/io.h>
+
+#include <linux/init.h>
+#include <asm/titan_dep.h>
+
+#ifdef CONFIG_HYPERTRANSPORT
+
+
+/*
+ * This function check if the Hypertransport Link Initialization completed. If
+ * it did, then proceed further with scanning bus #2
+ */
+static __inline__ int check_titan_htlink(void)
+{
+ u32 val;
+
+ val = *(volatile uint32_t *)(RM9000x2_HTLINK_REG);
+ if (val & 0x00000020)
+ /* HT Link Initialization completed */
+ return 1;
+ else
+ return 0;
+}
+
+static int titan_ht_config_read_dword(struct pci_dev *device,
+ int offset, u32* val)
+{
+ int dev, bus, func;
+ uint32_t address_reg, data_reg;
+ uint32_t address;
+
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+ func = PCI_FUNC(device->devfn);
+
+ /* XXX Need to change the Bus # */
+ if (bus > 2)
+ address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+ 0x80000000 | 0x1;
+ else
+ address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+ address_reg = RM9000x2_OCD_HTCFGA;
+ data_reg = RM9000x2_OCD_HTCFGD;
+
+ RM9K_WRITE(address_reg, address);
+ RM9K_READ(data_reg, val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int titan_ht_config_read_word(struct pci_dev *device,
+ int offset, u16* val)
+{
+ int dev, bus, func;
+ uint32_t address_reg, data_reg;
+ uint32_t address;
+
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+ func = PCI_FUNC(device->devfn);
+
+ /* XXX Need to change the Bus # */
+ if (bus > 2)
+ address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+ 0x80000000 | 0x1;
+ else
+ address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+ address_reg = RM9000x2_OCD_HTCFGA;
+ data_reg = RM9000x2_OCD_HTCFGD;
+
+ if ((offset & 0x3) == 0)
+ offset = 0x2;
+ else
+ offset = 0x0;
+
+ RM9K_WRITE(address_reg, address);
+ RM9K_READ_16(data_reg + offset, val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+u32 longswap(unsigned long l)
+{
+ unsigned char b1,b2,b3,b4;
+
+ b1 = l&255;
+ b2 = (l>>8)&255;
+ b3 = (l>>16)&255;
+ b4 = (l>>24)&255;
+
+ return ((b1<<24) + (b2<<16) + (b3<<8) + b4);
+}
+
+
+static int titan_ht_config_read_byte(struct pci_dev *device,
+ int offset, u8* val)
+{
+ int dev, bus, func;
+ uint32_t address_reg, data_reg;
+ uint32_t address;
+ int offset1;
+
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+ func = PCI_FUNC(device->devfn);
+
+ /* XXX Need to change the Bus # */
+ if (bus > 2)
+ address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+ 0x80000000 | 0x1;
+ else
+ address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+ address_reg = RM9000x2_OCD_HTCFGA;
+ data_reg = RM9000x2_OCD_HTCFGD;
+
+ RM9K_WRITE(address_reg, address);
+
+ if ((offset & 0x3) == 0) {
+ offset1 = 0x3;
+ }
+ if ((offset & 0x3) == 1) {
+ offset1 = 0x2;
+ }
+ if ((offset & 0x3) == 2) {
+ offset1 = 0x1;
+ }
+ if ((offset & 0x3) == 3) {
+ offset1 = 0x0;
+ }
+ RM9K_READ_8(data_reg + offset1, val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int titan_ht_config_write_dword(struct pci_dev *device,
+ int offset, u8 val)
+{
+ int dev, bus, func;
+ uint32_t address_reg, data_reg;
+ uint32_t address;
+
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+ func = PCI_FUNC(device->devfn);
+
+ /* XXX Need to change the Bus # */
+ if (bus > 2)
+ address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+ 0x80000000 | 0x1;
+ else
+ address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+ address_reg = RM9000x2_OCD_HTCFGA;
+ data_reg = RM9000x2_OCD_HTCFGD;
+
+ RM9K_WRITE(address_reg, address);
+ RM9K_WRITE(data_reg, val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int titan_ht_config_write_word(struct pci_dev *device,
+ int offset, u8 val)
+{
+ int dev, bus, func;
+ uint32_t address_reg, data_reg;
+ uint32_t address;
+
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+ func = PCI_FUNC(device->devfn);
+
+ /* XXX Need to change the Bus # */
+ if (bus > 2)
+ address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+ 0x80000000 | 0x1;
+ else
+ address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+ address_reg = RM9000x2_OCD_HTCFGA;
+ data_reg = RM9000x2_OCD_HTCFGD;
+
+ if ((offset & 0x3) == 0)
+ offset = 0x2;
+ else
+ offset = 0x0;
+
+ RM9K_WRITE(address_reg, address);
+ RM9K_WRITE_16(data_reg + offset, val);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int titan_ht_config_write_byte(struct pci_dev *device,
+ int offset, u8 val)
+{
+ int dev, bus, func;
+ uint32_t address_reg, data_reg;
+ uint32_t address;
+ int offset1;
+
+ bus = device->bus->number;
+ dev = PCI_SLOT(device->devfn);
+ func = PCI_FUNC(device->devfn);
+
+ /* XXX Need to change the Bus # */
+ if (bus > 2)
+ address = (bus << 16) | (dev << 11) | (func << 8) | (offset & 0xfc) |
+ 0x80000000 | 0x1;
+ else
+ address = (dev << 11) | (func << 8) | (offset & 0xfc) | 0x80000000;
+
+ address_reg = RM9000x2_OCD_HTCFGA;
+ data_reg = RM9000x2_OCD_HTCFGD;
+
+ RM9K_WRITE(address_reg, address);
+
+ if ((offset & 0x3) == 0) {
+ offset1 = 0x3;
+ }
+ if ((offset & 0x3) == 1) {
+ offset1 = 0x2;
+ }
+ if ((offset & 0x3) == 2) {
+ offset1 = 0x1;
+ }
+ if ((offset & 0x3) == 3) {
+ offset1 = 0x0;
+ }
+
+ RM9K_WRITE_8(data_reg + offset1, val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+static void titan_pcibios_set_master(struct pci_dev *dev)
+{
+ u16 cmd;
+ int bus = dev->bus->number;
+
+ if (check_titan_htlink())
+ titan_ht_config_read_word(dev, PCI_COMMAND, &cmd);
+
+ cmd |= PCI_COMMAND_MASTER;
+
+ if (check_titan_htlink())
+ titan_ht_config_write_word(dev, PCI_COMMAND, cmd);
+}
+
+
+int pcibios_enable_resources(struct pci_dev *dev)
+{
+ u16 cmd, old_cmd;
+ u8 tmp1;
+ int idx;
+ struct resource *r;
+ int bus = dev->bus->number;
+
+ if (check_titan_htlink())
+ titan_ht_config_read_word(dev, PCI_COMMAND, &cmd);
+
+ old_cmd = cmd;
+ for (idx = 0; idx < 6; idx++) {
+ r = &dev->resource[idx];
+ if (!r->start && r->end) {
+ printk(KERN_ERR
+ "PCI: Device %s not available because of "
+ "resource collisions\n", pci_name(dev));
+ return -EINVAL;
+ }
+ if (r->flags & IORESOURCE_IO)
+ cmd |= PCI_COMMAND_IO;
+ if (r->flags & IORESOURCE_MEM)
+ cmd |= PCI_COMMAND_MEMORY;
+ }
+ if (cmd != old_cmd) {
+ if (check_titan_htlink())
+ titan_ht_config_write_word(dev, PCI_COMMAND, cmd);
+ }
+
+ if (check_titan_htlink())
+ titan_ht_config_read_byte(dev, PCI_CACHE_LINE_SIZE, &tmp1);
+
+ if (tmp1 != 8) {
+ printk(KERN_WARNING "PCI setting cache line size to 8 from "
+ "%d\n", tmp1);
+ }
+
+ if (check_titan_htlink())
+ titan_ht_config_write_byte(dev, PCI_CACHE_LINE_SIZE, 8);
+
+ if (check_titan_htlink())
+ titan_ht_config_read_byte(dev, PCI_LATENCY_TIMER, &tmp1);
+
+ if (tmp1 < 32 || tmp1 == 0xff) {
+ printk(KERN_WARNING "PCI setting latency timer to 32 from %d\n",
+ tmp1);
+ }
+
+ if (check_titan_htlink())
+ titan_ht_config_write_byte(dev, PCI_LATENCY_TIMER, 32);
+
+ return 0;
+}
+
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+ return pcibios_enable_resources(dev);
+}
+
+
+
+void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+ struct resource *res, int resource)
+{
+ u32 new, check;
+ int reg;
+
+ return;
+
+ new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+ if (resource < 6) {
+ reg = PCI_BASE_ADDRESS_0 + 4 * resource;
+ } else if (resource == PCI_ROM_RESOURCE) {
+ res->flags |= IORESOURCE_ROM_ENABLE;
+ reg = dev->rom_base_reg;
+ } else {
+ /*
+ * Somebody might have asked allocation of a non-standard
+ * resource
+ */
+ return;
+ }
+
+ pci_write_config_dword(dev, reg, new);
+ pci_read_config_dword(dev, reg, &check);
+ if ((new ^ check) &
+ ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK :
+ PCI_BASE_ADDRESS_MEM_MASK)) {
+ printk(KERN_ERR "PCI: Error while updating region "
+ "%s/%d (%08x != %08x)\n", pci_name(dev), resource,
+ new, check);
+ }
+}
+
+
+void pcibios_align_resource(void *data, struct resource *res,
+ unsigned long size, unsigned long align)
+{
+ struct pci_dev *dev = data;
+
+ if (res->flags & IORESOURCE_IO) {
+ unsigned long start = res->start;
+
+ /* We need to avoid collisions with `mirrored' VGA ports
+ and other strange ISA hardware, so we always want the
+ addresses kilobyte aligned. */
+ if (size > 0x100) {
+ printk(KERN_ERR "PCI: I/O Region %s/%d too large"
+ " (%ld bytes)\n", pci_name(dev),
+ dev->resource - res, size);
+ }
+
+ start = (start + 1024 - 1) & ~(1024 - 1);
+ res->start = start;
+ }
+}
+
+struct pci_ops titan_pci_ops = {
+ titan_ht_config_read_byte,
+ titan_ht_config_read_word,
+ titan_ht_config_read_dword,
+ titan_ht_config_write_byte,
+ titan_ht_config_write_word,
+ titan_ht_config_write_dword
+};
+
+void __init pcibios_fixup_bus(struct pci_bus *c)
+{
+ titan_ht_pcibios_fixup_bus(c);
+}
+
+void __init pcibios_init(void)
+{
+
+ /* Reset PCI I/O and PCI MEM values */
+ /* XXX Need to add the proper values here */
+ ioport_resource.start = 0xe0000000;
+ ioport_resource.end = 0xe0000000 + 0x20000000 - 1;
+ iomem_resource.start = 0xc0000000;
+ iomem_resource.end = 0xc0000000 + 0x20000000 - 1;
+
+ /* XXX Need to add bus values */
+ pci_scan_bus(2, &titan_pci_ops, NULL);
+ pci_scan_bus(3, &titan_pci_ops, NULL);
+}
+
+/*
+ * for parsing "pci=" kernel boot arguments.
+ */
+char *pcibios_setup(char *str)
+{
+ printk(KERN_INFO "rr: pcibios_setup\n");
+ /* Nothing to do for now. */
+
+ return str;
+}
+
+unsigned __init int pcibios_assign_all_busses(void)
+{
+ /* We want to use the PCI bus detection done by PMON */
+ return 0;
+}
+
+#endif /* CONFIG_HYPERTRANSPORT */
diff --git a/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c b/arch/mips/pmc-sierra/yosemite/i2c-yosemite.c
new file mode 100644
index 00000000000..416da22b3bf
--- /dev/null
+++ b/