powerpc/pmac: Early debug output on screen on 64-bit macs
[linux-2.6-block.git] / arch / powerpc / kernel / btext.c
index ac8f52732fde2948675be0983a5a47dd8163584c..0428992fdb4bf9690b44daf19abff613d5d4fc6a 100644 (file)
 static void scrollscreen(void);
 #endif
 
-static void draw_byte(unsigned char c, long locX, long locY);
-static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb);
-static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb);
-static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb);
-
 #define __force_data __attribute__((__section__(".data")))
 
 static int g_loc_X __force_data;
@@ -52,6 +47,26 @@ static unsigned char vga_font[cmapsz];
 int boot_text_mapped __force_data = 0;
 int force_printk_to_btext = 0;
 
+extern void rmci_on(void);
+extern void rmci_off(void);
+
+static inline void rmci_maybe_on(void)
+{
+#ifdef CONFIG_PPC_EARLY_DEBUG_BOOTX
+       if (!(mfmsr() & MSR_DR))
+               rmci_on();
+#endif
+}
+
+static inline void rmci_maybe_off(void)
+{
+#ifdef CONFIG_PPC_EARLY_DEBUG_BOOTX
+       if (!(mfmsr() & MSR_DR))
+               rmci_off();
+#endif
+}
+
+
 #ifdef CONFIG_PPC32
 /* Calc BAT values for mapping the display and store them
  * in disp_BAT.  Those values are then used from head.S to map
@@ -134,7 +149,7 @@ void __init btext_unmap(void)
  *    changes.
  */
 
-static void map_boot_text(void)
+void btext_map(void)
 {
        unsigned long base, offset, size;
        unsigned char *vbase;
@@ -209,7 +224,7 @@ int btext_initialize(struct device_node *np)
        dispDeviceRect[2] = width;
        dispDeviceRect[3] = height;
 
-       map_boot_text();
+       btext_map();
 
        return 0;
 }
@@ -283,7 +298,7 @@ void btext_update_display(unsigned long phys, int width, int height,
                iounmap(logicalDisplayBase);
                boot_text_mapped = 0;
        }
-       map_boot_text();
+       btext_map();
        g_loc_X = 0;
        g_loc_Y = 0;
        g_max_loc_X = width / 8;
@@ -298,6 +313,7 @@ void btext_clearscreen(void)
                                        (dispDeviceDepth >> 3)) >> 2;
        int i,j;
 
+       rmci_maybe_on();
        for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
        {
                unsigned int *ptr = base;
@@ -305,6 +321,7 @@ void btext_clearscreen(void)
                        *(ptr++) = 0;
                base += (dispDeviceRowBytes >> 2);
        }
+       rmci_maybe_off();
 }
 
 void btext_flushscreen(void)
@@ -355,6 +372,8 @@ static void scrollscreen(void)
                                   (dispDeviceDepth >> 3)) >> 2;
        int i,j;
 
+       rmci_maybe_on();
+
        for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
        {
                unsigned int *src_ptr = src;
@@ -371,9 +390,116 @@ static void scrollscreen(void)
                        *(dst_ptr++) = 0;
                dst += (dispDeviceRowBytes >> 2);
        }
+
+       rmci_maybe_off();
 }
 #endif /* ndef NO_SCROLL */
 
+static unsigned int expand_bits_8[16] = {
+       0x00000000,
+       0x000000ff,
+       0x0000ff00,
+       0x0000ffff,
+       0x00ff0000,
+       0x00ff00ff,
+       0x00ffff00,
+       0x00ffffff,
+       0xff000000,
+       0xff0000ff,
+       0xff00ff00,
+       0xff00ffff,
+       0xffff0000,
+       0xffff00ff,
+       0xffffff00,
+       0xffffffff
+};
+
+static unsigned int expand_bits_16[4] = {
+       0x00000000,
+       0x0000ffff,
+       0xffff0000,
+       0xffffffff
+};
+
+
+static void draw_byte_32(unsigned char *font, unsigned int *base, int rb)
+{
+       int l, bits;
+       int fg = 0xFFFFFFFFUL;
+       int bg = 0x00000000UL;
+
+       for (l = 0; l < 16; ++l)
+       {
+               bits = *font++;
+               base[0] = (-(bits >> 7) & fg) ^ bg;
+               base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
+               base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
+               base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
+               base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
+               base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
+               base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
+               base[7] = (-(bits & 1) & fg) ^ bg;
+               base = (unsigned int *) ((char *)base + rb);
+       }
+}
+
+static inline void draw_byte_16(unsigned char *font, unsigned int *base, int rb)
+{
+       int l, bits;
+       int fg = 0xFFFFFFFFUL;
+       int bg = 0x00000000UL;
+       unsigned int *eb = (int *)expand_bits_16;
+
+       for (l = 0; l < 16; ++l)
+       {
+               bits = *font++;
+               base[0] = (eb[bits >> 6] & fg) ^ bg;
+               base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
+               base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
+               base[3] = (eb[bits & 3] & fg) ^ bg;
+               base = (unsigned int *) ((char *)base + rb);
+       }
+}
+
+static inline void draw_byte_8(unsigned char *font, unsigned int *base, int rb)
+{
+       int l, bits;
+       int fg = 0x0F0F0F0FUL;
+       int bg = 0x00000000UL;
+       unsigned int *eb = (int *)expand_bits_8;
+
+       for (l = 0; l < 16; ++l)
+       {
+               bits = *font++;
+               base[0] = (eb[bits >> 4] & fg) ^ bg;
+               base[1] = (eb[bits & 0xf] & fg) ^ bg;
+               base = (unsigned int *) ((char *)base + rb);
+       }
+}
+
+static noinline void draw_byte(unsigned char c, long locX, long locY)
+{
+       unsigned char *base     = calc_base(locX << 3, locY << 4);
+       unsigned char *font     = &vga_font[((unsigned int)c) * 16];
+       int rb                  = dispDeviceRowBytes;
+
+       rmci_maybe_on();
+       switch(dispDeviceDepth) {
+       case 24:
+       case 32:
+               draw_byte_32(font, (unsigned int *)base, rb);
+               break;
+       case 15:
+       case 16:
+               draw_byte_16(font, (unsigned int *)base, rb);
+               break;
+       case 8:
+               draw_byte_8(font, (unsigned int *)base, rb);
+               break;
+       }
+       rmci_maybe_off();
+}
+
 void btext_drawchar(char c)
 {
        int cline = 0;
@@ -465,107 +591,12 @@ void btext_drawhex(unsigned long v)
        btext_drawchar(' ');
 }
 
