summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-04-07 22:11:01 +0100
committerAidan MacDonald <amachronic@protonmail.com>2021-04-17 20:22:49 +0000
commit1b8542490da3283dfa0ce0f3363f16eab0609815 (patch)
treed3775ef4ee2739e0f140dc70f70e422bc06059f3 /firmware/target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c
parent85fbbd9c7f3e1ac84910a16095a297cbe13a8123 (diff)
downloadrockbox-1b8542490da3283dfa0ce0f3363f16eab0609815.tar.gz
rockbox-1b8542490da3283dfa0ce0f3363f16eab0609815.zip
x1000: Redesign SPL, and allow it to flash the bootloader
SPL is now designed so core X1000 code is in control of the boot, under the reasonable assumption that the device boots from flash. It should not be too hard to adapt to other X1000 ports. The biggest functional change is that the SPL can now read/write the flash, under the control of a host computer. The SPL relies on the boot ROM for USB communication, so the host has to execute the SPL multiple times following a protocol. Change-Id: I3ffaa00e4bf191e043c9df0e2e64d15193ff42c9
Diffstat (limited to 'firmware/target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c')
-rw-r--r--firmware/target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/firmware/target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c b/firmware/target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c
new file mode 100644
index 0000000000..0ebe11e24d
--- /dev/null
+++ b/firmware/target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c
@@ -0,0 +1,132 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "spl-x1000.h"
23#include "gpio-x1000.h"
24#include "nand-x1000.h"
25#include "system.h"
26#include <string.h>
27
28/* Boot select button state must remain stable for this duration
29 * before the choice will be accepted. Currently 100ms.
30 */
31#define BTN_STABLE_TIME (100 * (X1000_EXCLK_FREQ / 4000))
32
33static const char normal_cmdline[] = "mem=64M@0x0\
34 no_console_suspend\
35 console=ttyS2,115200n8\
36 lpj=5009408\
37 ip=off\
38 init=/linuxrc\
39 ubi.mtd=3\
40 root=ubi0:rootfs\
41 ubi.mtd=4\
42 rootfstype=ubifs\
43 rw\
44 loglevel=8";
45
46static const char recovery_cmdline[] = "mem=64M@0x0\
47 no_console_suspend\
48 console=ttyS2,115200n8\
49 lpj=5009408\
50 ip=off";
51
52const struct spl_boot_option spl_boot_options[] = {
53 {
54 /* Rockbox: the first unused NAND page is 26 KiB in, and the
55 * remainder of the block is unused, giving us 102 KiB to use.
56 */
57 .nand_addr = 0x6800,
58 .nand_size = 0x19800,
59 .load_addr = 0x80003ff8, /* first 8 bytes are bootloader ID */
60 .exec_addr = 0x80004000,
61 .cmdline = NULL,
62 },
63 {
64 /* Original firmware */
65 .nand_addr = 0x20000,
66 .nand_size = 0x400000,
67 .load_addr = 0x80efffc0,
68 .exec_addr = 0x80f00000,
69 .cmdline = normal_cmdline,
70 },
71 {
72 /* Recovery image */
73 .nand_addr = 0x420000,
74 .nand_size = 0x500000,
75 .load_addr = 0x80efffc0,
76 .exec_addr = 0x80f00000,
77 .cmdline = recovery_cmdline,
78 },
79};
80
81void spl_error(void)
82{
83 const int pin = (1 << 24);
84
85 /* Turn on button light */
86 jz_clr(GPIO_INT(GPIO_C), pin);
87 jz_set(GPIO_MSK(GPIO_C), pin);
88 jz_clr(GPIO_PAT1(GPIO_C), pin);
89 jz_set(GPIO_PAT0(GPIO_C), pin);
90
91 while(1) {
92 /* Turn it off */
93 mdelay(100);
94 jz_set(GPIO_PAT0(GPIO_C), pin);
95
96 /* Turn it on */
97 mdelay(100);
98 jz_clr(GPIO_PAT0(GPIO_C), pin);
99 }
100}
101
102int spl_get_boot_option(void)
103{
104 const uint32_t pinmask = (1 << 17) | (1 << 19);
105
106 uint32_t pin = 1, lastpin = 0;
107 uint32_t deadline = 0;
108
109 /* Configure the button GPIOs as inputs */
110 gpio_config(GPIO_A, pinmask, GPIO_INPUT);
111
112 /* Poll the pins for a short duration to detect a keypress */
113 do {
114 lastpin = pin;
115 pin = ~REG_GPIO_PIN(GPIO_A) & pinmask;
116 if(pin != lastpin) {
117 /* This will always be set on the first iteration */
118 deadline = __ost_read32() + BTN_STABLE_TIME;
119 }
120 } while(__ost_read32() < deadline);
121
122 /* Play button boots original firmware */
123 if(pin == (1 << 17))
124 return SPL_BOOTOPT_ORIG_FW;
125
126 /* Volume up boots recovery */
127 if(pin == (1 << 19))
128 return SPL_BOOTOPT_RECOVERY;
129
130 /* Default is to boot Rockbox */
131 return SPL_BOOTOPT_ROCKBOX;
132}