From: Grant Likely <[EMAIL PROTECTED]>

Signed-off-by: Grant Likely <[EMAIL PROTECTED]>
---

 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__ */

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to