]> git.proxmox.com Git - mirror_qemu.git/blame - hw/ssi/aspeed_smc.c
aspeed/smc: Introduce segment operations
[mirror_qemu.git] / hw / ssi / aspeed_smc.c
CommitLineData
7c1c69bc
CLG
1/*
2 * ASPEED AST2400 SMC Controller (SPI Flash Only)
3 *
4 * Copyright (C) 2016 IBM Corp.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25#include "qemu/osdep.h"
26#include "hw/sysbus.h"
d6454270 27#include "migration/vmstate.h"
7c1c69bc 28#include "qemu/log.h"
0b8fa32f 29#include "qemu/module.h"
d6e3f50a 30#include "qemu/error-report.h"
c4e1f0b4
CLG
31#include "qapi/error.h"
32#include "exec/address-spaces.h"
7c1c69bc 33
64552b6b 34#include "hw/irq.h"
a27bd6c7 35#include "hw/qdev-properties.h"
7c1c69bc
CLG
36#include "hw/ssi/aspeed_smc.h"
37
38/* CE Type Setting Register */
39#define R_CONF (0x00 / 4)
40#define CONF_LEGACY_DISABLE (1 << 31)
41#define CONF_ENABLE_W4 20
42#define CONF_ENABLE_W3 19
43#define CONF_ENABLE_W2 18
44#define CONF_ENABLE_W1 17
45#define CONF_ENABLE_W0 16
0707b34d
CLG
46#define CONF_FLASH_TYPE4 8
47#define CONF_FLASH_TYPE3 6
48#define CONF_FLASH_TYPE2 4
49#define CONF_FLASH_TYPE1 2
50#define CONF_FLASH_TYPE0 0
51#define CONF_FLASH_TYPE_NOR 0x0
52#define CONF_FLASH_TYPE_NAND 0x1
53#define CONF_FLASH_TYPE_SPI 0x2
7c1c69bc
CLG
54
55/* CE Control Register */
56#define R_CE_CTRL (0x04 / 4)
57#define CTRL_EXTENDED4 4 /* 32 bit addressing for SPI */
58#define CTRL_EXTENDED3 3 /* 32 bit addressing for SPI */
59#define CTRL_EXTENDED2 2 /* 32 bit addressing for SPI */
60#define CTRL_EXTENDED1 1 /* 32 bit addressing for SPI */
61#define CTRL_EXTENDED0 0 /* 32 bit addressing for SPI */
62
63/* Interrupt Control and Status Register */
64#define R_INTR_CTRL (0x08 / 4)
65#define INTR_CTRL_DMA_STATUS (1 << 11)
66#define INTR_CTRL_CMD_ABORT_STATUS (1 << 10)
67#define INTR_CTRL_WRITE_PROTECT_STATUS (1 << 9)
68#define INTR_CTRL_DMA_EN (1 << 3)
69#define INTR_CTRL_CMD_ABORT_EN (1 << 2)
70#define INTR_CTRL_WRITE_PROTECT_EN (1 << 1)
71
72/* CEx Control Register */
73#define R_CTRL0 (0x10 / 4)
0721309e
CLG
74#define CTRL_IO_DUAL_DATA (1 << 29)
75#define CTRL_IO_DUAL_ADDR_DATA (1 << 28) /* Includes dummies */
7c1c69bc
CLG
76#define CTRL_CMD_SHIFT 16
77#define CTRL_CMD_MASK 0xff
ac2810de 78#define CTRL_DUMMY_HIGH_SHIFT 14
fcdf2c59 79#define CTRL_AST2400_SPI_4BYTE (1 << 13)
0d72c717
CLG
80#define CE_CTRL_CLOCK_FREQ_SHIFT 8
81#define CE_CTRL_CLOCK_FREQ_MASK 0xf
82#define CE_CTRL_CLOCK_FREQ(div) \
83 (((div) & CE_CTRL_CLOCK_FREQ_MASK) << CE_CTRL_CLOCK_FREQ_SHIFT)
ac2810de 84#define CTRL_DUMMY_LOW_SHIFT 6 /* 2 bits [7:6] */
7c1c69bc
CLG
85#define CTRL_CE_STOP_ACTIVE (1 << 2)
86#define CTRL_CMD_MODE_MASK 0x3
87#define CTRL_READMODE 0x0
88#define CTRL_FREADMODE 0x1
89#define CTRL_WRITEMODE 0x2
90#define CTRL_USERMODE 0x3
91#define R_CTRL1 (0x14 / 4)
92#define R_CTRL2 (0x18 / 4)
93#define R_CTRL3 (0x1C / 4)
94#define R_CTRL4 (0x20 / 4)
95
96/* CEx Segment Address Register */
97#define R_SEG_ADDR0 (0x30 / 4)
a03cb1da
CLG
98#define SEG_END_SHIFT 24 /* 8MB units */
99#define SEG_END_MASK 0xff
7c1c69bc 100#define SEG_START_SHIFT 16 /* address bit [A29-A23] */
a03cb1da 101#define SEG_START_MASK 0xff
7c1c69bc
CLG
102#define R_SEG_ADDR1 (0x34 / 4)
103#define R_SEG_ADDR2 (0x38 / 4)
104#define R_SEG_ADDR3 (0x3C / 4)
105#define R_SEG_ADDR4 (0x40 / 4)
106
107/* Misc Control Register #1 */
108#define R_MISC_CTRL1 (0x50 / 4)
109
9149af2a
CLG
110/* SPI dummy cycle data */
111#define R_DUMMY_DATA (0x54 / 4)
7c1c69bc
CLG
112
113/* DMA Control/Status Register */
114#define R_DMA_CTRL (0x80 / 4)
115#define DMA_CTRL_DELAY_MASK 0xf
116#define DMA_CTRL_DELAY_SHIFT 8
117#define DMA_CTRL_FREQ_MASK 0xf
118#define DMA_CTRL_FREQ_SHIFT 4
0d72c717 119#define DMA_CTRL_CALIB (1 << 3)
7c1c69bc 120#define DMA_CTRL_CKSUM (1 << 2)
c4e1f0b4
CLG
121#define DMA_CTRL_WRITE (1 << 1)
122#define DMA_CTRL_ENABLE (1 << 0)
7c1c69bc
CLG
123
124/* DMA Flash Side Address */
125#define R_DMA_FLASH_ADDR (0x84 / 4)
126
127/* DMA DRAM Side Address */
128#define R_DMA_DRAM_ADDR (0x88 / 4)
129
130/* DMA Length Register */
131#define R_DMA_LEN (0x8C / 4)
132
133/* Checksum Calculation Result */
134#define R_DMA_CHECKSUM (0x90 / 4)
135
136/* Misc Control Register #2 */
137#define R_TIMINGS (0x94 / 4)
138
139/* SPI controller registers and bits */
140#define R_SPI_CONF (0x00 / 4)
141#define SPI_CONF_ENABLE_W0 0
142#define R_SPI_CTRL0 (0x4 / 4)
143#define R_SPI_MISC_CTRL (0x10 / 4)
144#define R_SPI_TIMINGS (0x14 / 4)
145
087b57c9
CLG
146#define ASPEED_SMC_R_SPI_MAX (0x20 / 4)
147#define ASPEED_SMC_R_SMC_MAX (0x20 / 4)
148
dcb83444
CLG
149#define ASPEED_SOC_SMC_FLASH_BASE 0x10000000
150#define ASPEED_SOC_FMC_FLASH_BASE 0x20000000
151#define ASPEED_SOC_SPI_FLASH_BASE 0x30000000
6dc52326 152#define ASPEED_SOC_SPI2_FLASH_BASE 0x38000000
dcb83444 153
c4e1f0b4
CLG
154/*
155 * DMA DRAM addresses should be 4 bytes aligned and the valid address
156 * range is 0x40000000 - 0x5FFFFFFF (AST2400)
157 * 0x80000000 - 0xBFFFFFFF (AST2500)
158 *
159 * DMA flash addresses should be 4 bytes aligned and the valid address
160 * range is 0x20000000 - 0x2FFFFFFF.
161 *
162 * DMA length is from 4 bytes to 32MB
163 * 0: 4 bytes
164 * 0x7FFFFF: 32M bytes
165 */
166#define DMA_DRAM_ADDR(s, val) ((s)->sdram_base | \
167 ((val) & (s)->ctrl->dma_dram_mask))
168#define DMA_FLASH_ADDR(s, val) ((s)->ctrl->flash_window_base | \
169 ((val) & (s)->ctrl->dma_flash_mask))
170#define DMA_LENGTH(val) ((val) & 0x01FFFFFC)
171
fcdf2c59
CLG
172/* Flash opcodes. */
173#define SPI_OP_READ 0x03 /* Read data bytes (low frequency) */
174
f95c4bff
CLG
175#define SNOOP_OFF 0xFF
176#define SNOOP_START 0x0
177
924ed163
CLG
178/*
179 * Default segments mapping addresses and size for each slave per
180 * controller. These can be changed when board is initialized with the
a03cb1da 181 * Segment Address Registers.
924ed163
CLG
182 */
183static const AspeedSegments aspeed_segments_legacy[] = {
184 { 0x10000000, 32 * 1024 * 1024 },
185};
186
187static const AspeedSegments aspeed_segments_fmc[] = {
6dc52326 188 { 0x20000000, 64 * 1024 * 1024 }, /* start address is readonly */
924ed163
CLG
189 { 0x24000000, 32 * 1024 * 1024 },
190 { 0x26000000, 32 * 1024 * 1024 },
191 { 0x28000000, 32 * 1024 * 1024 },
192 { 0x2A000000, 32 * 1024 * 1024 }
193};
194
195static const AspeedSegments aspeed_segments_spi[] = {
196 { 0x30000000, 64 * 1024 * 1024 },
197};
198
6dc52326
CLG
199static const AspeedSegments aspeed_segments_ast2500_fmc[] = {
200 { 0x20000000, 128 * 1024 * 1024 }, /* start address is readonly */
201 { 0x28000000, 32 * 1024 * 1024 },
202 { 0x2A000000, 32 * 1024 * 1024 },
203};
204
205static const AspeedSegments aspeed_segments_ast2500_spi1[] = {
206 { 0x30000000, 32 * 1024 * 1024 }, /* start address is readonly */
207 { 0x32000000, 96 * 1024 * 1024 }, /* end address is readonly */
208};
209
210static const AspeedSegments aspeed_segments_ast2500_spi2[] = {
211 { 0x38000000, 32 * 1024 * 1024 }, /* start address is readonly */
212 { 0x3A000000, 96 * 1024 * 1024 }, /* end address is readonly */
213};
d0e25040
CLG
214static uint32_t aspeed_smc_segment_to_reg(const AspeedSMCState *s,
215 const AspeedSegments *seg);
216static void aspeed_smc_reg_to_segment(const AspeedSMCState *s, uint32_t reg,
217 AspeedSegments *seg);
6dc52326 218
7c1c69bc 219static const AspeedSMCController controllers[] = {
d09dc5b7 220 {
811a5b1d 221 .name = "aspeed.smc-ast2400",
d09dc5b7
CLG
222 .r_conf = R_CONF,
223 .r_ce_ctrl = R_CE_CTRL,
224 .r_ctrl0 = R_CTRL0,
225 .r_timings = R_TIMINGS,
226 .conf_enable_w0 = CONF_ENABLE_W0,
227 .max_slaves = 5,
228 .segments = aspeed_segments_legacy,
229 .flash_window_base = ASPEED_SOC_SMC_FLASH_BASE,
230 .flash_window_size = 0x6000000,
231 .has_dma = false,
087b57c9 232 .nregs = ASPEED_SMC_R_SMC_MAX,
d0e25040
CLG
233 .segment_to_reg = aspeed_smc_segment_to_reg,
234 .reg_to_segment = aspeed_smc_reg_to_segment,
d09dc5b7 235 }, {
811a5b1d 236 .name = "aspeed.fmc-ast2400",
d09dc5b7
CLG
237 .r_conf = R_CONF,
238 .r_ce_ctrl = R_CE_CTRL,
239 .r_ctrl0 = R_CTRL0,
240 .r_timings = R_TIMINGS,
241 .conf_enable_w0 = CONF_ENABLE_W0,
242 .max_slaves = 5,
243 .segments = aspeed_segments_fmc,
244 .flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
245 .flash_window_size = 0x10000000,
246 .has_dma = true,
c4e1f0b4
CLG
247 .dma_flash_mask = 0x0FFFFFFC,
248 .dma_dram_mask = 0x1FFFFFFC,
087b57c9 249 .nregs = ASPEED_SMC_R_MAX,
d0e25040
CLG
250 .segment_to_reg = aspeed_smc_segment_to_reg,
251 .reg_to_segment = aspeed_smc_reg_to_segment,
d09dc5b7 252 }, {
811a5b1d 253 .name = "aspeed.spi1-ast2400",
d09dc5b7
CLG
254 .r_conf = R_SPI_CONF,
255 .r_ce_ctrl = 0xff,
256 .r_ctrl0 = R_SPI_CTRL0,
257 .r_timings = R_SPI_TIMINGS,
258 .conf_enable_w0 = SPI_CONF_ENABLE_W0,
259 .max_slaves = 1,
260 .segments = aspeed_segments_spi,
261 .flash_window_base = ASPEED_SOC_SPI_FLASH_BASE,
262 .flash_window_size = 0x10000000,
263 .has_dma = false,
087b57c9 264 .nregs = ASPEED_SMC_R_SPI_MAX,
d0e25040
CLG
265 .segment_to_reg = aspeed_smc_segment_to_reg,
266 .reg_to_segment = aspeed_smc_reg_to_segment,
d09dc5b7 267 }, {
811a5b1d 268 .name = "aspeed.fmc-ast2500",
d09dc5b7
CLG
269 .r_conf = R_CONF,
270 .r_ce_ctrl = R_CE_CTRL,
271 .r_ctrl0 = R_CTRL0,
272 .r_timings = R_TIMINGS,
273 .conf_enable_w0 = CONF_ENABLE_W0,
274 .max_slaves = 3,
275 .segments = aspeed_segments_ast2500_fmc,
276 .flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
277 .flash_window_size = 0x10000000,
278 .has_dma = true,
c4e1f0b4
CLG
279 .dma_flash_mask = 0x0FFFFFFC,
280 .dma_dram_mask = 0x3FFFFFFC,
087b57c9 281 .nregs = ASPEED_SMC_R_MAX,
d0e25040
CLG
282 .segment_to_reg = aspeed_smc_segment_to_reg,
283 .reg_to_segment = aspeed_smc_reg_to_segment,
d09dc5b7 284 }, {
811a5b1d 285 .name = "aspeed.spi1-ast2500",
d09dc5b7
CLG
286 .r_conf = R_CONF,
287 .r_ce_ctrl = R_CE_CTRL,
288 .r_ctrl0 = R_CTRL0,
289 .r_timings = R_TIMINGS,
290 .conf_enable_w0 = CONF_ENABLE_W0,
291 .max_slaves = 2,
292 .segments = aspeed_segments_ast2500_spi1,
293 .flash_window_base = ASPEED_SOC_SPI_FLASH_BASE,
294 .flash_window_size = 0x8000000,
295 .has_dma = false,
087b57c9 296 .nregs = ASPEED_SMC_R_MAX,
d0e25040
CLG
297 .segment_to_reg = aspeed_smc_segment_to_reg,
298 .reg_to_segment = aspeed_smc_reg_to_segment,
d09dc5b7 299 }, {
811a5b1d 300 .name = "aspeed.spi2-ast2500",
d09dc5b7
CLG
301 .r_conf = R_CONF,
302 .r_ce_ctrl = R_CE_CTRL,
303 .r_ctrl0 = R_CTRL0,
304 .r_timings = R_TIMINGS,
305 .conf_enable_w0 = CONF_ENABLE_W0,
306 .max_slaves = 2,
307 .segments = aspeed_segments_ast2500_spi2,
308 .flash_window_base = ASPEED_SOC_SPI2_FLASH_BASE,
309 .flash_window_size = 0x8000000,
310 .has_dma = false,
087b57c9 311 .nregs = ASPEED_SMC_R_MAX,
d0e25040
CLG
312 .segment_to_reg = aspeed_smc_segment_to_reg,
313 .reg_to_segment = aspeed_smc_reg_to_segment,
d09dc5b7 314 },
924ed163
CLG
315};
316
a03cb1da 317/*
d0e25040
CLG
318 * The Segment Registers of the AST2400 and AST2500 have a 8MB
319 * unit. The address range of a flash SPI slave is encoded with
320 * absolute addresses which should be part of the overall controller
321 * window.
a03cb1da 322 */
d0e25040
CLG
323static uint32_t aspeed_smc_segment_to_reg(const AspeedSMCState *s,
324 const AspeedSegments *seg)
a03cb1da
CLG
325{
326 uint32_t reg = 0;
327 reg |= ((seg->addr >> 23) & SEG_START_MASK) << SEG_START_SHIFT;
328 reg |= (((seg->addr + seg->size) >> 23) & SEG_END_MASK) << SEG_END_SHIFT;
329 return reg;
330}
331
d0e25040
CLG
332static void aspeed_smc_reg_to_segment(const AspeedSMCState *s,
333 uint32_t reg, AspeedSegments *seg)
a03cb1da
CLG
334{
335 seg->addr = ((reg >> SEG_START_SHIFT) & SEG_START_MASK) << 23;
336 seg->size = (((reg >> SEG_END_SHIFT) & SEG_END_MASK) << 23) - seg->addr;
337}
338
339static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
340 const AspeedSegments *new,
341 int cs)
342{
343 AspeedSegments seg;
344 int i;
345
346 for (i = 0; i < s->ctrl->max_slaves; i++) {
347 if (i == cs) {
348 continue;
349 }
350
d0e25040 351 s->ctrl->reg_to_segment(s, s->regs[R_SEG_ADDR0 + i], &seg);
a03cb1da
CLG
352
353 if (new->addr + new->size > seg.addr &&
354 new->addr < seg.addr + seg.size) {
355 qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment CS%d [ 0x%"
356 HWADDR_PRIx" - 0x%"HWADDR_PRIx" ] overlaps with "
357 "CS%d [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
358 s->ctrl->name, cs, new->addr, new->addr + new->size,
359 i, seg.addr, seg.addr + seg.size);
360 return true;
361 }
362 }
363 return false;
364}
365
366static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
367 uint64_t new)
368{
369 AspeedSMCFlash *fl = &s->flashes[cs];
370 AspeedSegments seg;
371
d0e25040 372 s->ctrl->reg_to_segment(s, new, &seg);
a03cb1da
CLG
373
374 /* The start address of CS0 is read-only */
375 if (cs == 0 && seg.addr != s->ctrl->flash_window_base) {
376 qemu_log_mask(LOG_GUEST_ERROR,
377 "%s: Tried to change CS0 start address to 0x%"
378 HWADDR_PRIx "\n", s->ctrl->name, seg.addr);
0584d3c3 379 seg.addr = s->ctrl->flash_window_base;
d0e25040 380 new = s->ctrl->segment_to_reg(s, &seg);
a03cb1da
CLG
381 }
382
383 /*
384 * The end address of the AST2500 spi controllers is also
385 * read-only.
386 */
387 if ((s->ctrl->segments == aspeed_segments_ast2500_spi1 ||
388 s->ctrl->segments == aspeed_segments_ast2500_spi2) &&
389 cs == s->ctrl->max_slaves &&
390 seg.addr + seg.size != s->ctrl->segments[cs].addr +
391 s->ctrl->segments[cs].size) {
392 qemu_log_mask(LOG_GUEST_ERROR,
393 "%s: Tried to change CS%d end address to 0x%"
0584d3c3
CLG
394 HWADDR_PRIx "\n", s->ctrl->name, cs, seg.addr + seg.size);
395 seg.size = s->ctrl->segments[cs].addr + s->ctrl->segments[cs].size -
396 seg.addr;
d0e25040 397 new = s->ctrl->segment_to_reg(s, &seg);
a03cb1da
CLG
398 }
399
400 /* Keep the segment in the overall flash window */
401 if (seg.addr + seg.size <= s->ctrl->flash_window_base ||
402 seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size) {
403 qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is invalid : "
404 "[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
405 s->ctrl->name, cs, seg.addr, seg.addr + seg.size);
406 return;
407 }
408
409 /* Check start address vs. alignment */
0584d3c3 410 if (seg.size && !QEMU_IS_ALIGNED(seg.addr, seg.size)) {
a03cb1da
CLG
411 qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is not "
412 "aligned : [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
413 s->ctrl->name, cs, seg.addr, seg.addr + seg.size);
414 }
415
0584d3c3
CLG
416 /* And segments should not overlap (in the specs) */
417 aspeed_smc_flash_overlap(s, &seg, cs);
a03cb1da
CLG
418
419 /* All should be fine now to move the region */
420 memory_region_transaction_begin();
421 memory_region_set_size(&fl->mmio, seg.size);
422 memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
423 memory_region_set_enabled(&fl->mmio, true);
424 memory_region_transaction_commit();
425
426 s->regs[R_SEG_ADDR0 + cs] = new;
427}
428
924ed163
CLG
429static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
430 unsigned size)
431{
432 qemu_log_mask(LOG_GUEST_ERROR, "%s: To 0x%" HWADDR_PRIx " of size %u"
433 PRIx64 "\n", __func__, addr, size);
434 return 0;
435}
436
437static void aspeed_smc_flash_default_write(void *opaque, hwaddr addr,
438 uint64_t data, unsigned size)
439{
b3d6b8f5
CLG
440 qemu_log_mask(LOG_GUEST_ERROR, "%s: To 0x%" HWADDR_PRIx " of size %u: 0x%"
441 PRIx64 "\n", __func__, addr, size, data);
924ed163
CLG
442}
443
444static const MemoryRegionOps aspeed_smc_flash_default_ops = {
445 .read = aspeed_smc_flash_default_read,
446 .write = aspeed_smc_flash_default_write,
447 .endianness = DEVICE_LITTLE_ENDIAN,
448 .valid = {
449 .min_access_size = 1,
450 .max_access_size = 4,
451 },
452};
453
f248a9db 454static inline int aspeed_smc_flash_mode(const AspeedSMCFlash *fl)
924ed163 455{
f248a9db
CLG
456 const AspeedSMCState *s = fl->controller;
457
458 return s->regs[s->r_ctrl0 + fl->id] & CTRL_CMD_MODE_MASK;
924ed163
CLG
459}
460
fcdf2c59 461static inline bool aspeed_smc_is_writable(const AspeedSMCFlash *fl)
924ed163 462{
fcdf2c59
CLG
463 const AspeedSMCState *s = fl->controller;
464
465 return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + fl->id));
924ed163
CLG
466}
467
fcdf2c59 468static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl)
924ed163 469{
f248a9db 470 const AspeedSMCState *s = fl->controller;
fcdf2c59 471 int cmd = (s->regs[s->r_ctrl0 + fl->id] >> CTRL_CMD_SHIFT) & CTRL_CMD_MASK;
f248a9db 472
fcdf2c59
CLG
473 /* In read mode, the default SPI command is READ (0x3). In other
474 * modes, the command should necessarily be defined */
475 if (aspeed_smc_flash_mode(fl) == CTRL_READMODE) {
476 cmd = SPI_OP_READ;
477 }
478
479 if (!cmd) {
480 qemu_log_mask(LOG_GUEST_ERROR, "%s: no command defined for mode %d\n",
481 __func__, aspeed_smc_flash_mode(fl));
482 }
483
484 return cmd;
485}
486
487static inline int aspeed_smc_flash_is_4byte(const AspeedSMCFlash *fl)
488{
489 const AspeedSMCState *s = fl->controller;
490
491 if (s->ctrl->segments == aspeed_segments_spi) {
492 return s->regs[s->r_ctrl0] & CTRL_AST2400_SPI_4BYTE;
493 } else {
494 return s->regs[s->r_ce_ctrl] & (1 << (CTRL_EXTENDED0 + fl->id));
495 }
496}
497
498static inline bool aspeed_smc_is_ce_stop_active(const AspeedSMCFlash *fl)
499{
500 const AspeedSMCState *s = fl->controller;
501
502 return s->regs[s->r_ctrl0 + fl->id] & CTRL_CE_STOP_ACTIVE;
503}
504
505static void aspeed_smc_flash_select(AspeedSMCFlash *fl)
506{
507 AspeedSMCState *s = fl->controller;
508
509 s->regs[s->r_ctrl0 + fl->id] &= ~CTRL_CE_STOP_ACTIVE;
510 qemu_set_irq(s->cs_lines[fl->id], aspeed_smc_is_ce_stop_active(fl));
511}
512
513static void aspeed_smc_flash_unselect(AspeedSMCFlash *fl)
514{
515 AspeedSMCState *s = fl->controller;
516
517 s->regs[s->r_ctrl0 + fl->id] |= CTRL_CE_STOP_ACTIVE;
518 qemu_set_irq(s->cs_lines[fl->id], aspeed_smc_is_ce_stop_active(fl));
519}
520
521static uint32_t aspeed_smc_check_segment_addr(const AspeedSMCFlash *fl,
522 uint32_t addr)
523{
524 const AspeedSMCState *s = fl->controller;
525 AspeedSegments seg;
526
d0e25040 527 s->ctrl->reg_to_segment(s, s->regs[R_SEG_ADDR0 + fl->id], &seg);
b4cc583f 528 if ((addr % seg.size) != addr) {
fcdf2c59
CLG
529 qemu_log_mask(LOG_GUEST_ERROR,
530 "%s: invalid address 0x%08x for CS%d segment : "
531 "[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
532 s->ctrl->name, addr, fl->id, seg.addr,
533 seg.addr + seg.size);
b4cc583f 534 addr %= seg.size;
fcdf2c59
CLG
535 }
536
fcdf2c59
CLG
537 return addr;
538}
539
ac2810de
CLG
540static int aspeed_smc_flash_dummies(const AspeedSMCFlash *fl)
541{
542 const AspeedSMCState *s = fl->controller;
543 uint32_t r_ctrl0 = s->regs[s->r_ctrl0 + fl->id];
544 uint32_t dummy_high = (r_ctrl0 >> CTRL_DUMMY_HIGH_SHIFT) & 0x1;
545 uint32_t dummy_low = (r_ctrl0 >> CTRL_DUMMY_LOW_SHIFT) & 0x3;
0721309e 546 uint32_t dummies = ((dummy_high << 2) | dummy_low) * 8;
ac2810de 547
0721309e
CLG
548 if (r_ctrl0 & CTRL_IO_DUAL_ADDR_DATA) {
549 dummies /= 2;
550 }
551
552 return dummies;
ac2810de
CLG
553}
554
96c4be95 555static void aspeed_smc_flash_setup(AspeedSMCFlash *fl, uint32_t addr)
fcdf2c59
CLG
556{
557 const AspeedSMCState *s = fl->controller;
558 uint8_t cmd = aspeed_smc_flash_cmd(fl);
96c4be95 559 int i;
fcdf2c59
CLG
560
561 /* Flash access can not exceed CS segment */
562 addr = aspeed_smc_check_segment_addr(fl, addr);
563
564 ssi_transfer(s->spi, cmd);
565
566 if (aspeed_smc_flash_is_4byte(fl)) {
567 ssi_transfer(s->spi, (addr >> 24) & 0xff);
568 }
569 ssi_transfer(s->spi, (addr >> 16) & 0xff);
570 ssi_transfer(s->spi, (addr >> 8) & 0xff);
571 ssi_transfer(s->spi, (addr & 0xff));
96c4be95
CLG
572
573 /*
574 * Use fake transfers to model dummy bytes. The value should
575 * be configured to some non-zero value in fast read mode and
576 * zero in read mode. But, as the HW allows inconsistent
577 * settings, let's check for fast read mode.
578 */
579 if (aspeed_smc_flash_mode(fl) == CTRL_FREADMODE) {
580 for (i = 0; i < aspeed_smc_flash_dummies(fl); i++) {
9149af2a 581 ssi_transfer(fl->controller->spi, s->regs[R_DUMMY_DATA] & 0xff);
96c4be95
CLG
582 }
583 }
924ed163
CLG
584}
585
586static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
587{
588 AspeedSMCFlash *fl = opaque;
fcdf2c59 589 AspeedSMCState *s = fl->controller;
924ed163
CLG
590 uint64_t ret = 0;
591 int i;
592
fcdf2c59
CLG
593 switch (aspeed_smc_flash_mode(fl)) {
594 case CTRL_USERMODE:
924ed163
CLG
595 for (i = 0; i < size; i++) {
596 ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
597 }
fcdf2c59
CLG
598 break;
599 case CTRL_READMODE:
600 case CTRL_FREADMODE:
601 aspeed_smc_flash_select(fl);
96c4be95 602 aspeed_smc_flash_setup(fl, addr);
ac2810de 603
fcdf2c59
CLG
604 for (i = 0; i < size; i++) {
605 ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
606 }
607
608 aspeed_smc_flash_unselect(fl);
609 break;
610 default:
611 qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid flash mode %d\n",
612 __func__, aspeed_smc_flash_mode(fl));
924ed163
CLG
613 }
614
615 return ret;
616}
617
f95c4bff
CLG
618/*
619 * TODO (clg@kaod.org): stolen from xilinx_spips.c. Should move to a
620 * common include header.
621 */
622typedef enum {
623 READ = 0x3, READ_4 = 0x13,
624 FAST_READ = 0xb, FAST_READ_4 = 0x0c,
625 DOR = 0x3b, DOR_4 = 0x3c,
626 QOR = 0x6b, QOR_4 = 0x6c,
627 DIOR = 0xbb, DIOR_4 = 0xbc,
628 QIOR = 0xeb, QIOR_4 = 0xec,
629
630 PP = 0x2, PP_4 = 0x12,
631 DPP = 0xa2,
632 QPP = 0x32, QPP_4 = 0x34,
633} FlashCMD;
634
635static int aspeed_smc_num_dummies(uint8_t command)
636{
637 switch (command) { /* check for dummies */
638 case READ: /* no dummy bytes/cycles */
639 case PP:
640 case DPP:
641 case QPP:
642 case READ_4:
643 case PP_4:
644 case QPP_4:
645 return 0;
646 case FAST_READ:
647 case DOR:
648 case QOR:
649 case DOR_4:
650 case QOR_4:
651 return 1;
652 case DIOR:
653 case FAST_READ_4:
654 case DIOR_4:
655 return 2;
656 case QIOR:
657 case QIOR_4:
658 return 4;
659 default:
660 return -1;
661 }
662}
663
664static bool aspeed_smc_do_snoop(AspeedSMCFlash *fl, uint64_t data,
665 unsigned size)
666{
667 AspeedSMCState *s = fl->controller;
668 uint8_t addr_width = aspeed_smc_flash_is_4byte(fl) ? 4 : 3;
669
670 if (s->snoop_index == SNOOP_OFF) {
671 return false; /* Do nothing */
672
673 } else if (s->snoop_index == SNOOP_START) {
674 uint8_t cmd = data & 0xff;
675 int ndummies = aspeed_smc_num_dummies(cmd);
676
677 /*
678 * No dummy cycles are expected with the current command. Turn
679 * off snooping and let the transfer proceed normally.
680 */
681 if (ndummies <= 0) {
682 s->snoop_index = SNOOP_OFF;
683 return false;
684 }
685
686 s->snoop_dummies = ndummies * 8;
687
688 } else if (s->snoop_index >= addr_width + 1) {
689
690 /* The SPI transfer has reached the dummy cycles sequence */
691 for (; s->snoop_dummies; s->snoop_dummies--) {
692 ssi_transfer(s->spi, s->regs[R_DUMMY_DATA] & 0xff);
693 }
694
695 /* If no more dummy cycles are expected, turn off snooping */
696 if (!s->snoop_dummies) {
697 s->snoop_index = SNOOP_OFF;
698 } else {
699 s->snoop_index += size;
700 }
701
702 /*
703 * Dummy cycles have been faked already. Ignore the current
704 * SPI transfer
705 */
706 return true;
707 }
708
709 s->snoop_index += size;
710 return false;
711}
712
924ed163 713static void aspeed_smc_flash_write(void *opaque, hwaddr addr, uint64_t data,
b3d6b8f5 714 unsigned size)
924ed163
CLG
715{
716 AspeedSMCFlash *fl = opaque;
fcdf2c59 717 AspeedSMCState *s = fl->controller;
924ed163
CLG
718 int i;
719
f248a9db 720 if (!aspeed_smc_is_writable(fl)) {
924ed163
CLG
721 qemu_log_mask(LOG_GUEST_ERROR, "%s: flash is not writable at 0x%"
722 HWADDR_PRIx "\n", __func__, addr);
723 return;
724 }
725
fcdf2c59
CLG
726 switch (aspeed_smc_flash_mode(fl)) {
727 case CTRL_USERMODE:
f95c4bff
CLG
728 if (aspeed_smc_do_snoop(fl, data, size)) {
729 break;
730 }
731
fcdf2c59
CLG
732 for (i = 0; i < size; i++) {
733 ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
734 }
735 break;
736 case CTRL_WRITEMODE:
737 aspeed_smc_flash_select(fl);
96c4be95 738 aspeed_smc_flash_setup(fl, addr);
fcdf2c59
CLG
739
740 for (i = 0; i < size; i++) {
741 ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
742 }
924ed163 743
fcdf2c59
CLG
744 aspeed_smc_flash_unselect(fl);
745 break;
746 default:
747 qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid flash mode %d\n",
748 __func__, aspeed_smc_flash_mode(fl));
924ed163
CLG
749 }
750}
751
752static const MemoryRegionOps aspeed_smc_flash_ops = {
753 .read = aspeed_smc_flash_read,
754 .write = aspeed_smc_flash_write,
755 .endianness = DEVICE_LITTLE_ENDIAN,
756 .valid = {
757 .min_access_size = 1,
758 .max_access_size = 4,
759 },
7c1c69bc
CLG
760};
761
f248a9db 762static void aspeed_smc_flash_update_cs(AspeedSMCFlash *fl)
7c1c69bc 763{
f95c4bff
CLG
764 AspeedSMCState *s = fl->controller;
765
766 s->snoop_index = aspeed_smc_is_ce_stop_active(fl) ? SNOOP_OFF : SNOOP_START;
7c1c69bc 767
f248a9db 768 qemu_set_irq(s->cs_lines[fl->id], aspeed_smc_is_ce_stop_active(fl));
7c1c69bc
CLG
769}
770
771static void aspeed_smc_reset(DeviceState *d)
772{
773 AspeedSMCState *s = ASPEED_SMC(d);
774 int i;
775
776 memset(s->regs, 0, sizeof s->regs);
777
778 /* Unselect all slaves */
779 for (i = 0; i < s->num_cs; ++i) {
780 s->regs[s->r_ctrl0 + i] |= CTRL_CE_STOP_ACTIVE;
1d247bd0 781 qemu_set_irq(s->cs_lines[i], true);
7c1c69bc
CLG
782 }
783
a03cb1da
CLG
784 /* setup default segment register values for all */
785 for (i = 0; i < s->ctrl->max_slaves; ++i) {
786 s->regs[R_SEG_ADDR0 + i] =
d0e25040 787 s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]);
a03cb1da 788 }
0707b34d 789
a57baeb4 790 /* HW strapping flash type for FMC controllers */
0707b34d
CLG
791 if (s->ctrl->segments == aspeed_segments_ast2500_fmc) {
792 /* flash type is fixed to SPI for CE0 and CE1 */
793 s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
794 s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1);
0707b34d
CLG
795 }
796
797 /* HW strapping for AST2400 FMC controllers (SCU70). Let's use the
798 * configuration of the palmetto-bmc machine */
799 if (s->ctrl->segments == aspeed_segments_fmc) {
800 s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
0707b34d 801 }
f95c4bff
CLG
802
803 s->snoop_index = SNOOP_OFF;
804 s->snoop_dummies = 0;
7c1c69bc
CLG
805}
806
7c1c69bc
CLG
807static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
808{
809 AspeedSMCState *s = ASPEED_SMC(opaque);
810
811 addr >>= 2;
812
97c2ed5d
CLG
813 if (addr == s->r_conf ||
814 addr == s->r_timings ||
815 addr == s->r_ce_ctrl ||
2e1f0502 816 addr == R_INTR_CTRL ||
9149af2a 817 addr == R_DUMMY_DATA ||
c4e1f0b4
CLG
818 (s->ctrl->has_dma && addr == R_DMA_CTRL) ||
819 (s->ctrl->has_dma && addr == R_DMA_FLASH_ADDR) ||
820 (s->ctrl->has_dma && addr == R_DMA_DRAM_ADDR) ||
821 (s->ctrl->has_dma && addr == R_DMA_LEN) ||
822 (s->ctrl->has_dma && addr == R_DMA_CHECKSUM) ||
a03cb1da 823 (addr >= R_SEG_ADDR0 && addr < R_SEG_ADDR0 + s->ctrl->max_slaves) ||
597d6bb3 824 (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->ctrl->max_slaves)) {
97c2ed5d
CLG
825 return s->regs[addr];
826 } else {
7c1c69bc 827 qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
97c2ed5d 828 __func__, addr);
b617ca92 829 return -1;
7c1c69bc 830 }
7c1c69bc
CLG
831}
832
0d72c717
CLG
833static uint8_t aspeed_smc_hclk_divisor(uint8_t hclk_mask)
834{
835 /* HCLK/1 .. HCLK/16 */
836 const uint8_t hclk_divisors[] = {
837 15, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 0
838 };
839 int i;
840
841 for (i = 0; i < ARRAY_SIZE(hclk_divisors); i++) {
842 if (hclk_mask == hclk_divisors[i]) {
843 return i + 1;
844 }
845 }
846
847 qemu_log_mask(LOG_GUEST_ERROR, "invalid HCLK mask %x", hclk_mask);
848 return 0;
849}
850
851/*
852 * When doing calibration, the SPI clock rate in the CE0 Control
853 * Register and the read delay cycles in the Read Timing Compensation
854 * Register are set using bit[11:4] of the DMA Control Register.
855 */
856static void aspeed_smc_dma_calibration(AspeedSMCState *s)
857{
858 uint8_t delay =
859 (s->regs[R_DMA_CTRL] >> DMA_CTRL_DELAY_SHIFT) & DMA_CTRL_DELAY_MASK;
860 uint8_t hclk_mask =
861 (s->regs[R_DMA_CTRL] >> DMA_CTRL_FREQ_SHIFT) & DMA_CTRL_FREQ_MASK;
862 uint8_t hclk_div = aspeed_smc_hclk_divisor(hclk_mask);
863 uint32_t hclk_shift = (hclk_div - 1) << 2;
864 uint8_t cs;
865
866 /*
867 * The Read Timing Compensation Register values apply to all CS on
868 * the SPI bus and only HCLK/1 - HCLK/5 can have tunable delays
869 */
870 if (hclk_div && hclk_div < 6) {
871 s->regs[s->r_timings] &= ~(0xf << hclk_shift);
872 s->regs[s->r_timings] |= delay << hclk_shift;
873 }
874
875 /*
876 * TODO: compute the CS from the DMA address and the segment
877 * registers. This is not really a problem for now because the
878 * Timing Register values apply to all CS and software uses CS0 to
879 * do calibration.
880 */
881 cs = 0;
882 s->regs[s->r_ctrl0 + cs] &=
883 ~(CE_CTRL_CLOCK_FREQ_MASK << CE_CTRL_CLOCK_FREQ_SHIFT);
884 s->regs[s->r_ctrl0 + cs] |= CE_CTRL_CLOCK_FREQ(hclk_div);
885}
886
5258c2a6
CLG
887/*
888 * Emulate read errors in the DMA Checksum Register for high
889 * frequencies and optimistic settings of the Read Timing Compensation
890 * Register. This will help in tuning the SPI timing calibration
891 * algorithm.
892 */
893static bool aspeed_smc_inject_read_failure(AspeedSMCState *s)
894{
895 uint8_t delay =
896 (s->regs[R_DMA_CTRL] >> DMA_CTRL_DELAY_SHIFT) & DMA_CTRL_DELAY_MASK;
897 uint8_t hclk_mask =
898 (s->regs[R_DMA_CTRL] >> DMA_CTRL_FREQ_SHIFT) & DMA_CTRL_FREQ_MASK;
899
900 /*
901 * Typical values of a palmetto-bmc machine.
902 */
903 switch (aspeed_smc_hclk_divisor(hclk_mask)) {
904 case 4 ... 16:
905 return false;
906 case 3: /* at least one HCLK cycle delay */
907 return (delay & 0x7) < 1;
908 case 2: /* at least two HCLK cycle delay */
909 return (delay & 0x7) < 2;
910 case 1: /* (> 100MHz) is above the max freq of the controller */
911 return true;
912 default:
913 g_assert_not_reached();
914 }
915}
916
c4e1f0b4
CLG
917/*
918 * Accumulate the result of the reads to provide a checksum that will
919 * be used to validate the read timing settings.
920 */
921static void aspeed_smc_dma_checksum(AspeedSMCState *s)
922{
923 MemTxResult result;
924 uint32_t data;
925
926 if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
927 qemu_log_mask(LOG_GUEST_ERROR,
928 "%s: invalid direction for DMA checksum\n", __func__);
929 return;
930 }
931
0d72c717
CLG
932 if (s->regs[R_DMA_CTRL] & DMA_CTRL_CALIB) {
933 aspeed_smc_dma_calibration(s);
934 }
935
c4e1f0b4
CLG
936 while (s->regs[R_DMA_LEN]) {
937 data = address_space_ldl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
938 MEMTXATTRS_UNSPECIFIED, &result);
939 if (result != MEMTX_OK) {
940 qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash read failed @%08x\n",
941 __func__, s->regs[R_DMA_FLASH_ADDR]);
942 return;
943 }
944
945 /*
946 * When the DMA is on-going, the DMA registers are updated
947 * with the current working addresses and length.
948 */
949 s->regs[R_DMA_CHECKSUM] += data;
950 s->regs[R_DMA_FLASH_ADDR] += 4;
951 s->regs[R_DMA_LEN] -= 4;
952 }
5258c2a6
CLG
953
954 if (s->inject_failure && aspeed_smc_inject_read_failure(s)) {
955 s->regs[R_DMA_CHECKSUM] = 0xbadc0de;
956 }
957
c4e1f0b4
CLG
958}
959
960static void aspeed_smc_dma_rw(AspeedSMCState *s)
961{
962 MemTxResult result;
963 uint32_t data;
964
965 while (s->regs[R_DMA_LEN]) {
966 if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
967 data = address_space_ldl_le(&s->dram_as, s->regs[R_DMA_DRAM_ADDR],
968 MEMTXATTRS_UNSPECIFIED, &result);
969 if (result != MEMTX_OK) {
970 qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM read failed @%08x\n",
971 __func__, s->regs[R_DMA_DRAM_ADDR]);
972 return;
973 }
974
975 address_space_stl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
976 data, MEMTXATTRS_UNSPECIFIED, &result);
977 if (result != MEMTX_OK) {
978 qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash write failed @%08x\n",
979 __func__, s->regs[R_DMA_FLASH_ADDR]);
980 return;
981 }
982 } else {
983 data = address_space_ldl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
984 MEMTXATTRS_UNSPECIFIED, &result);
985 if (result != MEMTX_OK) {
986 qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash read failed @%08x\n",
987 __func__, s->regs[R_DMA_FLASH_ADDR]);
988 return;
989 }
990
991 address_space_stl_le(&s->dram_as, s->regs[R_DMA_DRAM_ADDR],
992 data, MEMTXATTRS_UNSPECIFIED, &result);
993 if (result != MEMTX_OK) {
994 qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM write failed @%08x\n",
995 __func__, s->regs[R_DMA_DRAM_ADDR]);
996 return;
997 }
998 }
999
1000 /*
1001 * When the DMA is on-going, the DMA registers are updated
1002 * with the current working addresses and length.
1003 */
1004 s->regs[R_DMA_FLASH_ADDR] += 4;
1005 s->regs[R_DMA_DRAM_ADDR] += 4;
1006 s->regs[R_DMA_LEN] -= 4;
ae275f71 1007 s->regs[R_DMA_CHECKSUM] += data;
c4e1f0b4
CLG
1008 }
1009}
1010
1011static void aspeed_smc_dma_stop(AspeedSMCState *s)
1012{
1013 /*
1014 * When the DMA is disabled, INTR_CTRL_DMA_STATUS=0 means the
1015 * engine is idle
1016 */
1017 s->regs[R_INTR_CTRL] &= ~INTR_CTRL_DMA_STATUS;
1018 s->regs[R_DMA_CHECKSUM] = 0;
1019
1020 /*
1021 * Lower the DMA irq in any case. The IRQ control register could
1022 * have been cleared before disabling the DMA.
1023 */
1024 qemu_irq_lower(s->irq);
1025}
1026
1027/*
1028 * When INTR_CTRL_DMA_STATUS=1, the DMA has completed and a new DMA
1029 * can start even if the result of the previous was not collected.
1030 */
1031static bool aspeed_smc_dma_in_progress(AspeedSMCState *s)
1032{
1033 return s->regs[R_DMA_CTRL] & DMA_CTRL_ENABLE &&
1034 !(s->regs[R_INTR_CTRL] & INTR_CTRL_DMA_STATUS);
1035}
1036
1037static void aspeed_smc_dma_done(AspeedSMCState *s)
1038{
1039 s->regs[R_INTR_CTRL] |= INTR_CTRL_DMA_STATUS;
1040 if (s->regs[R_INTR_CTRL] & INTR_CTRL_DMA_EN) {
1041 qemu_irq_raise(s->irq);
1042 }
1043}
1044
1045static void aspeed_smc_dma_ctrl(AspeedSMCState *s, uint64_t dma_ctrl)
1046{
1047 if (!(dma_ctrl & DMA_CTRL_ENABLE)) {
1048 s->regs[R_DMA_CTRL] = dma_ctrl;
1049
1050 aspeed_smc_dma_stop(s);
1051 return;
1052 }
1053
1054 if (aspeed_smc_dma_in_progress(s)) {
1055 qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA in progress\n", __func__);
1056 return;
1057 }
1058
1059 s->regs[R_DMA_CTRL] = dma_ctrl;
1060
1061 if (s->regs[R_DMA_CTRL] & DMA_CTRL_CKSUM) {
1062 aspeed_smc_dma_checksum(s);
1063 } else {
1064 aspeed_smc_dma_rw(s);
1065 }
1066
1067 aspeed_smc_dma_done(s);
1068}
1069
7c1c69bc
CLG
1070static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
1071 unsigned int size)
1072{
1073 AspeedSMCState *s = ASPEED_SMC(opaque);
1074 uint32_t value = data;
1075
1076 addr >>= 2;
1077
97c2ed5d
CLG
1078 if (addr == s->r_conf ||
1079 addr == s->r_timings ||
1080 addr == s->r_ce_ctrl) {
1081 s->regs[addr] = value;
1082 } else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
f248a9db 1083 int cs = addr - s->r_ctrl0;
97c2ed5d 1084 s->regs[addr] = value;
f248a9db 1085 aspeed_smc_flash_update_cs(&s->flashes[cs]);
a03cb1da
CLG
1086 } else if (addr >= R_SEG_ADDR0 &&
1087 addr < R_SEG_ADDR0 + s->ctrl->max_slaves) {
1088 int cs = addr - R_SEG_ADDR0;
1089
1090 if (value != s->regs[R_SEG_ADDR0 + cs]) {
1091 aspeed_smc_flash_set_segment(s, cs, value);
1092 }
9149af2a
CLG
1093 } else if (addr == R_DUMMY_DATA) {
1094 s->regs[addr] = value & 0xff;
c4e1f0b4
CLG
1095 } else if (addr == R_INTR_CTRL) {
1096 s->regs[addr] = value;
1097 } else if (s->ctrl->has_dma && addr == R_DMA_CTRL) {
1098 aspeed_smc_dma_ctrl(s, value);
1099 } else if (s->ctrl->has_dma && addr == R_DMA_DRAM_ADDR) {
1100 s->regs[addr] = DMA_DRAM_ADDR(s, value);
1101 } else if (s->ctrl->has_dma && addr == R_DMA_FLASH_ADDR) {
1102 s->regs[addr] = DMA_FLASH_ADDR(s, value);
1103 } else if (s->ctrl->has_dma && addr == R_DMA_LEN) {
1104 s->regs[addr] = DMA_LENGTH(value);
97c2ed5d 1105 } else {
7c1c69bc
CLG
1106 qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
1107 __func__, addr);
1108 return;
1109 }
7c1c69bc
CLG
1110}
1111
1112static const MemoryRegionOps aspeed_smc_ops = {
1113 .read = aspeed_smc_read,
1114 .write = aspeed_smc_write,
1115 .endianness = DEVICE_LITTLE_ENDIAN,
1116 .valid.unaligned = true,
1117};
1118
c4e1f0b4
CLG
1119
1120/*
1121 * Initialize the custom address spaces for DMAs
1122 */
1123static void aspeed_smc_dma_setup(AspeedSMCState *s, Error **errp)
1124{
1125 char *name;
1126
1127 if (!s->dram_mr) {
1128 error_setg(errp, TYPE_ASPEED_SMC ": 'dram' link not set");
1129 return;
1130 }
1131
1132 name = g_strdup_printf("%s-dma-flash", s->ctrl->name);
1133 address_space_init(&s->flash_as, &s->mmio_flash, name);
1134 g_free(name);
1135
1136 name = g_strdup_printf("%s-dma-dram", s->ctrl->name);
1137 address_space_init(&s->dram_as, s->dram_mr, name);
1138 g_free(name);
1139}
1140
7c1c69bc
CLG
1141static void aspeed_smc_realize(DeviceState *dev, Error **errp)
1142{
1143 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
1144 AspeedSMCState *s = ASPEED_SMC(dev);
1145 AspeedSMCClass *mc = ASPEED_SMC_GET_CLASS(s);
1146 int i;
924ed163
CLG
1147 char name[32];
1148 hwaddr offset = 0;
7c1c69bc
CLG
1149
1150 s->ctrl = mc->ctrl;
1151
1152 /* keep a copy under AspeedSMCState to speed up accesses */
1153 s->r_conf = s->ctrl->r_conf;
1154 s->r_ce_ctrl = s->ctrl->r_ce_ctrl;
1155 s->r_ctrl0 = s->ctrl->r_ctrl0;
1156 s->r_timings = s->ctrl->r_timings;
1157 s->conf_enable_w0 = s->ctrl->conf_enable_w0;
1158
1159 /* Enforce some real HW limits */
1160 if (s->num_cs > s->ctrl->max_slaves) {
1161 qemu_log_mask(LOG_GUEST_ERROR, "%s: num_cs cannot exceed: %d\n",
1162 __func__, s->ctrl->max_slaves);
1163 s->num_cs = s->ctrl->max_slaves;
1164 }
1165
c4e1f0b4
CLG
1166 /* DMA irq. Keep it first for the initialization in the SoC */
1167 sysbus_init_irq(sbd, &s->irq);
1168
7c1c69bc
CLG
1169 s->spi = ssi_create_bus(dev, "spi");
1170
1171 /* Setup cs_lines for slaves */
7c1c69bc
CLG
1172 s->cs_lines = g_new0(qemu_irq, s->num_cs);
1173 ssi_auto_connect_slaves(dev, s->cs_lines, s->spi);
1174
1175 for (i = 0; i < s->num_cs; ++i) {
1176 sysbus_init_irq(sbd, &s->cs_lines[i]);
1177 }
1178
2da95fd8 1179 /* The memory region for the controller registers */
7c1c69bc 1180 memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_smc_ops, s,
087b57c9 1181 s->ctrl->name, s->ctrl->nregs * 4);
7c1c69bc 1182 sysbus_init_mmio(sbd, &s->mmio);
924ed163
CLG
1183
1184 /*
2da95fd8
CLG
1185 * The container memory region representing the address space
1186 * window in which the flash modules are mapped. The size and
1187 * address depends on the SoC model and controller type.
924ed163
CLG
1188 */
1189 snprintf(name, sizeof(name), "%s.flash", s->ctrl->name);
1190
1191 memory_region_init_io(&s->mmio_flash, OBJECT(s),
1192 &aspeed_smc_flash_default_ops, s, name,
dcb83444 1193 s->ctrl->flash_window_size);
924ed163
CLG
1194 sysbus_init_mmio(sbd, &s->mmio_flash);
1195
2da95fd8 1196 s->flashes = g_new0(AspeedSMCFlash, s->ctrl->max_slaves);
924ed163 1197
2da95fd8
CLG
1198 /*
1199 * Let's create a sub memory region for each possible slave. All
1200 * have a configurable memory segment in the overall flash mapping
1201 * window of the controller but, there is not necessarily a flash
1202 * module behind to handle the memory accesses. This depends on
1203 * the board configuration.
1204 */
1205 for (i = 0; i < s->ctrl->max_slaves; ++i) {
924ed163
CLG
1206 AspeedSMCFlash *fl = &s->flashes[i];
1207
1208 snprintf(name, sizeof(name), "%s.%d", s->ctrl->name, i);
1209
1210 fl->id = i;
1211 fl->controller = s;
1212 fl->size = s->ctrl->segments[i].size;
1213 memory_region_init_io(&fl->mmio, OBJECT(s), &aspeed_smc_flash_ops,
1214 fl, name, fl->size);
1215 memory_region_add_subregion(&s->mmio_flash, offset, &fl->mmio);
1216 offset += fl->size;
1217 }
c4e1f0b4
CLG
1218
1219 /* DMA support */
1220 if (s->ctrl->has_dma) {
1221 aspeed_smc_dma_setup(s, errp);
1222 }
7c1c69bc
CLG
1223}
1224
1225static const VMStateDescription vmstate_aspeed_smc = {
1226 .name = "aspeed.smc",
f95c4bff
CLG
1227 .version_id = 2,
1228 .minimum_version_id = 2,
7c1c69bc
CLG
1229 .fields = (VMStateField[]) {
1230 VMSTATE_UINT32_ARRAY(regs, AspeedSMCState, ASPEED_SMC_R_MAX),
f95c4bff
CLG
1231 VMSTATE_UINT8(snoop_index, AspeedSMCState),
1232 VMSTATE_UINT8(snoop_dummies, AspeedSMCState),
7c1c69bc
CLG
1233 VMSTATE_END_OF_LIST()
1234 }
1235};
1236
1237static Property aspeed_smc_properties[] = {
1238 DEFINE_PROP_UINT32("num-cs", AspeedSMCState, num_cs, 1),
5258c2a6 1239 DEFINE_PROP_BOOL("inject-failure", AspeedSMCState, inject_failure, false),
6da4433f 1240 DEFINE_PROP_UINT64("sdram-base", AspeedSMCState, sdram_base, 0),
c4e1f0b4
CLG
1241 DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr,
1242 TYPE_MEMORY_REGION, MemoryRegion *),
7c1c69bc
CLG
1243 DEFINE_PROP_END_OF_LIST(),
1244};
1245
1246static void aspeed_smc_class_init(ObjectClass *klass, void *data)
1247{
1248 DeviceClass *dc = DEVICE_CLASS(klass);
1249 AspeedSMCClass *mc = ASPEED_SMC_CLASS(klass);
1250
1251 dc->realize = aspeed_smc_realize;
1252 dc->reset = aspeed_smc_reset;
1253 dc->props = aspeed_smc_properties;
1254 dc->vmsd = &vmstate_aspeed_smc;
1255 mc->ctrl = data;
1256}
1257
1258static const TypeInfo aspeed_smc_info = {
1259 .name = TYPE_ASPEED_SMC,
1260 .parent = TYPE_SYS_BUS_DEVICE,
1261 .instance_size = sizeof(AspeedSMCState),
1262 .class_size = sizeof(AspeedSMCClass),
1263 .abstract = true,
1264};
1265
1266static void aspeed_smc_register_types(void)
1267{
1268 int i;
1269
1270 type_register_static(&aspeed_smc_info);
1271 for (i = 0; i < ARRAY_SIZE(controllers); ++i) {
1272 TypeInfo ti = {
1273 .name = controllers[i].name,
1274 .parent = TYPE_ASPEED_SMC,
1275 .class_init = aspeed_smc_class_init,
1276 .class_data = (void *)&controllers[i],
1277 };
1278 type_register(&ti);
1279 }
1280}
1281
1282type_init(aspeed_smc_register_types)