blob: 548bb3686f8ea952210979cda38dfcab8b17d12b [file] [log] [blame]
Amaury Pouly08fb3f62011-05-01 13:02:46 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by amaury Pouly
11 *
12 * Based on Rockbox iriver bootloader by Linus Nielsen Feltzing
13 * and the ipodlinux bootloader by Daniel Palffy and Bernard Leach
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#include <stdio.h>
26#include <system.h>
27#include <inttypes.h>
28#include "config.h"
29#include "gcc_extensions.h"
30#include "lcd.h"
31#include "backlight.h"
32#include "button-target.h"
33#include "common.h"
34#include "storage.h"
35#include "disk.h"
36#include "panic.h"
37#include "power.h"
Amaury Pouly86e8c282011-05-11 22:38:09 +000038#include "system-target.h"
Amaury Pouly5a268112011-07-09 17:14:05 +000039#include "fmradio_i2c.h"
Amaury Pouly2cf33132011-06-17 22:30:58 +000040
41#include "usb.h"
Amaury Pouly7d4fed52011-09-05 11:29:32 +000042#include "usb-target.h"
43
44#include "clkctrl-imx233.h"
45
46#ifdef HAVE_BOOTLOADER_USB_MODE
47static void usb_mode(int connect_timeout)
48{
49 int button;
50
51 usb_init();
52 usb_start_monitoring();
53
54 /* Wait for threads to connect or cable is pulled */
55 printf("USB: Connecting");
56
57 long end_tick = current_tick + connect_timeout;
58
59 while(1)
60 {
61 button = button_get_w_tmo(HZ/10);
62
63 if(button == SYS_USB_CONNECTED)
64 break; /* Hit */
65
66 if(TIME_AFTER(current_tick, end_tick))
67 {
68 /* Timed out waiting for the connect - will happen when connected
69 * to a charger through the USB port */
70 printf("USB: Timed out");
71 break;
72 }
73
74 if(!usb_plugged())
75 break; /* Cable pulled */
76 }
77
78 if(button == SYS_USB_CONNECTED)
79 {
80 /* Got the message - wait for disconnect */
81 printf("Bootloader USB mode");
82
83 usb_acknowledge(SYS_USB_CONNECTED_ACK);
84
85 while(1)
86 {
87 button = button_get_w_tmo(HZ/2);
88 if(button == SYS_USB_DISCONNECTED)
89 break;
90 }
91 }
92
93 /* Put drivers initialized for USB connection into a known state */
94 usb_close();
Amaury Pouly7d4fed52011-09-05 11:29:32 +000095}
96#else /* !HAVE_BOOTLOADER_USB_MODE */
97static void usb_mode(int connect_timeout)
98{
99 (void) connect_timeout;
100}
101#endif /* HAVE_BOOTLOADER_USB_MODE */
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000102
Amaury Pouly82f70b82011-07-22 15:45:58 +0000103void main(uint32_t arg) NORETURN_ATTR;
104void main(uint32_t arg)
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000105{
106 unsigned char* loadbuffer;
107 int buffer_size;
108 void(*kernel_entry)(void);
109 int ret;
110
111 system_init();
112 kernel_init();
113
Amaury Pouly7d4fed52011-09-05 11:29:32 +0000114 power_init();
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000115 enable_irq();
116
117 lcd_init();
Amaury Pouly82ecc752011-07-02 02:12:10 +0000118 lcd_clear_display();
119 lcd_update();
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000120
121 backlight_init();
122
Amaury Pouly7d4fed52011-09-05 11:29:32 +0000123 button_init();
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000124
Amaury Pouly2cf33132011-06-17 22:30:58 +0000125 //button_debug_screen();
Amaury Pouly7d4fed52011-09-05 11:29:32 +0000126 printf("arg=%x", arg);
127
128#ifdef SANSA_FUZEPLUS
129 extern void imx233_mmc_disable_window(void);
130 if(arg == 0xfee1dead)
131 {
132 printf("Disable MMC window.");
133 imx233_mmc_disable_window();
134 }
135#endif
Amaury Pouly86e8c282011-05-11 22:38:09 +0000136
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000137 ret = storage_init();
138 if(ret < 0)
139 error(EATA, ret, true);
140
Amaury Pouly333b9ed2011-09-05 18:32:40 +0000141 /* NOTE: allow disk_init and disk_mount_all to fail since we can do USB after.
142 * We need this order to determine the correct logical sector size */
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000143 while(!disk_init(IF_MV(0)))
Amaury Pouly7d4fed52011-09-05 11:29:32 +0000144 printf("disk_init failed!");
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000145
Amaury Pouly7d4fed52011-09-05 11:29:32 +0000146 if((ret = disk_mount_all()) <= 0)
147 error(EDISK, ret, false);
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000148
Amaury Pouly25f00602011-09-05 13:58:29 +0000149 if(usb_plugged())
150 usb_mode(HZ);
Amaury Pouly82f70b82011-07-22 15:45:58 +0000151
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000152 printf("Loading firmware");
153
154 loadbuffer = (unsigned char*)DRAM_ORIG; /* DRAM */
155 buffer_size = (int)(loadbuffer + DRAM_SIZE - TTB_SIZE);
156
157 while((ret = load_firmware(loadbuffer, BOOTFILE, buffer_size)) < 0)
158 {
159 error(EBOOTFILE, ret, true);
160 }
161
162 kernel_entry = (void*) loadbuffer;
Amaury Pouly25f00602011-09-05 13:58:29 +0000163 cpucache_invalidate();
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000164 printf("Executing");
165 kernel_entry();
166 printf("ERR: Failed to boot");
167
168 /* never returns */
169 while(1) ;
170}