[RFC/PATCH 3/3] powerpc/52xx: add udbg and early debug support for PSC serial console
Grant Likely
grant.likely at secretlab.ca
Wed Aug 6 16:02:54 EST 2008
From: Grant Likely <grant.likely at secretlab.ca>
Signed-off-by: Grant Likely <grant.likely at secretlab.ca>
---
arch/powerpc/Kconfig.debug | 11 +++
arch/powerpc/kernel/udbg.c | 2
arch/powerpc/platforms/52xx/lite5200.c | 6 +
arch/powerpc/platforms/52xx/mpc5200_simple.c | 3 +
arch/powerpc/platforms/52xx/mpc52xx_common.c | 109 ++++++++++++++++++++++++++
include/asm-powerpc/mpc52xx.h | 1
include/asm-powerpc/udbg.h | 1
7 files changed, 131 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 8c8aadb..26e12d6 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -210,6 +210,12 @@ config PPC_EARLY_DEBUG_40x
inbuilt serial port. This works on chips with a 16550 compatible
UART. Xilinx chips with uartlite cannot use this option.
+config PPC_EARLY_DEBUG_5200
+ bool "MPC5200 PSC serial port"
+ depends on PPC_MPC52xx
+ help
+ Select this to enable early debugging for the Freescale MPC5200 SoC.
+
config PPC_EARLY_DEBUG_CPM
bool "Early serial debugging for Freescale CPM-based serial ports"
depends on SERIAL_CPM
@@ -239,6 +245,11 @@ config PPC_EARLY_DEBUG_40x_PHYSADDR
depends on PPC_EARLY_DEBUG_40x
default "0xef600300"
+config PPC_EARLY_DEBUG_5200_PHYSADDR
+ hex "Early debug PSC UART physical address"
+ depends on PPC_EARLY_DEBUG_5200
+ default "0xf0002000"
+
config PPC_EARLY_DEBUG_CPM_ADDR
hex "CPM UART early debug transmit descriptor address"
depends on PPC_EARLY_DEBUG_CPM
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 7d6c9bb..a3a0c13 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -57,6 +57,8 @@ void __init udbg_early_init(void)
#elif defined(CONFIG_PPC_EARLY_DEBUG_40x)
/* PPC40x debug */
udbg_init_40x_realmode();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_5200)
+ udbg_init_mpc5200();
#elif defined(CONFIG_PPC_EARLY_DEBUG_CPM)
udbg_init_cpm();
#endif
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
index 6d584f4..0685c2c 100644
--- a/arch/powerpc/platforms/52xx/lite5200.c
+++ b/arch/powerpc/platforms/52xx/lite5200.c
@@ -25,6 +25,7 @@
#include <asm/machdep.h>
#include <asm/prom.h>
#include <asm/mpc52xx.h>
+#include <asm/udbg.h>
/* ************************************************************************
*
@@ -182,7 +183,8 @@ static int __init lite5200_probe(void)
if (!of_flat_dt_is_compatible(node, "fsl,lite5200") &&
!of_flat_dt_is_compatible(node, "fsl,lite5200b"))
return 0;
- pr_debug("%s board found\n", model ? model : "unknown");
+
+ udbg_printf("%s board found\n", model ? model : "unknown");
return 1;
}
@@ -191,9 +193,11 @@ define_machine(lite5200) {
.name = "lite5200",
.probe = lite5200_probe,
.setup_arch = lite5200_setup_arch,
+ .init_early = mpc52xx_udbg_init,
.init = mpc52xx_declare_of_platform_devices,
.init_IRQ = mpc52xx_init_irq,
.get_irq = mpc52xx_get_irq,
.restart = mpc52xx_restart,
.calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
};
diff --git a/arch/powerpc/platforms/52xx/mpc5200_simple.c b/arch/powerpc/platforms/52xx/mpc5200_simple.c
index a3bda0b..16daf9d 100644
--- a/arch/powerpc/platforms/52xx/mpc5200_simple.c
+++ b/arch/powerpc/platforms/52xx/mpc5200_simple.c
@@ -30,6 +30,7 @@
#include <asm/prom.h>
#include <asm/machdep.h>
#include <asm/mpc52xx.h>
+#include <asm/udbg.h>
/*
* Setup the architecture
@@ -78,9 +79,11 @@ define_machine(mpc5200_simple_platform) {
.name = "mpc5200-simple-platform",
.probe = mpc5200_simple_probe,
.setup_arch = mpc5200_simple_setup_arch,
+ .init_early = mpc52xx_udbg_init,
.init = mpc52xx_declare_of_platform_devices,
.init_IRQ = mpc52xx_init_irq,
.get_irq = mpc52xx_get_irq,
.restart = mpc52xx_restart,
.calibrate_decr = generic_calibrate_decr,
+ .progress = udbg_progress,
};
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index 4d5fd1d..dcbeb06 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -10,7 +10,7 @@
*
*/
-#undef DEBUG
+#define DEBUG
#include <linux/kernel.h>
#include <linux/spinlock.h>
@@ -18,6 +18,18 @@
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/mpc52xx.h>
+#include <asm/udbg.h>
+#include <asm/pgalloc.h>
+#include <mm/mmu_decl.h>
+
+/* Programmable Serial Controller (PSC) status register bits */
+#define MPC52xx_PSC_SR 0x04
+#define MPC52xx_PSC_SR_RXRDY 0x0100
+#define MPC52xx_PSC_SR_RXFULL 0x0200
+#define MPC52xx_PSC_SR_TXRDY 0x0400
+#define MPC52xx_PSC_SR_TXEMP 0x0800
+
+#define MPC52xx_PSC_BUFFER 0x0C
/* MPC5200 device tree match tables */
static struct of_device_id mpc52xx_xlb_ids[] __initdata = {
@@ -36,6 +48,101 @@ static struct of_device_id mpc52xx_bus_ids[] __initdata = {
{}
};
+static struct of_device_id mpc52xx_psc_uart_ids[] __initdata = {
+ { .compatible = "fsl,mpc5200-psc-uart", },
+};
+
+static void __iomem *psc_console;
+
+static void mpc52xx_udbg_putc(char c)
+{
+ while (!(in_be16(psc_console + MPC52xx_PSC_SR) & MPC52xx_PSC_SR_TXRDY))
+ ; /* wait for idle */
+ out_8(psc_console + MPC52xx_PSC_BUFFER, c);
+ if (c == '\n')
+ mpc52xx_udbg_putc('\r');
+}
+
+static int mpc52xx_udbg_getc(void)
+{
+ while (!(in_be16(psc_console + MPC52xx_PSC_SR) & MPC52xx_PSC_SR_RXRDY))
+ ; /* wait for char */
+ return in_8(psc_console + MPC52xx_PSC_BUFFER);
+}
+
+static int mpc52xx_udbg_getc_poll(void)
+{
+ if (!(in_be16(psc_console + MPC52xx_PSC_SR) & MPC52xx_PSC_SR_RXRDY))
+ return -1;
+
+ return in_8(psc_console + MPC52xx_PSC_BUFFER);
+}
+
+
+#if defined(CONFIG_PPC_EARLY_DEBUG_5200)
+/**
+ * mpc52xx_udbg_init_early - Set up UDBG for early debug
+ *
+ * Called by udbg code if early debug is configured for the MPC5200
+ */
+void __init udbg_init_mpc5200(void)
+{
+ /* At this point, the bootwrapper or u-boot has already set up the
+ * serial console correctly. Assume that it is still configured
+ * for the correct baud rate */
+
+ /* Map the entire IMMR range (minimum mapping of 128k) */
+ psc_console = ioremap_bat(0xf0000000, 128<<10);
+ if (!psc_console)
+ return;
+
+ /* Adjust upwards for the base address of the PSC. */
+ psc_console += CONFIG_PPC_EARLY_DEBUG_5200_PHYSADDR - 0xf0000000;
+
+ /* See if it works */
+ mpc52xx_udbg_putc('=');
+
+ udbg_putc = mpc52xx_udbg_putc;
+ udbg_getc = mpc52xx_udbg_getc;
+ udbg_getc_poll = mpc52xx_udbg_getc_poll;
+ udbg_printf("psc_console=%p\n", psc_console);
+}
+#endif
+
+/**
+ * Initialize UDBG based on data in the device tree
+ */
+void __init mpc52xx_udbg_init(void)
+{
+ /* Lookup the console node */
+ struct device_node *stdout_node = of_lookup_stdout();
+ if (!stdout_node)
+ return;
+
+ /* Is this a PSC? */
+ if (!of_match_node(mpc52xx_psc_uart_ids, stdout_node)) {
+ of_node_put(stdout_node);
+ return;
+ }
+
+ /* Map the PSC registers */
+ psc_console = of_iomap(stdout_node, 0);
+ of_node_put(stdout_node);
+ if (!psc_console)
+ return;
+
+ /* See if it works */
+ mpc52xx_udbg_putc('+');
+
+ /* At this point, the bootwrapper or u-boot has already set up the
+ * serial console correctly. Assume that it is still configured
+ * for the correct baud rate */
+ udbg_putc = mpc52xx_udbg_putc;
+ udbg_getc = mpc52xx_udbg_getc;
+ udbg_getc_poll = mpc52xx_udbg_getc_poll;
+ udbg_printf("psc_console=%p\n", psc_console);
+}
+
/*
* This variable is mapped in mpc52xx_map_wdt() and used in mpc52xx_restart().
* Permanent mapping is required because mpc52xx_restart() can be called
diff --git a/include/asm-powerpc/mpc52xx.h b/include/asm-powerpc/mpc52xx.h
index 81ef10b..94e7f22 100644
--- a/include/asm-powerpc/mpc52xx.h
+++ b/include/asm-powerpc/mpc52xx.h
@@ -255,6 +255,7 @@ extern void mpc52xx_declare_of_platform_devices(void);
extern void mpc52xx_map_common_devices(void);
extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv);
extern void mpc52xx_restart(char *cmd);
+extern void __init mpc52xx_udbg_init(void);
/* mpc52xx_pic.c */
extern void mpc52xx_init_irq(void);
diff --git a/include/asm-powerpc/udbg.h b/include/asm-powerpc/udbg.h
index 6418cee..ea6dd41 100644
--- a/include/asm-powerpc/udbg.h
+++ b/include/asm-powerpc/udbg.h
@@ -49,6 +49,7 @@ extern void __init udbg_init_debug_beat(void);
extern void __init udbg_init_btext(void);
extern void __init udbg_init_44x_as1(void);
extern void __init udbg_init_40x_realmode(void);
+extern void __init udbg_init_mpc5200(void);
extern void __init udbg_init_cpm(void);
#endif /* __KERNEL__ */
More information about the Linuxppc-dev
mailing list