summaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2014-07-04 17:26:05 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2014-07-04 17:26:05 +0200
commit45d593bc5ec78e26e3a967517ed7a51f27c8b91f (patch)
tree197cc45c686dc86b4537ce55313d5ec074671918 /arch/mips
parent6724928c6972842b73962dc5af70d26de9969582 (diff)
parent988ecf42691e101a35ecae83d26253e9590d14c6 (diff)
downloadbarebox-45d593bc5ec78e26e3a967517ed7a51f27c8b91f.tar.gz
barebox-45d593bc5ec78e26e3a967517ed7a51f27c8b91f.tar.xz
Merge branch 'for-next/mips'
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/Kconfig4
-rw-r--r--arch/mips/configs/qemu-malta_defconfig64
-rw-r--r--arch/mips/configs/ritmix-rzx50_defconfig28
-rw-r--r--arch/mips/dts/jz4755.dtsi42
-rw-r--r--arch/mips/dts/qemu-malta.dts23
-rw-r--r--arch/mips/include/asm/dma-mapping.h25
-rw-r--r--arch/mips/include/asm/gpio.h6
-rw-r--r--arch/mips/include/asm/gt64120.h53
-rw-r--r--arch/mips/mach-malta/Makefile1
-rw-r--r--arch/mips/mach-malta/include/mach/mach-gt64120.h2
-rw-r--r--arch/mips/mach-malta/pci.c236
11 files changed, 442 insertions, 42 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 9a240b782..bc68c679d 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -44,6 +44,8 @@ config MACH_MIPS_MALTA
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
select HAS_DEBUG_LL
+ select GPIOLIB
+ select HW_HAS_PCI
config MACH_MIPS_AR231X
bool "Atheros ar231x-based boards"
@@ -61,7 +63,6 @@ config MACH_MIPS_ATH79
select SYS_SUPPORTS_BIG_ENDIAN
select CSRC_R4K_LIB
select HAS_DEBUG_LL
- select HAVE_CLK
select COMMON_CLK
select COMMON_CLK_OF_PROVIDER
select CLKDEV_LOOKUP
@@ -89,6 +90,7 @@ config MACH_MIPS_XBURST
select HAVE_PBL_IMAGE
select HAVE_IMAGE_COMPRESSION
select HAS_NMON
+ select GPIOLIB
endchoice
source arch/mips/mach-malta/Kconfig
diff --git a/arch/mips/configs/qemu-malta_defconfig b/arch/mips/configs/qemu-malta_defconfig
index ba5fa96df..6ee302df0 100644
--- a/arch/mips/configs/qemu-malta_defconfig
+++ b/arch/mips/configs/qemu-malta_defconfig
@@ -4,9 +4,7 @@ CONFIG_PBL_IMAGE=y
CONFIG_STACK_SIZE=0x7000
CONFIG_BROKEN=y
CONFIG_EXPERIMENTAL=y
-CONFIG_LONGHELP=y
CONFIG_HUSH_FANCY_PROMPT=y
-CONFIG_CMD_GETOPT=y
CONFIG_CMDLINE_EDITING=y
CONFIG_AUTO_COMPLETE=y
CONFIG_MENU=y
@@ -14,54 +12,64 @@ CONFIG_PARTITION=y
# CONFIG_DEFAULT_ENVIRONMENT is not set
CONFIG_POLLER=y
CONFIG_DEBUG_INFO=y
-CONFIG_CMD_EDIT=y
-CONFIG_CMD_SLEEP=y
-CONFIG_CMD_SAVEENV=y
-CONFIG_CMD_LOADENV=y
+CONFIG_LONGHELP=y
+CONFIG_CMD_IOMEM=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_LOADB=y
+CONFIG_CMD_LOADY=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_PARTITION=y
CONFIG_CMD_EXPORT=y
+CONFIG_CMD_LOADENV=y
CONFIG_CMD_PRINTENV=y
-CONFIG_CMD_READLINE=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_SHA1SUM=y
+CONFIG_CMD_SHA256SUM=y
+CONFIG_CMD_UNCOMPRESS=y
+CONFIG_CMD_GETOPT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MIITOOL=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_TFTP=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_EDIT=y
CONFIG_CMD_MENU=y
CONFIG_CMD_MENU_MANAGEMENT=y
CONFIG_CMD_PASSWD=y
-CONFIG_CMD_TIME=y
-CONFIG_CMD_TFTP=y
-CONFIG_CMD_ECHO_E=y
-CONFIG_CMD_LOADB=y
-CONFIG_CMD_LOADY=y
-CONFIG_CMD_MEMINFO=y
-CONFIG_CMD_IOMEM=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_CRC=y
CONFIG_CMD_CRC_CMP=y
-CONFIG_CMD_MD5SUM=y
-CONFIG_CMD_SHA1SUM=y
-CONFIG_CMD_SHA256SUM=y
CONFIG_CMD_FLASH=y
-CONFIG_CMD_BOOTM_SHOW_TYPE=y
-CONFIG_CMD_RESET=y
-CONFIG_CMD_GO=y
-CONFIG_CMD_OFTREE=y
-CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
CONFIG_CMD_OF_NODE=y
-CONFIG_CMD_MTEST=y
-CONFIG_CMD_TIMEOUT=y
-CONFIG_CMD_PARTITION=y
-CONFIG_CMD_UNCOMPRESS=y
+CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_TIME=y
CONFIG_NET=y
-CONFIG_CMD_DHCP=y
CONFIG_NET_NFS=y
-CONFIG_CMD_PING=y
CONFIG_NET_NETCONSOLE=y
CONFIG_NET_RESOLV=y
CONFIG_OFDEVICE=y
CONFIG_OF_BAREBOX_DRIVERS=y
+CONFIG_DRIVER_NET_RTL8139=y
# CONFIG_SPI is not set
+CONFIG_I2C=y
+CONFIG_I2C_GPIO=y
CONFIG_MTD=y
CONFIG_DRIVER_CFI=y
# CONFIG_DRIVER_CFI_AMD is not set
# CONFIG_DRIVER_CFI_BANK_WIDTH_1 is not set
# CONFIG_DRIVER_CFI_BANK_WIDTH_2 is not set
CONFIG_CFI_BUFFER_WRITE=y
+CONFIG_GPIO_MALTA_FPGA_I2C=y
+CONFIG_PCI=y
+CONFIG_PCI_DEBUG=y
CONFIG_FS_CRAMFS=y
CONFIG_FS_TFTP=y
CONFIG_FS_FAT=y
diff --git a/arch/mips/configs/ritmix-rzx50_defconfig b/arch/mips/configs/ritmix-rzx50_defconfig
index 62f23b291..e6f10fb93 100644
--- a/arch/mips/configs/ritmix-rzx50_defconfig
+++ b/arch/mips/configs/ritmix-rzx50_defconfig
@@ -6,34 +6,36 @@ CONFIG_PBL_IMAGE=y
CONFIG_BAUDRATE=57600
CONFIG_GLOB=y
CONFIG_HUSH_FANCY_PROMPT=y
-CONFIG_CMD_GETOPT=y
CONFIG_CMDLINE_EDITING=y
CONFIG_AUTO_COMPLETE=y
# CONFIG_DEFAULT_ENVIRONMENT is not set
CONFIG_DEBUG_LL=y
-CONFIG_CMD_EDIT=y
-CONFIG_CMD_SLEEP=y
-CONFIG_CMD_LOADB=y
-CONFIG_CMD_LOADY=y
-CONFIG_CMD_LOADS=y
-CONFIG_CMD_SAVES=y
-CONFIG_CMD_MEMINFO=y
CONFIG_CMD_IOMEM=y
-CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_MEMINFO=y
CONFIG_CMD_BOOTM_SHOW_TYPE=y
CONFIG_CMD_BOOTM_VERBOSE=y
CONFIG_CMD_BOOTM_INITRD=y
CONFIG_CMD_BOOTM_OFTREE=y
CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y
-CONFIG_CMD_UIMAGE=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_LOADB=y
+CONFIG_CMD_LOADS=y
+CONFIG_CMD_LOADY=y
CONFIG_CMD_RESET=y
+CONFIG_CMD_SAVES=y
+CONFIG_CMD_UIMAGE=y
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_GETOPT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_GPIO=y
CONFIG_CMD_POWEROFF=y
-CONFIG_CMD_GO=y
-CONFIG_CMD_OFTREE=y
-CONFIG_CMD_OF_PROPERTY=y
CONFIG_CMD_OF_NODE=y
+CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_OFTREE=y
CONFIG_OFDEVICE=y
# CONFIG_SPI is not set
+CONFIG_GPIO_JZ4740=y
CONFIG_SHA1=y
CONFIG_SHA224=y
CONFIG_SHA256=y
diff --git a/arch/mips/dts/jz4755.dtsi b/arch/mips/dts/jz4755.dtsi
index 44ff91291..0e655b65a 100644
--- a/arch/mips/dts/jz4755.dtsi
+++ b/arch/mips/dts/jz4755.dtsi
@@ -31,5 +31,47 @@
clock-frequency = <12000000>;
status = "disabled";
};
+
+ gpio0: gpio@10010000 {
+ compatible = "ingenic,jz4740-gpio";
+ gpio-controller;
+ reg = <0xb0010000 0x100>;
+ #gpio-cells = <2>;
+ };
+
+ gpio1: gpio@10010100 {
+ compatible = "ingenic,jz4740-gpio";
+ gpio-controller;
+ reg = <0xb0010100 0x100>;
+ #gpio-cells = <2>;
+ };
+
+ gpio2: gpio@10010200 {
+ compatible = "ingenic,jz4740-gpio";
+ gpio-controller;
+ reg = <0xb0010200 0x100>;
+ #gpio-cells = <2>;
+ };
+
+ gpio3: gpio@10010300 {
+ compatible = "ingenic,jz4740-gpio";
+ gpio-controller;
+ reg = <0xb0010300 0x100>;
+ #gpio-cells = <2>;
+ };
+
+ gpio4: gpio@10010400 {
+ compatible = "ingenic,jz4740-gpio";
+ gpio-controller;
+ reg = <0xb0010400 0x100>;
+ #gpio-cells = <2>;
+ };
+
+ gpio5: gpio@10010500 {
+ compatible = "ingenic,jz4740-gpio";
+ gpio-controller;
+ reg = <0xb0010500 0x100>;
+ #gpio-cells = <2>;
+ };
};
};
diff --git a/arch/mips/dts/qemu-malta.dts b/arch/mips/dts/qemu-malta.dts
index 67fe591f1..cc1c9609e 100644
--- a/arch/mips/dts/qemu-malta.dts
+++ b/arch/mips/dts/qemu-malta.dts
@@ -25,6 +25,25 @@
clock-frequency = <1843200>;
};
+ gpio: gpio@1f000b00 {
+ compatible = "mti,malta-fpga-i2c-gpio";
+ gpio-controller;
+ reg = <0xbf000b00 0x20>;
+ #gpio-cells = <2>;
+ };
+
+ i2c0: i2c0 {
+ compatible = "i2c-gpio";
+ gpios = <&gpio 0 0 /* sda */
+ &gpio 1 0 /* scl */
+ >;
+ i2c-gpio,sda-open-drain;
+ i2c-gpio,scl-open-drain;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
uart2: serial@bf000900 {
compatible = "ns16550a";
reg = <0xbf000900 0x40>;
@@ -51,3 +70,7 @@
};
};
};
+
+&i2c0 {
+ status = "okay";
+};
diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h
new file mode 100644
index 000000000..555efa577
--- /dev/null
+++ b/arch/mips/include/asm/dma-mapping.h
@@ -0,0 +1,25 @@
+#ifndef _ASM_DMA_MAPPING_H
+#define _ASM_DMA_MAPPING_H
+
+#include <xfuncs.h>
+#include <asm/addrspace.h>
+#include <asm/types.h>
+#include <malloc.h>
+
+static inline void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle)
+{
+ void *ret;
+
+ ret = xmemalign(PAGE_SIZE, size);
+
+ *dma_handle = CPHYSADDR(ret);
+
+ return (void *)CKSEG1ADDR(ret);
+}
+
+static inline void dma_free_coherent(void *vaddr)
+{
+ free(vaddr);
+}
+
+#endif /* _ASM_DMA_MAPPING_H */
diff --git a/arch/mips/include/asm/gpio.h b/arch/mips/include/asm/gpio.h
new file mode 100644
index 000000000..41a9589f8
--- /dev/null
+++ b/arch/mips/include/asm/gpio.h
@@ -0,0 +1,6 @@
+#ifndef _ARCH_MIPS_GPIO_H
+#define _ARCH_MIPS_GPIO_H
+
+#include <asm-generic/gpio.h>
+
+#endif /* _ARCH_MIPS_GPIO_H */
diff --git a/arch/mips/include/asm/gt64120.h b/arch/mips/include/asm/gt64120.h
index 6b2ad0f83..7e783c811 100644
--- a/arch/mips/include/asm/gt64120.h
+++ b/arch/mips/include/asm/gt64120.h
@@ -18,6 +18,8 @@
#ifndef _ASM_GT64120_H
#define _ASM_GT64120_H
+#define MSK(n) ((1 << (n)) - 1)
+
#define GT_DEF_BASE 0x14000000
/*
@@ -34,4 +36,55 @@
#define GT_PCI0M1LD_OFS 0x080
#define GT_PCI0M1HD_OFS 0x088
+#define GT_PCI0IOREMAP_OFS 0x0f0
+#define GT_PCI0M0REMAP_OFS 0x0f8
+#define GT_PCI0M1REMAP_OFS 0x100
+
+/* Interrupts. */
+#define GT_INTRCAUSE_OFS 0xc18
+
+/* PCI Internal. */
+#define GT_PCI0_CMD_OFS 0xc00
+#define GT_PCI0_CFGADDR_OFS 0xcf8
+#define GT_PCI0_CFGDATA_OFS 0xcfc
+
+#define GT_PCI_DCRM_SHF 21
+#define GT_PCI_LD_SHF 0
+#define GT_PCI_LD_MSK (MSK(15) << GT_PCI_LD_SHF)
+#define GT_PCI_HD_SHF 0
+#define GT_PCI_HD_MSK (MSK(7) << GT_PCI_HD_SHF)
+#define GT_PCI_REMAP_SHF 0
+#define GT_PCI_REMAP_MSK (MSK(11) << GT_PCI_REMAP_SHF)
+
+#define GT_INTRCAUSE_MASABORT0_SHF 18
+#define GT_INTRCAUSE_MASABORT0_MSK (MSK(1) << GT_INTRCAUSE_MASABORT0_SHF)
+#define GT_INTRCAUSE_MASABORT0_BIT GT_INTRCAUSE_MASABORT0_MSK
+
+#define GT_INTRCAUSE_TARABORT0_SHF 19
+#define GT_INTRCAUSE_TARABORT0_MSK (MSK(1) << GT_INTRCAUSE_TARABORT0_SHF)
+#define GT_INTRCAUSE_TARABORT0_BIT GT_INTRCAUSE_TARABORT0_MSK
+
+#define GT_PCI0_CFGADDR_REGNUM_SHF 2
+#define GT_PCI0_CFGADDR_REGNUM_MSK (MSK(6) << GT_PCI0_CFGADDR_REGNUM_SHF)
+#define GT_PCI0_CFGADDR_FUNCTNUM_SHF 8
+#define GT_PCI0_CFGADDR_FUNCTNUM_MSK (MSK(3) << GT_PCI0_CFGADDR_FUNCTNUM_SHF)
+#define GT_PCI0_CFGADDR_DEVNUM_SHF 11
+#define GT_PCI0_CFGADDR_DEVNUM_MSK (MSK(5) << GT_PCI0_CFGADDR_DEVNUM_SHF)
+#define GT_PCI0_CFGADDR_BUSNUM_SHF 16
+#define GT_PCI0_CFGADDR_BUSNUM_MSK (MSK(8) << GT_PCI0_CFGADDR_BUSNUM_SHF)
+#define GT_PCI0_CFGADDR_CONFIGEN_SHF 31
+#define GT_PCI0_CFGADDR_CONFIGEN_MSK (MSK(1) << GT_PCI0_CFGADDR_CONFIGEN_SHF)
+#define GT_PCI0_CFGADDR_CONFIGEN_BIT GT_PCI0_CFGADDR_CONFIGEN_MSK
+
+/*
+ * Because of an error/peculiarity in the Galileo chip, we need to swap the
+ * bytes when running bigendian. We also provide non-swapping versions.
+ */
+#define __GT_READ(ofs) \
+ (*(volatile u32 *)(GT64120_BASE+(ofs)))
+#define __GT_WRITE(ofs, data) \
+ do { *(volatile u32 *)(GT64120_BASE+(ofs)) = (data); } while (0)
+#define GT_READ(ofs) le32_to_cpu(__GT_READ(ofs))
+#define GT_WRITE(ofs, data) __GT_WRITE(ofs, cpu_to_le32(data))
+
#endif /* _ASM_GT64120_H */
diff --git a/arch/mips/mach-malta/Makefile b/arch/mips/mach-malta/Makefile
index f3cc6684b..0c5a7018d 100644
--- a/arch/mips/mach-malta/Makefile
+++ b/arch/mips/mach-malta/Makefile
@@ -1 +1,2 @@
obj-y += reset.o
+obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/mips/mach-malta/include/mach/mach-gt64120.h b/arch/mips/mach-malta/include/mach/mach-gt64120.h
index ed1e23e9e..8f20fcf26 100644
--- a/arch/mips/mach-malta/include/mach/mach-gt64120.h
+++ b/arch/mips/mach-malta/include/mach/mach-gt64120.h
@@ -10,4 +10,6 @@
#define MIPS_GT_BASE 0x1be00000
+#define GT64120_BASE 0xbbe00000
+
#endif /* _ASM_MACH_MIPS_MACH_GT64120_DEP_H */
diff --git a/arch/mips/mach-malta/pci.c b/arch/mips/mach-malta/pci.c
new file mode 100644
index 000000000..90351758e
--- /dev/null
+++ b/arch/mips/mach-malta/pci.c
@@ -0,0 +1,236 @@
+#include <common.h>
+#include <types.h>
+#include <driver.h>
+#include <init.h>
+#include <mach/hardware.h>
+#include <asm/io.h>
+#include <asm/addrspace.h>
+
+#include <linux/pci.h>
+#include <asm/gt64120.h>
+
+#include <mach/mach-gt64120.h>
+
+#define PCI_ACCESS_READ 0
+#define PCI_ACCESS_WRITE 1
+
+static struct resource gt64120_mem_resource = {
+ .name = "GT-64120 PCI MEM",
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource gt64120_io_resource = {
+ .name = "GT-64120 PCI I/O",
+ .flags = IORESOURCE_IO,
+};
+
+static int gt64xxx_pci0_pcibios_config_access(unsigned char access_type,
+ struct pci_bus *bus, unsigned int devfn, int where, u32 *data)
+{
+ unsigned char busnum = bus->number;
+ u32 intr;
+
+ if ((busnum == 0) && (devfn >= PCI_DEVFN(31, 0)))
+ return -1; /* Because of a bug in the galileo (for slot 31). */
+
+ /* Clear cause register bits */
+ GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
+ GT_INTRCAUSE_TARABORT0_BIT));
+
+ /* Setup address */
+ GT_WRITE(GT_PCI0_CFGADDR_OFS,
+ (busnum << GT_PCI0_CFGADDR_BUSNUM_SHF) |
+ (devfn << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
+ ((where / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
+ GT_PCI0_CFGADDR_CONFIGEN_BIT);
+
+ if (access_type == PCI_ACCESS_WRITE) {
+ if (busnum == 0 && PCI_SLOT(devfn) == 0) {
+ /*
+ * The Galileo system controller is acting
+ * differently than other devices.
+ */
+ GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
+ } else
+ __GT_WRITE(GT_PCI0_CFGDATA_OFS, *data);
+ } else {
+ if (busnum == 0 && PCI_SLOT(devfn) == 0) {
+ /*
+ * The Galileo system controller is acting
+ * differently than other devices.
+ */
+ *data = GT_READ(GT_PCI0_CFGDATA_OFS);
+ } else
+ *data = __GT_READ(GT_PCI0_CFGDATA_OFS);
+ }
+
+ /* Check for master or target abort */
+ intr = GT_READ(GT_INTRCAUSE_OFS);
+
+ if (intr & (GT_INTRCAUSE_MASABORT0_BIT | GT_INTRCAUSE_TARABORT0_BIT)) {
+ /* Error occurred */
+
+ /* Clear bits */
+ GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
+ GT_INTRCAUSE_TARABORT0_BIT));
+
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * We can't address 8 and 16 bit words directly. Instead we have to
+ * read/write a 32bit word and mask/modify the data we actually want.
+ */
+static int gt64xxx_pci0_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ u32 data = 0;
+
+ if (gt64xxx_pci0_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
+ where, &data))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if (size == 1)
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ else if (size == 2)
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ else
+ *val = data;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int gt64xxx_pci0_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 data = 0;
+
+ if (size == 4)
+ data = val;
+ else {
+ if (gt64xxx_pci0_pcibios_config_access(PCI_ACCESS_READ, bus,
+ devfn, where, &data))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if (size == 1)
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else if (size == 2)
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ }
+
+ if (gt64xxx_pci0_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
+ where, &data))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+/* function returns memory address for begin of pci resource */
+static int gt64xxx_res_start(struct pci_bus *bus, resource_size_t res_addr)
+{
+ return KSEG0ADDR(res_addr);
+}
+
+struct pci_ops gt64xxx_pci0_ops = {
+ .read = gt64xxx_pci0_pcibios_read,
+ .write = gt64xxx_pci0_pcibios_write,
+
+ .res_start = gt64xxx_res_start,
+};
+
+static struct pci_controller gt64120_controller = {
+ .pci_ops = &gt64xxx_pci0_ops,
+ .io_resource = &gt64120_io_resource,
+ .mem_resource = &gt64120_mem_resource,
+};
+
+static int pcibios_init(void)
+{
+ resource_size_t start, end, map, start1, end1, map1, mask, res_end;
+
+ /*
+ * Due to a bug in the Galileo system controller, we need
+ * to setup the PCI BAR for the Galileo internal registers.
+ * This should be done in the bios/bootprom and will be
+ * fixed in a later revision of YAMON (the MIPS boards
+ * boot prom).
+ */
+ GT_WRITE(GT_PCI0_CFGADDR_OFS,
+ (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) | /* Local bus */
+ (0 << GT_PCI0_CFGADDR_DEVNUM_SHF) | /* GT64120 dev */
+ (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) | /* Function 0*/
+ ((0x20/4) << GT_PCI0_CFGADDR_REGNUM_SHF) | /* BAR 4*/
+ GT_PCI0_CFGADDR_CONFIGEN_BIT);
+
+ /* Perform the write */
+ GT_WRITE(GT_PCI0_CFGDATA_OFS, CPHYSADDR(MIPS_GT_BASE));
+
+ /* Here is linux code. It assumes, that firmware
+ (pbl in case of barebox) made the work... */
+
+ /* Set up resource ranges from the controller's registers. */
+ start = GT_READ(GT_PCI0M0LD_OFS);
+ end = GT_READ(GT_PCI0M0HD_OFS);
+ map = GT_READ(GT_PCI0M0REMAP_OFS);
+ end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
+ start1 = GT_READ(GT_PCI0M1LD_OFS);
+ end1 = GT_READ(GT_PCI0M1HD_OFS);
+ map1 = GT_READ(GT_PCI0M1REMAP_OFS);
+ end1 = (end1 & GT_PCI_HD_MSK) | (start1 & ~GT_PCI_HD_MSK);
+
+ mask = ~(start ^ end);
+
+ /* We don't support remapping with a discontiguous mask. */
+ BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
+ mask != ~((mask & -mask) - 1));
+ gt64120_mem_resource.start = start;
+ gt64120_mem_resource.end = end;
+ gt64120_controller.mem_offset = (start & mask) - (map & mask);
+ /* Addresses are 36-bit, so do shifts in the destinations. */
+ gt64120_mem_resource.start <<= GT_PCI_DCRM_SHF;
+ gt64120_mem_resource.end <<= GT_PCI_DCRM_SHF;
+ gt64120_mem_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
+ gt64120_controller.mem_offset <<= GT_PCI_DCRM_SHF;
+
+ start = GT_READ(GT_PCI0IOLD_OFS);
+ end = GT_READ(GT_PCI0IOHD_OFS);
+ map = GT_READ(GT_PCI0IOREMAP_OFS);
+ end = (end & GT_PCI_HD_MSK) | (start & ~GT_PCI_HD_MSK);
+ mask = ~(start ^ end);
+
+ /* We don't support remapping with a discontiguous mask. */
+ BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
+ mask != ~((mask & -mask) - 1));
+ gt64120_io_resource.start = map & mask;
+ res_end = (map & mask) | ~mask;
+ gt64120_controller.io_offset = 0;
+ /* Addresses are 36-bit, so do shifts in the destinations. */
+ gt64120_io_resource.start <<= GT_PCI_DCRM_SHF;
+ gt64120_io_resource.end <<= GT_PCI_DCRM_SHF;
+ gt64120_io_resource.end |= (1 << GT_PCI_DCRM_SHF) - 1;
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+ GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT |
+ GT_PCI0_CMD_SBYTESWAP_BIT);
+#else
+ GT_WRITE(GT_PCI0_CMD_OFS, 0);
+#endif
+
+ /* Fix up PCI I/O mapping if necessary (for Atlas). */
+ start = GT_READ(GT_PCI0IOLD_OFS);
+ map = GT_READ(GT_PCI0IOREMAP_OFS);
+ if ((start & map) != 0) {
+ map &= ~start;
+ GT_WRITE(GT_PCI0IOREMAP_OFS, map);
+ }
+
+ register_pci_controller(&gt64120_controller);
+
+ return 0;
+}
+postcore_initcall(pcibios_init);