-static void draw_byte(unsigned char c, long locX, long locY)
-{
-       unsigned char *base     = calc_base(locX << 3, locY << 4);
-       unsigned char *font     = &vga_font[((unsigned int)c) * 16];
-       int rb                  = dispDeviceRowBytes;
-
-       switch(dispDeviceDepth) {
-       case 24:
-       case 32:
-               draw_byte_32(font, (unsigned int *)base, rb);
-               break;
-       case 15:
-       case 16:
-               draw_byte_16(font, (unsigned int *)base, rb);
-               break;
-       case 8:
-               draw_byte_8(font, (unsigned int *)base, rb);
-               break;
-       }
-}
-
-static unsigned int expand_bits_8[16] = {
-       0x00000000,
-       0x000000ff,
-       0x0000ff00,
-       0x0000ffff,
-       0x00ff0000,
-       0x00ff00ff,
-       0x00ffff00,
-       0x00ffffff,
-       0xff000000,
-       0xff0000ff,
-       0xff00ff00,
-       0xff00ffff,
-       0xffff0000,
-       0xffff00ff,
-       0xffffff00,
-       0xffffffff
-};
-
-static unsigned int expand_bits_16[4] = {
-       0x00000000,
-       0x0000ffff,
-       0xffff0000,
-       0xffffffff
-};
-
-
-static void draw_byte_32(unsigned char *font, unsigned int *base, int rb)
-{
-       int l, bits;
-       int fg = 0xFFFFFFFFUL;
-       int bg = 0x00000000UL;
-
-       for (l = 0; l < 16; ++l)
-       {
-               bits = *font++;
-               base[0] = (-(bits >> 7) & fg) ^ bg;
-               base[1] = (-((bits >> 6) & 1) & fg) ^ bg;
-               base[2] = (-((bits >> 5) & 1) & fg) ^ bg;
-               base[3] = (-((bits >> 4) & 1) & fg) ^ bg;
-               base[4] = (-((bits >> 3) & 1) & fg) ^ bg;
-               base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
-               base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
-               base[7] = (-(bits & 1) & fg) ^ bg;
-               base = (unsigned int *) ((char *)base + rb);
-       }
-}
-
-static void draw_byte_16(unsigned char *font, unsigned int *base, int rb)
-{
-       int l, bits;
-       int fg = 0xFFFFFFFFUL;
-       int bg = 0x00000000UL;
-       unsigned int *eb = (int *)expand_bits_16;
-
-       for (l = 0; l < 16; ++l)
-       {
-               bits = *font++;
-               base[0] = (eb[bits >> 6] & fg) ^ bg;
-               base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
-               base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
-               base[3] = (eb[bits & 3] & fg) ^ bg;
-               base = (unsigned int *) ((char *)base + rb);
-       }
-}
-
-static void draw_byte_8(unsigned char *font, unsigned int *base, int rb)
+void __init udbg_init_btext(void)
 {
-       int l, bits;
-       int fg = 0x0F0F0F0FUL;
-       int bg = 0x00000000UL;
-       unsigned int *eb = (int *)expand_bits_8;
-
-       for (l = 0; l < 16; ++l)
-       {
-               bits = *font++;
-               base[0] = (eb[bits >> 4] & fg) ^ bg;
-               base[1] = (eb[bits & 0xf] & fg) ^ bg;
-               base = (unsigned int *) ((char *)base + rb);
-       }
+       /* If btext is enabled, we might have a BAT setup for early display,
+        * thus we do enable some very basic udbg output
+        */
+       udbg_putc = btext_drawchar;
 }
 
 static unsigned char vga_font[cmapsz] = {
@@ -913,10 +944,3 @@ static unsigned char vga_font[cmapsz] = {
 0x00, 0x00, 0x00, 0x00,
 };
 
-void __init udbg_init_btext(void)
-{
-       /* If btext is enabled, we might have a BAT setup for early display,
-        * thus we do enable some very basic udbg output
-        */
-       udbg_putc = btext_drawchar;
-}