Merge branch '080131_artila' of git://linux-arm.org/u-boot-armdev
[platform/kernel/u-boot.git] / lib_arm / armlinux.c
index 8ba9f0c..42098fc 100644 (file)
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307         USA
  *
  */
 
@@ -30,6 +30,8 @@
 #include <dataflash.h>
 #endif
 
+DECLARE_GLOBAL_DATA_PTR;
+
 /*cmd_boot.c*/
 extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 
@@ -38,7 +40,8 @@ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
     defined (CONFIG_INITRD_TAG) || \
     defined (CONFIG_SERIAL_TAG) || \
     defined (CONFIG_REVISION_TAG) || \
-    defined (CONFIG_VFD)
+    defined (CONFIG_VFD) || \
+    defined (CONFIG_LCD)
 static void setup_start_tag (bd_t *bd);
 
 # ifdef CONFIG_SETUP_MEMORY_TAGS
@@ -55,7 +58,7 @@ static void setup_initrd_tag (bd_t *bd, ulong initrd_start,
 # endif
 static void setup_end_tag (bd_t *bd);
 
-# if defined (CONFIG_VFD)
+# if defined (CONFIG_VFD) || defined (CONFIG_LCD)
 static void setup_videolfb_tag (gd_t *gd);
 # endif
 
@@ -63,27 +66,20 @@ static void setup_videolfb_tag (gd_t *gd);
 static struct tag *params;
 #endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
 
-#ifdef CONFIG_SHOW_BOOT_PROGRESS
-# include <status_led.h>
-# define SHOW_BOOT_PROGRESS(arg)       show_boot_progress(arg)
-#else
-# define SHOW_BOOT_PROGRESS(arg)
-#endif
-
 extern image_header_t header;  /* from cmd_bootm.c */
 
 
 void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
                     ulong addr, ulong *len_ptr, int verify)
 {
-       DECLARE_GLOBAL_DATA_PTR;
-
        ulong len = 0, checksum;
        ulong initrd_start, initrd_end;
        ulong data;
        void (*theKernel)(int zero, int arch, uint params);
        image_header_t *hdr = &header;
        bd_t *bd = gd->bd;
+       int machid = bd->bi_arch_number;
+       char *s;
 
 #ifdef CONFIG_CMDLINE_TAG
        char *commandline = getenv ("bootargs");
@@ -91,11 +87,17 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
 
        theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);
 
+       s = getenv ("machid");
+       if (s) {
+               machid = simple_strtoul (s, NULL, 16);
+               printf ("Using machid 0x%x from environment\n", machid);
+       }
+
        /*
         * Check if there is an initrd image
         */
        if (argc >= 3) {
-               SHOW_BOOT_PROGRESS (9);
+               show_boot_progress (9);
 
                addr = simple_strtoul (argv[2], NULL, 16);
 
@@ -113,7 +115,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
 
                if (ntohl (hdr->ih_magic) != IH_MAGIC) {
                        printf ("Bad Magic Number\n");
-                       SHOW_BOOT_PROGRESS (-10);
+                       show_boot_progress (-10);
                        do_reset (cmdtp, flag, argc, argv);
                }
 
@@ -123,13 +125,13 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
                checksum = ntohl (hdr->ih_hcrc);
                hdr->ih_hcrc = 0;
 
-               if (crc32 (0, (char *) data, len) != checksum) {
+               if (crc32 (0, (unsigned char *) data, len) != checksum) {
                        printf ("Bad Header Checksum\n");
-                       SHOW_BOOT_PROGRESS (-11);
+                       show_boot_progress (-11);
                        do_reset (cmdtp, flag, argc, argv);
                }
 
-               SHOW_BOOT_PROGRESS (10);
+               show_boot_progress (10);
 
                print_image_hdr (hdr);
 
@@ -147,32 +149,33 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
                        ulong csum = 0;
 
                        printf ("   Verifying Checksum ... ");
-                       csum = crc32 (0, (char *) data, len);
+                       csum = crc32 (0, (unsigned char *) data, len);
                        if (csum != ntohl (hdr->ih_dcrc)) {
                                printf ("Bad Data CRC\n");
-                               SHOW_BOOT_PROGRESS (-12);
+                               show_boot_progress (-12);
                                do_reset (cmdtp, flag, argc, argv);
                        }
                        printf ("OK\n");
                }
 
-               SHOW_BOOT_PROGRESS (11);
+               show_boot_progress (11);
 
                if ((hdr->ih_os != IH_OS_LINUX) ||
                    (hdr->ih_arch != IH_CPU_ARM) ||
                    (hdr->ih_type != IH_TYPE_RAMDISK)) {
                        printf ("No Linux ARM Ramdisk Image\n");
-                       SHOW_BOOT_PROGRESS (-13);
+                       show_boot_progress (-13);
                        do_reset (cmdtp, flag, argc, argv);
                }
 
-#ifdef CONFIG_B2
+#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) ||   \
+               defined(CONFIG_ARMADILLO) || defined(CONFIG_M501SK)
                /*
                 *we need to copy the ramdisk to SRAM to let Linux boot
                 */
                memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len);
                data = ntohl(hdr->ih_load);
