Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=e12deb840ceed7051ab4799ae71b675a83c58c7c
Commit:     e12deb840ceed7051ab4799ae71b675a83c58c7c
Parent:     0f81b11d2a14adaa9b2c944f104e13d72fedc769
Author:     Mark A. Greer <[EMAIL PROTECTED]>
AuthorDate: Sat May 12 10:54:31 2007 +1000
Committer:  Paul Mackerras <[EMAIL PROTECTED]>
CommitDate: Sat May 12 11:32:49 2007 +1000

    [POWERPC] Add bootwrapper support for Marvell MPSC
    
    The bootwrapper requires a serial driver to allow cmdline editing
    and information reporting on the console.  This driver is required
    by platforms that boot a zImage and use the MPSC for the console.
    
    Signed-off-by: Mark A. Greer <[EMAIL PROTECTED]>
    Signed-off-by: Paul Mackerras <[EMAIL PROTECTED]>
---
 arch/powerpc/boot/Makefile |    2 +-
 arch/powerpc/boot/mpsc.c   |  170 ++++++++++++++++++++++++++++++++++++++++++++
 arch/powerpc/boot/ops.h    |    1 +
 arch/powerpc/boot/serial.c |    2 +
 4 files changed, 174 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 77ef7ee..71b284b 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -43,7 +43,7 @@ $(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \
 src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
                ns16550.c serial.c simple_alloc.c div64.S util.S \
                gunzip_util.c elf_util.c $(zlib) devtree.c \
-               44x.c ebony.c mv64x60.c
+               44x.c ebony.c mv64x60.c mpsc.c
 src-plat := of.c cuboot-83xx.c cuboot-85xx.c holly.c \
                cuboot-ebony.c treeboot-ebony.c
 src-boot := $(src-wlib) $(src-plat) empty.c
diff --git a/arch/powerpc/boot/mpsc.c b/arch/powerpc/boot/mpsc.c
new file mode 100644
index 0000000..f1c0e96
--- /dev/null
+++ b/arch/powerpc/boot/mpsc.c
@@ -0,0 +1,170 @@
+/*
+ * MPSC/UART driver for the Marvell mv64360, mv64460, ...
+ *
+ * Author: Mark A. Greer <[EMAIL PROTECTED]>
+ *
+ * 2007 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "string.h"
+#include "stdio.h"
+#include "io.h"
+#include "ops.h"
+
+extern void udelay(long delay);
+
+#define MPSC_CHR_1             0x000c
+
+#define MPSC_CHR_2             0x0010
+#define MPSC_CHR_2_TA          (1<<7)
+#define MPSC_CHR_2_TCS         (1<<9)
+#define MPSC_CHR_2_RA          (1<<23)
+#define MPSC_CHR_2_CRD         (1<<25)
+#define MPSC_CHR_2_EH          (1<<31)
+
+#define MPSC_CHR_4             0x0018
+#define MPSC_CHR_4_Z           (1<<29)
+
+#define MPSC_CHR_5             0x001c
+#define MPSC_CHR_5_CTL1_INTR   (1<<12)
+#define MPSC_CHR_5_CTL1_VALID  (1<<15)
+
+#define MPSC_CHR_10            0x0030
+
+#define MPSC_INTR_CAUSE                0x0000
+#define MPSC_INTR_CAUSE_RCC    (1<<6)
+#define MPSC_INTR_MASK         0x0080
+
+#define SDMA_SDCM              0x0008
+#define SDMA_SDCM_AR           (1<<15)
+#define SDMA_SDCM_AT           (1<<31)
+
+static volatile char *mpsc_base;
+static volatile char *mpscintr_base;
+static u32 chr1, chr2;
+
+static int mpsc_open(void)
+{
+       chr1 = in_le32((u32 *)(mpsc_base + MPSC_CHR_1)) & 0x00ff0000;
+       chr2 = in_le32((u32 *)(mpsc_base + MPSC_CHR_2)) & ~(MPSC_CHR_2_TA
+                       | MPSC_CHR_2_TCS | MPSC_CHR_2_RA | MPSC_CHR_2_CRD
+                       | MPSC_CHR_2_EH);
+       out_le32((u32 *)(mpsc_base + MPSC_CHR_4), MPSC_CHR_4_Z);
+       out_le32((u32 *)(mpsc_base + MPSC_CHR_5),
+                       MPSC_CHR_5_CTL1_INTR | MPSC_CHR_5_CTL1_VALID);
+       out_le32((u32 *)(mpsc_base + MPSC_CHR_2), chr2 | MPSC_CHR_2_EH);
+       return 0;
+}
+
+static void mpsc_putc(unsigned char c)
+{
+       while (in_le32((u32 *)(mpsc_base + MPSC_CHR_2)) & MPSC_CHR_2_TCS);
+
+       out_le32((u32 *)(mpsc_base + MPSC_CHR_1), chr1 | c);
+       out_le32((u32 *)(mpsc_base + MPSC_CHR_2), chr2 | MPSC_CHR_2_TCS);
+}
+
+static unsigned char mpsc_getc(void)
+{
+       u32 cause = 0;
+       unsigned char c;
+
+       while (!(cause & MPSC_INTR_CAUSE_RCC))
+               cause = in_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE));
+
+       c = in_8((u8 *)(mpsc_base + MPSC_CHR_10 + 2));
+       out_8((u8 *)(mpsc_base + MPSC_CHR_10 + 2), c);
+       out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE),
+                       cause & ~MPSC_INTR_CAUSE_RCC);
+
+       return c;
+}
+
+static u8 mpsc_tstc(void)
+{
+       return (u8)((in_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE))
+                               & MPSC_INTR_CAUSE_RCC) != 0);
+}
+
+static void mpsc_stop_dma(volatile char *sdma_base)
+{
+       out_le32((u32 *)(mpsc_base + MPSC_CHR_2),MPSC_CHR_2_TA | MPSC_CHR_2_RA);
+       out_le32((u32 *)(sdma_base + SDMA_SDCM), SDMA_SDCM_AR | SDMA_SDCM_AT);
+
+       while ((in_le32((u32 *)(sdma_base + SDMA_SDCM))
+                               & (SDMA_SDCM_AR | SDMA_SDCM_AT)) != 0)
+               udelay(100);
+}
+
+static volatile char *mpsc_get_virtreg_of_phandle(void *devp, char *prop)
+{
+       void *v;
+       int n;
+
+       n = getprop(devp, prop, &v, sizeof(v));
+       if (n != sizeof(v))
+               goto err_out;
+
+       devp = find_node_by_linuxphandle((u32)v);
+       if (devp == NULL)
+               goto err_out;
+
+       n = getprop(devp, "virtual-reg", &v, sizeof(v));
+       if (n == sizeof(v))
+               return v;
+
+err_out:
+       return NULL;
+}
+
+int mpsc_console_init(void *devp, struct serial_console_data *scdp)
+{
+       void *v;
+       int n, reg_set;
+       volatile char *sdma_base;
+
+       n = getprop(devp, "virtual-reg", &v, sizeof(v));
+       if (n != sizeof(v))
+               goto err_out;
+       mpsc_base = v;
+
+       sdma_base = mpsc_get_virtreg_of_phandle(devp, "sdma");
+       if (sdma_base == NULL)
+               goto err_out;
+
+       mpscintr_base = mpsc_get_virtreg_of_phandle(devp, "mpscintr");
+       if (mpscintr_base == NULL)
+               goto err_out;
+
+       n = getprop(devp, "block-index", &v, sizeof(v));
+       if (n != sizeof(v))
+               goto err_out;
+       reg_set = (int)v;
+
+       mpscintr_base += (reg_set == 0) ? 0x4 : 0xc;
+
+       /* Make sure the mpsc ctlrs are shutdown */
+       out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE), 0);
+       out_le32((u32 *)(mpscintr_base + MPSC_INTR_CAUSE), 0);
+       out_le32((u32 *)(mpscintr_base + MPSC_INTR_MASK), 0);
+       out_le32((u32 *)(mpscintr_base + MPSC_INTR_MASK), 0);
+
+       mpsc_stop_dma(sdma_base);
+
+       scdp->open = mpsc_open;
+       scdp->putc = mpsc_putc;
+       scdp->getc = mpsc_getc;
+       scdp->tstc = mpsc_tstc;
+       scdp->close = NULL;
+
+       return 0;
+
+err_out:
+       return -1;
+}
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h
index 73bd47a..959124f 100644
--- a/arch/powerpc/boot/ops.h
+++ b/arch/powerpc/boot/ops.h
@@ -79,6 +79,7 @@ void start(void);
 int ft_init(void *dt_blob, unsigned int max_size, unsigned int 
max_find_device);
 int serial_console_init(void);
 int ns16550_console_init(void *devp, struct serial_console_data *scdp);
+int mpsc_console_init(void *devp, struct serial_console_data *scdp);
 void *simple_alloc_init(char *base, unsigned long heap_size,
                        unsigned long granularity, unsigned long max_allocs);
 extern void flush_cache(void *, unsigned long);
diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c
index e8de4cf..7fd3233 100644
--- a/arch/powerpc/boot/serial.c
+++ b/arch/powerpc/boot/serial.c
@@ -125,6 +125,8 @@ int serial_console_init(void)
 
        if (!strcmp(compat, "ns16550"))
                rc = ns16550_console_init(devp, &serial_cd);
+       else if (!strcmp(compat, "marvell,mpsc"))
+               rc = mpsc_console_init(devp, &serial_cd);
 
        /* Add other serial console driver calls here */
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to