summaryrefslogtreecommitdiff
path: root/firmware/target/mips
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2022-06-23 16:37:02 +0100
committerAidan MacDonald <amachronic@protonmail.com>2022-07-21 11:39:03 +0100
commit9ab5d311cba93ce9fe1409b9dbb6ed2da24830c9 (patch)
tree8d4e98082f24d4623fd5f40a337fe1f687da868a /firmware/target/mips
parent2fce0a98f8b3f0efd15cc1463430023f739dab30 (diff)
downloadrockbox-9ab5d311cba93ce9fe1409b9dbb6ed2da24830c9.tar.gz
rockbox-9ab5d311cba93ce9fe1409b9dbb6ed2da24830c9.zip
x1000: move NAND commands to chip data
Using predefined commands is too inflexible so allow the chip data to specify I/O commands directly. Change-Id: Ie8f943914da4b8299678a59b1063c4c6d226e83e
Diffstat (limited to 'firmware/target/mips')
-rw-r--r--firmware/target/mips/ingenic_x1000/nand-x1000.c35
-rw-r--r--firmware/target/mips/ingenic_x1000/nand-x1000.h18
2 files changed, 18 insertions, 35 deletions
diff --git a/firmware/target/mips/ingenic_x1000/nand-x1000.c b/firmware/target/mips/ingenic_x1000/nand-x1000.c
index e22c639b8f..896ac97d28 100644
--- a/firmware/target/mips/ingenic_x1000/nand-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/nand-x1000.c
@@ -31,8 +31,6 @@ const struct nand_chip supported_nand_chips[] = {
31 /* ATO25D1GA */ 31 /* ATO25D1GA */
32 .mf_id = 0x9b, 32 .mf_id = 0x9b,
33 .dev_id = 0x12, 33 .dev_id = 0x12,
34 .row_cycles = 3,
35 .col_cycles = 2,
36 .log2_ppb = 6, /* 64 pages */ 34 .log2_ppb = 6, /* 64 pages */
37 .page_size = 2048, 35 .page_size = 2048,
38 .oob_size = 64, 36 .oob_size = 64,
@@ -46,6 +44,11 @@ const struct nand_chip supported_nand_chips[] = {
46 STA_TYPE_V(1BYTE), CMD_TYPE_V(8BITS), 44 STA_TYPE_V(1BYTE), CMD_TYPE_V(8BITS),
47 SMP_DELAY(1)), 45 SMP_DELAY(1)),
48 .flags = NAND_CHIPFLAG_QUAD | NAND_CHIPFLAG_HAS_QE_BIT, 46 .flags = NAND_CHIPFLAG_QUAD | NAND_CHIPFLAG_HAS_QE_BIT,
47 .cmd_page_read = NANDCMD_PAGE_READ(3),
48 .cmd_program_execute = NANDCMD_PROGRAM_EXECUTE(3),
49 .cmd_block_erase = NANDCMD_BLOCK_ERASE(3),
50 .cmd_read_cache = NANDCMD_READ_CACHE_x4(2),
51 .cmd_program_load = NANDCMD_PROGRAM_LOAD_x4(2),
49 }, 52 },
50#else 53#else
51 { 0 }, 54 { 0 },
@@ -127,22 +130,6 @@ static void setup_chip_data(struct nand_drv* drv)
127 drv->fpage_size = drv->chip->page_size + drv->chip->oob_size; 130 drv->fpage_size = drv->chip->page_size + drv->chip->oob_size;
128} 131}
129 132
130static void setup_chip_commands(struct nand_drv* drv)
131{
132 /* Select commands appropriate for the chip */
133 drv->cmd_page_read = NANDCMD_PAGE_READ(drv->chip->row_cycles);
134 drv->cmd_program_execute = NANDCMD_PROGRAM_EXECUTE(drv->chip->row_cycles);
135 drv->cmd_block_erase = NANDCMD_BLOCK_ERASE(drv->chip->row_cycles);
136
137 if(drv->chip->flags & NAND_CHIPFLAG_QUAD) {
138 drv->cmd_read_cache = NANDCMD_READ_CACHE_x4(drv->chip->col_cycles);
139 drv->cmd_program_load = NANDCMD_PROGRAM_LOAD_x4(drv->chip->col_cycles);
140 } else {
141 drv->cmd_read_cache = NANDCMD_READ_CACHE(drv->chip->col_cycles);
142 drv->cmd_program_load = NANDCMD_PROGRAM_LOAD(drv->chip->col_cycles);
143 }
144}
145
146static void setup_chip_registers(struct nand_drv* drv) 133static void setup_chip_registers(struct nand_drv* drv)
147{ 134{
148 /* Set chip registers to enter normal operation */ 135 /* Set chip registers to enter normal operation */
@@ -189,7 +176,6 @@ int nand_open(struct nand_drv* drv)
189 return NAND_ERR_UNKNOWN_CHIP; 176 return NAND_ERR_UNKNOWN_CHIP;
190 177
191 setup_chip_data(drv); 178 setup_chip_data(drv);
192 setup_chip_commands(drv);
193 179
194 /* Set new SFC parameters */ 180 /* Set new SFC parameters */
195 sfc_set_dev_conf(drv->chip->dev_conf); 181 sfc_set_dev_conf(drv->chip->dev_conf);
@@ -234,7 +220,7 @@ static uint8_t nand_wait_busy(struct nand_drv* drv)
234int nand_block_erase(struct nand_drv* drv, nand_block_t block) 220int nand_block_erase(struct nand_drv* drv, nand_block_t block)
235{ 221{
236 sfc_exec(NANDCMD_WR_EN, 0, NULL, 0); 222 sfc_exec(NANDCMD_WR_EN, 0, NULL, 0);
237 sfc_exec(drv->cmd_block_erase, block, NULL, 0); 223 sfc_exec(drv->chip->cmd_block_erase, block, NULL, 0);
238 224
239 uint8_t status = nand_wait_busy(drv); 225 uint8_t status = nand_wait_busy(drv);
240 if(status & FREG_STATUS_EFAIL) 226 if(status & FREG_STATUS_EFAIL)
@@ -246,8 +232,9 @@ int nand_block_erase(struct nand_drv* drv, nand_block_t block)
246int nand_page_program(struct nand_drv* drv, nand_page_t page, const void* buffer) 232int nand_page_program(struct nand_drv* drv, nand_page_t page, const void* buffer)
247{ 233{
248 sfc_exec(NANDCMD_WR_EN, 0, NULL, 0); 234 sfc_exec(NANDCMD_WR_EN, 0, NULL, 0);
249 sfc_exec(drv->cmd_program_load, 0, (void*)buffer, drv->fpage_size|SFC_WRITE); 235 sfc_exec(drv->chip->cmd_program_load,
250 sfc_exec(drv->cmd_program_execute, page, NULL, 0); 236 0, (void*)buffer, drv->fpage_size|SFC_WRITE);
237 sfc_exec(drv->chip->cmd_program_execute, page, NULL, 0);
251 238
252 uint8_t status = nand_wait_busy(drv); 239 uint8_t status = nand_wait_busy(drv);
253 if(status & FREG_STATUS_PFAIL) 240 if(status & FREG_STATUS_PFAIL)
@@ -258,9 +245,9 @@ int nand_page_program(struct nand_drv* drv, nand_page_t page, const void* buffer
258 245
259int nand_page_read(struct nand_drv* drv, nand_page_t page, void* buffer) 246int nand_page_read(struct nand_drv* drv, nand_page_t page, void* buffer)
260{ 247{
261 sfc_exec(drv->cmd_page_read, page, NULL, 0); 248 sfc_exec(drv->chip->cmd_page_read, page, NULL, 0);
262 nand_wait_busy(drv); 249 nand_wait_busy(drv);
263 sfc_exec(drv->cmd_read_cache, 0, buffer, drv->fpage_size|SFC_READ); 250 sfc_exec(drv->chip->cmd_read_cache, 0, buffer, drv->fpage_size|SFC_READ);
264 251
265 if(drv->chip->flags & NAND_CHIPFLAG_ON_DIE_ECC) { 252 if(drv->chip->flags & NAND_CHIPFLAG_ON_DIE_ECC) {
266 uint8_t status = nand_get_reg(drv, FREG_STATUS); 253 uint8_t status = nand_get_reg(drv, FREG_STATUS);
diff --git a/firmware/target/mips/ingenic_x1000/nand-x1000.h b/firmware/target/mips/ingenic_x1000/nand-x1000.h
index bc80ecce07..b2bf4da358 100644
--- a/firmware/target/mips/ingenic_x1000/nand-x1000.h
+++ b/firmware/target/mips/ingenic_x1000/nand-x1000.h
@@ -106,10 +106,6 @@ struct nand_chip {
106 uint8_t dev_id; 106 uint8_t dev_id;
107 uint8_t dev_id2; 107 uint8_t dev_id2;
108 108
109 /* Row/column address width */
110 uint8_t row_cycles;
111 uint8_t col_cycles;
112
113 /* Base2 logarithm of the number of pages per block */ 109 /* Base2 logarithm of the number of pages per block */
114 unsigned log2_ppb; 110 unsigned log2_ppb;
115 111
@@ -132,6 +128,13 @@ struct nand_chip {
132 /* Chip specific flags */ 128 /* Chip specific flags */
133 uint32_t flags; 129 uint32_t flags;
134 130
131 /* SFC commands for issuing I/O ops */
132 uint32_t cmd_page_read;
133 uint32_t cmd_program_execute;
134 uint32_t cmd_block_erase;
135 uint32_t cmd_read_cache;
136 uint32_t cmd_program_load;
137
135 /* Chip-specific setup routine */ 138 /* Chip-specific setup routine */
136 void(*setup_chip)(struct nand_drv* drv); 139 void(*setup_chip)(struct nand_drv* drv);
137}; 140};
@@ -170,13 +173,6 @@ struct nand_drv {
170 uint8_t mf_id; 173 uint8_t mf_id;
171 uint8_t dev_id; 174 uint8_t dev_id;
172 uint8_t dev_id2; 175 uint8_t dev_id2;
173
174 /* SFC commands used for I/O, these are set based on chip data */
175 uint32_t cmd_page_read;
176 uint32_t cmd_read_cache;
177 uint32_t cmd_program_load;
178 uint32_t cmd_program_execute;
179 uint32_t cmd_block_erase;
180}; 176};
181 177
182extern const struct nand_chip supported_nand_chips[]; 178extern const struct nand_chip supported_nand_chips[];