-#endif /* CONFIG_B2 */
+#endif /* CONFIG_B2 || CONFIG_EVB4510 */
 
                /*
                 * Now check if we have a multifile image
@@ -181,7 +184,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
                ulong tail = ntohl (len_ptr[0]) % 4;
                int i;
 
-               SHOW_BOOT_PROGRESS (13);
+               show_boot_progress (13);
 
                /* skip kernel length and terminator */
                data = (ulong) (&len_ptr[2]);
@@ -200,7 +203,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
                /*
                 * no initrd image
                 */
-               SHOW_BOOT_PROGRESS (14);
+               show_boot_progress (14);
 
                len = data = 0;
        }
@@ -219,7 +222,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
                initrd_end = 0;
        }
 
-       SHOW_BOOT_PROGRESS (15);
+       show_boot_progress (15);
 
        debug ("## Transferring control to Linux (at address %08lx) ...\n",
               (ulong) theKernel);
@@ -229,6 +232,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
     defined (CONFIG_INITRD_TAG) || \
     defined (CONFIG_SERIAL_TAG) || \
     defined (CONFIG_REVISION_TAG) || \
+    defined (CONFIG_LCD) || \
     defined (CONFIG_VFD)
        setup_start_tag (bd);
 #ifdef CONFIG_SERIAL_TAG
@@ -247,7 +251,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
        if (initrd_start && initrd_end)
                setup_initrd_tag (bd, initrd_start, initrd_end);
 #endif
-#if defined (CONFIG_VFD)
+#if defined (CONFIG_VFD) || defined (CONFIG_LCD)
        setup_videolfb_tag ((gd_t *) gd);
 #endif
        setup_end_tag (bd);
@@ -256,9 +260,16 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
        /* we assume that the kernel is in place */
        printf ("\nStarting kernel ...\n\n");
 
+#ifdef CONFIG_USB_DEVICE
+       {
+               extern void udc_disconnect (void);
+               udc_disconnect ();
+       }
+#endif
+
        cleanup_before_linux ();
 
-       theKernel (0, bd->bi_arch_number, bd->bi_boot_params);
+       theKernel (0, machid, bd->bi_boot_params);
 }
 
 
@@ -267,6 +278,7 @@ void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
     defined (CONFIG_INITRD_TAG) || \
     defined (CONFIG_SERIAL_TAG) || \
     defined (CONFIG_REVISION_TAG) || \
+    defined (CONFIG_LCD) || \
     defined (CONFIG_VFD)
 static void setup_start_tag (bd_t *bd)
 {
@@ -305,6 +317,9 @@ static void setup_commandline_tag (bd_t *bd, char *commandline)
 {
        char *p;
 
+       if (!commandline)
+               return;
+
        /* eat leading white space */
        for (p = commandline; *p == ' '; p++);
 
@@ -330,7 +345,7 @@ static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end)
        /* an ATAG_INITRD node tells the kernel where the compressed
         * ramdisk can be found. ATAG_RDIMG is a better name, actually.
         */
-       params->hdr.tag = ATAG_INITRD;
+       params->hdr.tag = ATAG_INITRD2;
        params->hdr.size = tag_size (tag_initrd);
 
        params->u.initrd.start = initrd_start;
@@ -341,7 +356,8 @@ static void setup_initrd_tag (bd_t *bd, ulong initrd_start, ulong initrd_end)
 #endif /* CONFIG_INITRD_TAG */
 
 
-#if defined (CONFIG_VFD)
+#if defined (CONFIG_VFD) || defined (CONFIG_LCD)
+extern ulong calc_fbsize (void);
 static void setup_videolfb_tag (gd_t *gd)
 {
        /* An ATAG_VIDEOLFB node tells the kernel where and how large
@@ -355,13 +371,46 @@ static void setup_videolfb_tag (gd_t *gd)
        params->hdr.size = tag_size (tag_videolfb);
 
        params->u.videolfb.lfb_base = (u32) gd->fb_base;
-       /* 7168 = 256*4*56/8 - actually 2 pages (8192 bytes) are allocated */
-       params->u.videolfb.lfb_size = 7168;
+       /* Fb size is calculated according to parameters for our panel
+        */
+       params->u.videolfb.lfb_size = calc_fbsize();
 
        params = tag_next (params);
 }
+#endif /* CONFIG_VFD || CONFIG_LCD */
+
+#ifdef CONFIG_SERIAL_TAG
+void setup_serial_tag (struct tag **tmp)
+{
+       struct tag *params = *tmp;
+       struct tag_serialnr serialnr;
+       void get_board_serial(struct tag_serialnr *serialnr);
+
+       get_board_serial(&serialnr);
+       params->hdr.tag = ATAG_SERIAL;
+       params->hdr.size = tag_size (tag_serialnr);
+       params->u.serialnr.low = serialnr.low;
+       params->u.serialnr.high= serialnr.high;
+       params = tag_next (params);
+       *tmp = params;
+}
 #endif
 
+#ifdef CONFIG_REVISION_TAG
+void setup_revision_tag(struct tag **in_params)
+{
+       u32 rev = 0;
+       u32 get_board_rev(void);
+
+       rev = get_board_rev();
+       params->hdr.tag = ATAG_REVISION;
+       params->hdr.size = tag_size (tag_revision);
+       params->u.revision.rev = rev;
+       params = tag_next (params);
+}
+#endif  /* CONFIG_REVISION_TAG */
+
+
 static void setup_end_tag (bd_t *bd)
 {
        params->hdr.tag = ATAG_NONE;