summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/wsp
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-02-10 16:52:55 +0100
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-02-10 17:14:49 +0100
commit9edd576d89a5b6d3e136d7dcab654d887c0d25b7 (patch)
treed19670de2256f8187321de3a41fa4a10d3c8e402 /arch/powerpc/platforms/wsp
parente21af88d39796c907c38648c824be3d646ffbe35 (diff)
parent28a4d5675857f6386930a324317281cb8ed1e5d0 (diff)
Merge remote-tracking branch 'airlied/drm-fixes' into drm-intel-next-queued
Back-merge from drm-fixes into drm-intel-next to sort out two things: - interlaced support: -fixes contains a bugfix to correctly clear interlaced configuration bits in case the bios sets up an interlaced mode and we want to set up the progressive mode (current kernels don't support interlaced). The actual feature work to support interlaced depends upon (and conflicts with) this bugfix. - forcewake voodoo to workaround missed IRQ issues: -fixes only enabled this for ivybridge, but some recent bug reports indicate that we need this on Sandybridge, too. But in a slightly different flavour and with other fixes and reworks on top. Additionally there are some forcewake cleanup patches heading to -next that would conflict with currrent -fixes. Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'arch/powerpc/platforms/wsp')
-rw-r--r--arch/powerpc/platforms/wsp/Kconfig12
-rw-r--r--arch/powerpc/platforms/wsp/Makefile8
-rw-r--r--arch/powerpc/platforms/wsp/chroma.c56
-rw-r--r--arch/powerpc/platforms/wsp/h8.c134
-rw-r--r--arch/powerpc/platforms/wsp/opb_pic.c3
-rw-r--r--arch/powerpc/platforms/wsp/psr2.c56
-rw-r--r--arch/powerpc/platforms/wsp/wsp.c115
-rw-r--r--arch/powerpc/platforms/wsp/wsp.h16
8 files changed, 347 insertions, 53 deletions
diff --git a/arch/powerpc/platforms/wsp/Kconfig b/arch/powerpc/platforms/wsp/Kconfig
index bd560c786ed..57d22a2f4ba 100644
--- a/arch/powerpc/platforms/wsp/Kconfig
+++ b/arch/powerpc/platforms/wsp/Kconfig
@@ -1,20 +1,28 @@
config PPC_WSP
bool
select PPC_A2
+ select GENERIC_TBSYNC
+ select PPC_ICSWX
select PPC_SCOM
select PPC_XICS
select PPC_ICP_NATIVE
select PCI
select PPC_IO_WORKAROUNDS if PCI
select PPC_INDIRECT_PIO if PCI
+ select PPC_WSP_COPRO
default n
menu "WSP platform selection"
depends on PPC_BOOK3E_64
config PPC_PSR2
- bool "PSR-2 platform"
- select GENERIC_TBSYNC
+ bool "PowerEN System Reference Platform 2"
+ select EPAPR_BOOT
+ select PPC_WSP
+ default y
+
+config PPC_CHROMA
+ bool "PowerEN PCIe Chroma Card"
select EPAPR_BOOT
select PPC_WSP
default y
diff --git a/arch/powerpc/platforms/wsp/Makefile b/arch/powerpc/platforms/wsp/Makefile
index a1486b436f0..56817ac98fc 100644
--- a/arch/powerpc/platforms/wsp/Makefile
+++ b/arch/powerpc/platforms/wsp/Makefile
@@ -1,8 +1,10 @@
ccflags-y += -mno-minimal-toc
-obj-y += setup.o ics.o
-obj-$(CONFIG_PPC_PSR2) += psr2.o opb_pic.o
+obj-y += setup.o ics.o wsp.o
+obj-$(CONFIG_PPC_PSR2) += psr2.o
+obj-$(CONFIG_PPC_CHROMA) += chroma.o h8.o
+obj-$(CONFIG_PPC_WSP) += opb_pic.o
obj-$(CONFIG_PPC_WSP) += scom_wsp.o
obj-$(CONFIG_SMP) += smp.o scom_smp.o
obj-$(CONFIG_PCI) += wsp_pci.o
-obj-$(CONFIG_PCI_MSI) += msi.o \ No newline at end of file
+obj-$(CONFIG_PCI_MSI) += msi.o
diff --git a/arch/powerpc/platforms/wsp/chroma.c b/arch/powerpc/platforms/wsp/chroma.c
new file mode 100644
index 00000000000..ca6fa26f6e6
--- /dev/null
+++ b/arch/powerpc/platforms/wsp/chroma.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008-2011, IBM Corporation
+ *
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/of.h>
+#include <linux/smp.h>
+#include <linux/time.h>
+
+#include <asm/machdep.h>
+#include <asm/system.h>
+#include <asm/udbg.h>
+
+#include "ics.h"
+#include "wsp.h"
+
+void __init chroma_setup_arch(void)
+{
+ wsp_setup_arch();
+ wsp_setup_h8();
+
+}
+
+static int __init chroma_probe(void)
+{
+ unsigned long root = of_get_flat_dt_root();
+
+ if (!of_flat_dt_is_compatible(root, "ibm,wsp-chroma"))
+ return 0;
+
+ return 1;
+}
+
+define_machine(chroma_md) {
+ .name = "Chroma PCIe",
+ .probe = chroma_probe,
+ .setup_arch = chroma_setup_arch,
+ .restart = wsp_h8_restart,
+ .power_off = wsp_h8_power_off,
+ .halt = wsp_halt,
+ .calibrate_decr = generic_calibrate_decr,
+ .init_IRQ = wsp_setup_irq,
+ .progress = udbg_progress,
+ .power_save = book3e_idle,
+};
+
+machine_arch_initcall(chroma_md, wsp_probe_devices);
diff --git a/arch/powerpc/platforms/wsp/h8.c b/arch/powerpc/platforms/wsp/h8.c
new file mode 100644
index 00000000000..d18e6cc19df
--- /dev/null
+++ b/arch/powerpc/platforms/wsp/h8.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2008-2011, IBM Corporation
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/io.h>
+
+#include "wsp.h"
+
+/*
+ * The UART connection to the H8 is over ttyS1 which is just a 16550.
+ * We assume that FW has it setup right and no one messes with it.
+ */
+
+
+static u8 __iomem *h8;
+
+#define RBR 0 /* Receiver Buffer Register */
+#define THR 0 /* Transmitter Holding Register */
+#define LSR 5 /* Line Status Register */
+#define LSR_DR 0x01 /* LSR value for Data-Ready */
+#define LSR_THRE 0x20 /* LSR value for Transmitter-Holding-Register-Empty */
+static void wsp_h8_putc(int c)
+{
+ u8 lsr;
+
+ do {
+ lsr = readb(h8 + LSR);
+ } while ((lsr & LSR_THRE) != LSR_THRE);
+ writeb(c, h8 + THR);
+}
+
+static int wsp_h8_getc(void)
+{
+ u8 lsr;
+
+ do {
+ lsr = readb(h8 + LSR);
+ } while ((lsr & LSR_DR) != LSR_DR);
+
+ return readb(h8 + RBR);
+}
+
+static void wsp_h8_puts(const char *s, int sz)
+{
+ int i;
+
+ for (i = 0; i < sz; i++) {
+ wsp_h8_putc(s[i]);
+
+ /* no flow control so wait for echo */
+ wsp_h8_getc();
+ }
+ wsp_h8_putc('\r');
+ wsp_h8_putc('\n');
+}
+
+static void wsp_h8_terminal_cmd(const char *cmd, int sz)
+{
+ hard_irq_disable();
+ wsp_h8_puts(cmd, sz);
+ /* should never return, but just in case */
+ for (;;)
+ continue;
+}
+
+
+void wsp_h8_restart(char *cmd)
+{
+ static const char restart[] = "warm-reset";
+
+ (void)cmd;
+ wsp_h8_terminal_cmd(restart, sizeof(restart) - 1);
+}
+
+void wsp_h8_power_off(void)
+{
+ static const char off[] = "power-off";
+
+ wsp_h8_terminal_cmd(off, sizeof(off) - 1);
+}
+
+static void __iomem *wsp_h8_getaddr(void)
+{
+ struct device_node *aliases;
+ struct device_node *uart;
+ struct property *path;
+ void __iomem *va = NULL;
+
+ /*
+ * there is nothing in the devtree to tell us which is mapped
+ * to the H8, but se know it is the second serial port.
+ */
+
+ aliases = of_find_node_by_path("/aliases");
+ if (aliases == NULL)
+ return NULL;
+
+ path = of_find_property(aliases, "serial1", NULL);
+ if (path == NULL)
+ goto out;
+
+ uart = of_find_node_by_path(path->value);
+ if (uart == NULL)
+ goto out;
+
+ va = of_iomap(uart, 0);
+
+ /* remove it so no one messes with it */
+ of_detach_node(uart);
+ of_node_put(uart);
+
+out:
+ of_node_put(aliases);
+
+ return va;
+}
+
+void __init wsp_setup_h8(void)
+{
+ h8 = wsp_h8_getaddr();
+
+ /* Devtree change? lets hard map it anyway */
+ if (h8 == NULL) {
+ pr_warn("UART to H8 could not be found");
+ h8 = ioremap(0xffc0008000ULL, 0x100);
+ }
+}
diff --git a/arch/powerpc/platforms/wsp/opb_pic.c b/arch/powerpc/platforms/wsp/opb_pic.c
index be05631a3c1..19f353dfcd0 100644
--- a/arch/powerpc/platforms/wsp/opb_pic.c
+++ b/arch/powerpc/platforms/wsp/opb_pic.c
@@ -320,7 +320,8 @@ void __init opb_pic_init(void)
}
/* Attach opb interrupt handler to new virtual IRQ */
- rc = request_irq(virq, opb_irq_handler, 0, "OPB LS Cascade", opb);
+ rc = request_irq(virq, opb_irq_handler, IRQF_NO_THREAD,
+ "OPB LS Cascade", opb);
if (rc) {
printk("opb: request_irq failed: %d\n", rc);
continue;
diff --git a/arch/powerpc/platforms/wsp/psr2.c b/arch/powerpc/platforms/wsp/psr2.c
index 166f2e4b4be..0c1ae06d0be 100644
--- a/arch/powerpc/platforms/wsp/psr2.c
+++ b/arch/powerpc/platforms/wsp/psr2.c
@@ -14,10 +14,10 @@
#include <linux/mm.h>
#include <linux/of.h>
#include <linux/smp.h>
+#include <linux/time.h>
#include <asm/machdep.h>
#include <asm/system.h>
-#include <asm/time.h>
#include <asm/udbg.h>
#include "ics.h"
@@ -27,7 +27,8 @@
static void psr2_spin(void)
{
hard_irq_disable();
- for (;;) ;
+ for (;;)
+ continue;
}
static void psr2_restart(char *cmd)
@@ -35,65 +36,32 @@ static void psr2_restart(char *cmd)
psr2_spin();
}
-static int psr2_probe_devices(void)
-{
- struct device_node *np;
-
- /* Our RTC is a ds1500. It seems to be programatically compatible
- * with the ds1511 for which we have a driver so let's use that
- */
- np = of_find_compatible_node(NULL, NULL, "dallas,ds1500");
- if (np != NULL) {
- struct resource res;
- if (of_address_to_resource(np, 0, &res) == 0)
- platform_device_register_simple("ds1511", 0, &res, 1);
- }
- return 0;
-}
-machine_arch_initcall(psr2_md, psr2_probe_devices);
-
-static void __init psr2_setup_arch(void)
-{
- /* init to some ~sane value until calibrate_delay() runs */
- loops_per_jiffy = 50000000;
-
- scom_init_wsp();
-
- /* Setup SMP callback */
-#ifdef CONFIG_SMP
- a2_setup_smp();
-#endif
-#ifdef CONFIG_PCI
- wsp_setup_pci();
-#endif
-
-}
-
static int __init psr2_probe(void)
{
unsigned long root = of_get_flat_dt_root();
+ if (of_flat_dt_is_compatible(root, "ibm,wsp-chroma")) {
+ /* chroma systems also claim they are psr2s */
+ return 0;
+ }
+
if (!of_flat_dt_is_compatible(root, "ibm,psr2"))
return 0;
return 1;
}
-static void __init psr2_init_irq(void)
-{
- wsp_init_irq();
- opb_pic_init();
-}
-
define_machine(psr2_md) {
.name = "PSR2 A2",
.probe = psr2_probe,
- .setup_arch = psr2_setup_arch,
+ .setup_arch = wsp_setup_arch,
.restart = psr2_restart,
.power_off = psr2_spin,
.halt = psr2_spin,
.calibrate_decr = generic_calibrate_decr,
- .init_IRQ = psr2_init_irq,
+ .init_IRQ = wsp_setup_irq,
.progress = udbg_progress,
.power_save = book3e_idle,
};
+
+machine_arch_initcall(psr2_md, wsp_probe_devices);
diff --git a/arch/powerpc/platforms/wsp/wsp.c b/arch/powerpc/platforms/wsp/wsp.c
new file mode 100644
index 00000000000..d25cc96c21b
--- /dev/null
+++ b/arch/powerpc/platforms/wsp/wsp.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2008-2011, IBM Corporation
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/smp.h>
+#include <linux/delay.h>
+#include <linux/time.h>
+
+#include <asm/scom.h>
+
+#include "wsp.h"
+#include "ics.h"
+
+#define WSP_SOC_COMPATIBLE "ibm,wsp-soc"
+#define PBIC_COMPATIBLE "ibm,wsp-pbic"
+#define COPRO_COMPATIBLE "ibm,wsp-coprocessor"
+
+static int __init wsp_probe_buses(void)
+{
+ static __initdata struct of_device_id bus_ids[] = {
+ /*
+ * every node in between needs to be here or you won't
+ * find it
+ */
+ { .compatible = WSP_SOC_COMPATIBLE, },
+ { .compatible = PBIC_COMPATIBLE, },
+ { .compatible = COPRO_COMPATIBLE, },
+ {},
+ };
+ of_platform_bus_probe(NULL, bus_ids, NULL);
+
+ return 0;
+}
+
+void __init wsp_setup_arch(void)
+{
+ /* init to some ~sane value until calibrate_delay() runs */
+ loops_per_jiffy = 50000000;
+
+ scom_init_wsp();
+
+ /* Setup SMP callback */
+#ifdef CONFIG_SMP
+ a2_setup_smp();
+#endif
+#ifdef CONFIG_PCI
+ wsp_setup_pci();
+#endif
+}
+
+void __init wsp_setup_irq(void)
+{
+ wsp_init_irq();
+ opb_pic_init();
+}
+
+
+int __init wsp_probe_devices(void)
+{
+ struct device_node *np;
+
+ /* Our RTC is a ds1500. It seems to be programatically compatible
+ * with the ds1511 for which we have a driver so let's use that
+ */
+ np = of_find_compatible_node(NULL, NULL, "dallas,ds1500");
+ if (np != NULL) {
+ struct resource res;
+ if (of_address_to_resource(np, 0, &res) == 0)
+ platform_device_register_simple("ds1511", 0, &res, 1);
+ }
+
+ wsp_probe_buses();
+
+ return 0;
+}
+
+void wsp_halt(void)
+{
+ u64 val;
+ scom_map_t m;
+ struct device_node *dn;
+ struct device_node *mine;
+ struct device_node *me;
+
+ me = of_get_cpu_node(smp_processor_id(), NULL);
+ mine = scom_find_parent(me);
+
+ /* This will halt all the A2s but not power off the chip */
+ for_each_node_with_property(dn, "scom-controller") {
+ if (dn == mine)
+ continue;
+ m = scom_map(dn, 0, 1);
+
+ /* read-modify-write it so the HW probe does not get
+ * confused */
+ val = scom_read(m, 0);
+ val |= 1;
+ scom_write(m, 0, val);
+ scom_unmap(m);
+ }
+ m = scom_map(mine, 0, 1);
+ val = scom_read(m, 0);
+ val |= 1;
+ scom_write(m, 0, val);
+ /* should never return */
+ scom_unmap(m);
+}
diff --git a/arch/powerpc/platforms/wsp/wsp.h b/arch/powerpc/platforms/wsp/wsp.h
index 33479818f62..10c1d1fff36 100644
--- a/arch/powerpc/platforms/wsp/wsp.h
+++ b/arch/powerpc/platforms/wsp/wsp.h
@@ -6,15 +6,25 @@
/* Devtree compatible strings for major devices */
#define PCIE_COMPATIBLE "ibm,wsp-pciex"
+extern void wsp_setup_arch(void);
+extern void wsp_setup_irq(void);
+extern int wsp_probe_devices(void);
+extern void wsp_halt(void);
+
extern void wsp_setup_pci(void);
extern void scom_init_wsp(void);
extern void a2_setup_smp(void);
extern int a2_scom_startup_cpu(unsigned int lcpu, int thr_idx,
struct device_node *np);
-int smp_a2_cpu_bootable(unsigned int nr);
-int __devinit smp_a2_kick_cpu(int nr);
+extern int smp_a2_cpu_bootable(unsigned int nr);
+extern int __devinit smp_a2_kick_cpu(int nr);
+
+extern void opb_pic_init(void);
-void opb_pic_init(void);
+/* chroma specific managment */
+extern void wsp_h8_restart(char *cmd);
+extern void wsp_h8_power_off(void);
+extern void __init wsp_setup_h8(void);
#endif /* __WSP_H */