1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "qemu/osdep.h"
26#include "hw/sysbus.h"
27#include "migration/vmstate.h"
28#include "qemu/log.h"
29#include "qemu/module.h"
30#include "qemu/error-report.h"
31#include "qapi/error.h"
32#include "qemu/units.h"
33#include "trace.h"
34
35#include "hw/irq.h"
36#include "hw/qdev-properties.h"
37#include "hw/ssi/aspeed_smc.h"
38
39
40#define R_CONF (0x00 / 4)
41#define CONF_LEGACY_DISABLE (1 << 31)
42#define CONF_ENABLE_W4 20
43#define CONF_ENABLE_W3 19
44#define CONF_ENABLE_W2 18
45#define CONF_ENABLE_W1 17
46#define CONF_ENABLE_W0 16
47#define CONF_FLASH_TYPE4 8
48#define CONF_FLASH_TYPE3 6
49#define CONF_FLASH_TYPE2 4
50#define CONF_FLASH_TYPE1 2
51#define CONF_FLASH_TYPE0 0
52#define CONF_FLASH_TYPE_NOR 0x0
53#define CONF_FLASH_TYPE_NAND 0x1
54#define CONF_FLASH_TYPE_SPI 0x2
55
56
57#define R_CE_CTRL (0x04 / 4)
58#define CTRL_EXTENDED4 4
59#define CTRL_EXTENDED3 3
60#define CTRL_EXTENDED2 2
61#define CTRL_EXTENDED1 1
62#define CTRL_EXTENDED0 0
63
64
65#define R_INTR_CTRL (0x08 / 4)
66#define INTR_CTRL_DMA_STATUS (1 << 11)
67#define INTR_CTRL_CMD_ABORT_STATUS (1 << 10)
68#define INTR_CTRL_WRITE_PROTECT_STATUS (1 << 9)
69#define INTR_CTRL_DMA_EN (1 << 3)
70#define INTR_CTRL_CMD_ABORT_EN (1 << 2)
71#define INTR_CTRL_WRITE_PROTECT_EN (1 << 1)
72
73
74#define R_CE_CMD_CTRL (0x0C / 4)
75#define CTRL_ADDR_BYTE0_DISABLE_SHIFT 4
76#define CTRL_DATA_BYTE0_DISABLE_SHIFT 0
77
78#define aspeed_smc_addr_byte_enabled(s, i) \
79 (!((s)->regs[R_CE_CMD_CTRL] & (1 << (CTRL_ADDR_BYTE0_DISABLE_SHIFT + (i)))))
80#define aspeed_smc_data_byte_enabled(s, i) \
81 (!((s)->regs[R_CE_CMD_CTRL] & (1 << (CTRL_DATA_BYTE0_DISABLE_SHIFT + (i)))))
82
83
84#define R_CTRL0 (0x10 / 4)
85#define CTRL_IO_QPI (1 << 31)
86#define CTRL_IO_QUAD_DATA (1 << 30)
87#define CTRL_IO_DUAL_DATA (1 << 29)
88#define CTRL_IO_DUAL_ADDR_DATA (1 << 28)
89#define CTRL_IO_QUAD_ADDR_DATA (1 << 28)
90#define CTRL_CMD_SHIFT 16
91#define CTRL_CMD_MASK 0xff
92#define CTRL_DUMMY_HIGH_SHIFT 14
93#define CTRL_AST2400_SPI_4BYTE (1 << 13)
94#define CE_CTRL_CLOCK_FREQ_SHIFT 8
95#define CE_CTRL_CLOCK_FREQ_MASK 0xf
96#define CE_CTRL_CLOCK_FREQ(div) \
97 (((div) & CE_CTRL_CLOCK_FREQ_MASK) << CE_CTRL_CLOCK_FREQ_SHIFT)
98#define CTRL_DUMMY_LOW_SHIFT 6
99#define CTRL_CE_STOP_ACTIVE (1 << 2)
100#define CTRL_CMD_MODE_MASK 0x3
101#define CTRL_READMODE 0x0
102#define CTRL_FREADMODE 0x1
103#define CTRL_WRITEMODE 0x2
104#define CTRL_USERMODE 0x3
105#define R_CTRL1 (0x14 / 4)
106#define R_CTRL2 (0x18 / 4)
107#define R_CTRL3 (0x1C / 4)
108#define R_CTRL4 (0x20 / 4)
109
110
111#define R_SEG_ADDR0 (0x30 / 4)
112#define SEG_END_SHIFT 24
113#define SEG_END_MASK 0xff
114#define SEG_START_SHIFT 16
115#define SEG_START_MASK 0xff
116#define R_SEG_ADDR1 (0x34 / 4)
117#define R_SEG_ADDR2 (0x38 / 4)
118#define R_SEG_ADDR3 (0x3C / 4)
119#define R_SEG_ADDR4 (0x40 / 4)
120
121
122#define R_MISC_CTRL1 (0x50 / 4)
123
124
125#define R_DUMMY_DATA (0x54 / 4)
126
127
128#define R_FMC_WDT2_CTRL (0x64 / 4)
129#define FMC_WDT2_CTRL_ALT_BOOT_MODE BIT(6)
130#define FMC_WDT2_CTRL_SINGLE_BOOT_MODE BIT(5)
131#define FMC_WDT2_CTRL_BOOT_SOURCE BIT(4)
132#define FMC_WDT2_CTRL_EN BIT(0)
133
134
135#define R_DMA_CTRL (0x80 / 4)
136#define DMA_CTRL_REQUEST (1 << 31)
137#define DMA_CTRL_GRANT (1 << 30)
138#define DMA_CTRL_DELAY_MASK 0xf
139#define DMA_CTRL_DELAY_SHIFT 8
140#define DMA_CTRL_FREQ_MASK 0xf
141#define DMA_CTRL_FREQ_SHIFT 4
142#define DMA_CTRL_CALIB (1 << 3)
143#define DMA_CTRL_CKSUM (1 << 2)
144#define DMA_CTRL_WRITE (1 << 1)
145#define DMA_CTRL_ENABLE (1 << 0)
146
147
148#define R_DMA_FLASH_ADDR (0x84 / 4)
149
150
151#define R_DMA_DRAM_ADDR (0x88 / 4)
152
153
154#define R_DMA_LEN (0x8C / 4)
155
156
157#define R_DMA_CHECKSUM (0x90 / 4)
158
159
160#define R_TIMINGS (0x94 / 4)
161
162
163#define R_SPI_CONF (0x00 / 4)
164#define SPI_CONF_ENABLE_W0 0
165#define R_SPI_CTRL0 (0x4 / 4)
166#define R_SPI_MISC_CTRL (0x10 / 4)
167#define R_SPI_TIMINGS (0x14 / 4)
168
169#define ASPEED_SMC_R_SPI_MAX (0x20 / 4)
170#define ASPEED_SMC_R_SMC_MAX (0x20 / 4)
171
172
173
174
175
176
177
178
179
180
181
182
183
184#define DMA_DRAM_ADDR(asc, val) ((val) & (asc)->dma_dram_mask)
185#define DMA_FLASH_ADDR(asc, val) ((val) & (asc)->dma_flash_mask)
186#define DMA_LENGTH(val) ((val) & 0x01FFFFFC)
187
188
189#define SPI_OP_READ 0x03
190
191#define SNOOP_OFF 0xFF
192#define SNOOP_START 0x0
193
194
195
196
197
198
199static const AspeedSegments aspeed_2500_spi1_segments[];
200static const AspeedSegments aspeed_2500_spi2_segments[];
201
202#define ASPEED_SMC_FEATURE_DMA 0x1
203#define ASPEED_SMC_FEATURE_DMA_GRANT 0x2
204#define ASPEED_SMC_FEATURE_WDT_CONTROL 0x4
205
206static inline bool aspeed_smc_has_dma(const AspeedSMCClass *asc)
207{
208 return !!(asc->features & ASPEED_SMC_FEATURE_DMA);
209}
210
211static inline bool aspeed_smc_has_wdt_control(const AspeedSMCClass *asc)
212{
213 return !!(asc->features & ASPEED_SMC_FEATURE_WDT_CONTROL);
214}
215
216#define aspeed_smc_error(fmt, ...) \
217 qemu_log_mask(LOG_GUEST_ERROR, "%s: " fmt "\n", __func__, ## __VA_ARGS__)
218
219static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
220 const AspeedSegments *new,
221 int cs)
222{
223 AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
224 AspeedSegments seg;
225 int i;
226
227 for (i = 0; i < asc->cs_num_max; i++) {
228 if (i == cs) {
229 continue;
230 }
231
232 asc->reg_to_segment(s, s->regs[R_SEG_ADDR0 + i], &seg);
233
234 if (new->addr + new->size > seg.addr &&
235 new->addr < seg.addr + seg.size) {
236 aspeed_smc_error("new segment CS%d [ 0x%"
237 HWADDR_PRIx" - 0x%"HWADDR_PRIx" ] overlaps with "
238 "CS%d [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]",
239 cs, new->addr, new->addr + new->size,
240 i, seg.addr, seg.addr + seg.size);
241 return true;
242 }
243 }
244 return false;
245}
246
247static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
248 uint64_t regval)
249{
250 AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
251 AspeedSMCFlash *fl = &s->flashes[cs];
252 AspeedSegments seg;
253
254 asc->reg_to_segment(s, regval, &seg);
255
256 memory_region_transaction_begin();
257 memory_region_set_size(&fl->mmio, seg.size);
258 memory_region_set_address(&fl->mmio, seg.addr - asc->flash_window_base);
259 memory_region_set_enabled(&fl->mmio, !!seg.size);
260 memory_region_transaction_commit();
261
262 if (asc->segment_addr_mask) {
263 regval &= asc->segment_addr_mask;
264 }
265
266 s->regs[R_SEG_ADDR0 + cs] = regval;
267}
268
269static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
270 uint64_t new)
271{
272 AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
273 AspeedSegments seg;
274
275 asc->reg_to_segment(s, new, &seg);
276
277 trace_aspeed_smc_flash_set_segment(cs, new, seg.addr, seg.addr + seg.size);
278
279
280 if (cs == 0 && seg.addr != asc->flash_window_base) {
281 aspeed_smc_error("Tried to change CS0 start address to 0x%"
282 HWADDR_PRIx, seg.addr);
283 seg.addr = asc->flash_window_base;
284 new = asc->segment_to_reg(s, &seg);
285 }
286
287
288
289
290
291 if ((asc->segments == aspeed_2500_spi1_segments ||
292 asc->segments == aspeed_2500_spi2_segments) &&
293 cs == asc->cs_num_max &&
294 seg.addr + seg.size != asc->segments[cs].addr +
295 asc->segments[cs].size) {
296 aspeed_smc_error("Tried to change CS%d end address to 0x%"
297 HWADDR_PRIx, cs, seg.addr + seg.size);
298 seg.size = asc->segments[cs].addr + asc->segments[cs].size -
299 seg.addr;
300 new = asc->segment_to_reg(s, &seg);
301 }
302
303
304 if (seg.size &&
305 (seg.addr + seg.size <= asc->flash_window_base ||
306 seg.addr > asc->flash_window_base + asc->flash_window_size)) {
307 aspeed_smc_error("new segment for CS%d is invalid : "
308 "[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]",
309 cs, seg.addr, seg.addr + seg.size);
310 return;
311 }
312
313
314 if (seg.size && !QEMU_IS_ALIGNED(seg.addr, seg.size)) {
315 aspeed_smc_error("new segment for CS%d is not "
316 "aligned : [ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]",
317 cs, seg.addr, seg.addr + seg.size);
318 }
319
320
321 aspeed_smc_flash_overlap(s, &seg, cs);
322
323
324 aspeed_smc_flash_set_segment_region(s, cs, new);
325}
326
327static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
328 unsigned size)
329{
330 aspeed_smc_error("To 0x%" HWADDR_PRIx " of size %u", addr, size);
331 return 0;
332}
333
334static void aspeed_smc_flash_default_write(void *opaque, hwaddr addr,
335 uint64_t data, unsigned size)
336{
337 aspeed_smc_error("To 0x%" HWADDR_PRIx " of size %u: 0x%" PRIx64,
338 addr, size, data);
339}
340
341static const MemoryRegionOps aspeed_smc_flash_default_ops = {
342 .read = aspeed_smc_flash_default_read,
343 .write = aspeed_smc_flash_default_write,
344 .endianness = DEVICE_LITTLE_ENDIAN,
345 .valid = {
346 .min_access_size = 1,
347 .max_access_size = 4,
348 },
349};
350
351static inline int aspeed_smc_flash_mode(const AspeedSMCFlash *fl)
352{
353 const AspeedSMCState *s = fl->controller;
354
355 return s->regs[s->r_ctrl0 + fl->cs] & CTRL_CMD_MODE_MASK;
356}
357
358static inline bool aspeed_smc_is_writable(const AspeedSMCFlash *fl)
359{
360 const AspeedSMCState *s = fl->controller;
361
362 return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + fl->cs));
363}
364
365static inline int aspeed_smc_flash_cmd(const AspeedSMCFlash *fl)
366{
367 const AspeedSMCState *s = fl->controller;
368 int cmd = (s->regs[s->r_ctrl0 + fl->cs] >> CTRL_CMD_SHIFT) & CTRL_CMD_MASK;
369
370
371
372
373
374
375
376 if (aspeed_smc_flash_mode(fl) == CTRL_READMODE) {
377 cmd = SPI_OP_READ;
378 }
379
380 if (!cmd) {
381 aspeed_smc_error("no command defined for mode %d",
382 aspeed_smc_flash_mode(fl));
383 }
384
385 return cmd;
386}
387
388static inline int aspeed_smc_flash_addr_width(const AspeedSMCFlash *fl)
389{
390 const AspeedSMCState *s = fl->controller;
391 AspeedSMCClass *asc = fl->asc;
392
393 if (asc->addr_width) {
394 return asc->addr_width(s);
395 } else {
396 return s->regs[s->r_ce_ctrl] & (1 << (CTRL_EXTENDED0 + fl->cs)) ? 4 : 3;
397 }
398}
399
400static void aspeed_smc_flash_do_select(AspeedSMCFlash *fl, bool unselect)
401{
402 AspeedSMCState *s = fl->controller;
403
404 trace_aspeed_smc_flash_select(fl->cs, unselect ? "un" : "");
405
406 qemu_set_irq(s->cs_lines[fl->cs], unselect);
407}
408
409static void aspeed_smc_flash_select(AspeedSMCFlash *fl)
410{
411 aspeed_smc_flash_do_select(fl, false);
412}
413
414static void aspeed_smc_flash_unselect(AspeedSMCFlash *fl)
415{
416 aspeed_smc_flash_do_select(fl, true);
417}
418
419static uint32_t aspeed_smc_check_segment_addr(const AspeedSMCFlash *fl,
420 uint32_t addr)
421{
422 const AspeedSMCState *s = fl->controller;
423 AspeedSMCClass *asc = fl->asc;
424 AspeedSegments seg;
425
426 asc->reg_to_segment(s, s->regs[R_SEG_ADDR0 + fl->cs], &seg);
427 if ((addr % seg.size) != addr) {
428 aspeed_smc_error("invalid address 0x%08x for CS%d segment : "
429 "[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]",
430 addr, fl->cs, seg.addr, seg.addr + seg.size);
431 addr %= seg.size;
432 }
433
434 return addr;
435}
436
437static int aspeed_smc_flash_dummies(const AspeedSMCFlash *fl)
438{
439 const AspeedSMCState *s = fl->controller;
440 uint32_t r_ctrl0 = s->regs[s->r_ctrl0 + fl->cs];
441 uint32_t dummy_high = (r_ctrl0 >> CTRL_DUMMY_HIGH_SHIFT) & 0x1;
442 uint32_t dummy_low = (r_ctrl0 >> CTRL_DUMMY_LOW_SHIFT) & 0x3;
443 uint32_t dummies = ((dummy_high << 2) | dummy_low) * 8;
444
445 if (r_ctrl0 & CTRL_IO_DUAL_ADDR_DATA) {
446 dummies /= 2;
447 }
448
449 return dummies;
450}
451
452static void aspeed_smc_flash_setup(AspeedSMCFlash *fl, uint32_t addr)
453{
454 const AspeedSMCState *s = fl->controller;
455 uint8_t cmd = aspeed_smc_flash_cmd(fl);
456 int i = aspeed_smc_flash_addr_width(fl);
457
458
459 addr = aspeed_smc_check_segment_addr(fl, addr);
460
461 ssi_transfer(s->spi, cmd);
462 while (i--) {
463 if (aspeed_smc_addr_byte_enabled(s, i)) {
464 ssi_transfer(s->spi, (addr >> (i * 8)) & 0xff);
465 }
466 }
467
468
469
470
471
472
473
474 if (aspeed_smc_flash_mode(fl) == CTRL_FREADMODE) {
475 for (i = 0; i < aspeed_smc_flash_dummies(fl); i++) {
476 ssi_transfer(fl->controller->spi, s->regs[R_DUMMY_DATA] & 0xff);
477 }
478 }
479}
480
481static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
482{
483 AspeedSMCFlash *fl = opaque;
484 AspeedSMCState *s = fl->controller;
485 uint64_t ret = 0;
486 int i;
487
488 switch (aspeed_smc_flash_mode(fl)) {
489 case CTRL_USERMODE:
490 for (i = 0; i < size; i++) {
491 ret |= (uint64_t) ssi_transfer(s->spi, 0x0) << (8 * i);
492 }
493 break;
494 case CTRL_READMODE:
495 case CTRL_FREADMODE:
496 aspeed_smc_flash_select(fl);
497 aspeed_smc_flash_setup(fl, addr);
498
499 for (i = 0; i < size; i++) {
500 ret |= (uint64_t) ssi_transfer(s->spi, 0x0) << (8 * i);
501 }
502
503 aspeed_smc_flash_unselect(fl);
504 break;
505 default:
506 aspeed_smc_error("invalid flash mode %d", aspeed_smc_flash_mode(fl));
507 }
508
509 trace_aspeed_smc_flash_read(fl->cs, addr, size, ret,
510 aspeed_smc_flash_mode(fl));
511 return ret;
512}
513
514
515
516
517
518typedef enum {
519 READ = 0x3, READ_4 = 0x13,
520 FAST_READ = 0xb, FAST_READ_4 = 0x0c,
521 DOR = 0x3b, DOR_4 = 0x3c,
522 QOR = 0x6b, QOR_4 = 0x6c,
523 DIOR = 0xbb, DIOR_4 = 0xbc,
524 QIOR = 0xeb, QIOR_4 = 0xec,
525
526 PP = 0x2, PP_4 = 0x12,
527 DPP = 0xa2,
528 QPP = 0x32, QPP_4 = 0x34,
529} FlashCMD;
530
531static int aspeed_smc_num_dummies(uint8_t command)
532{
533 switch (command) {
534 case READ:
535 case PP:
536 case DPP:
537 case QPP:
538 case READ_4:
539 case PP_4:
540 case QPP_4:
541 return 0;
542 case FAST_READ:
543 case DOR:
544 case QOR:
545 case FAST_READ_4:
546 case DOR_4:
547 case QOR_4:
548 return 1;
549 case DIOR:
550 case DIOR_4:
551 return 2;
552 case QIOR:
553 case QIOR_4:
554 return 4;
555 default:
556 return -1;
557 }
558}
559
560static bool aspeed_smc_do_snoop(AspeedSMCFlash *fl, uint64_t data,
561 unsigned size)
562{
563 AspeedSMCState *s = fl->controller;
564 uint8_t addr_width = aspeed_smc_flash_addr_width(fl);
565
566 trace_aspeed_smc_do_snoop(fl->cs, s->snoop_index, s->snoop_dummies,
567 (uint8_t) data & 0xff);
568
569 if (s->snoop_index == SNOOP_OFF) {
570 return false;
571
572 } else if (s->snoop_index == SNOOP_START) {
573 uint8_t cmd = data & 0xff;
574 int ndummies = aspeed_smc_num_dummies(cmd);
575
576
577
578
579
580 if (ndummies <= 0) {
581 s->snoop_index = SNOOP_OFF;
582 return false;
583 }
584
585 s->snoop_dummies = ndummies * 8;
586
587 } else if (s->snoop_index >= addr_width + 1) {
588
589
590 for (; s->snoop_dummies; s->snoop_dummies--) {
591 ssi_transfer(s->spi, s->regs[R_DUMMY_DATA] & 0xff);
592 }
593
594
595 if (!s->snoop_dummies) {
596 s->snoop_index = SNOOP_OFF;
597 } else {
598 s->snoop_index += size;
599 }
600
601
602
603
604
605 return true;
606 }
607
608 s->snoop_index += size;
609 return false;
610}
611
612static void aspeed_smc_flash_write(void *opaque, hwaddr addr, uint64_t data,
613 unsigned size)
614{
615 AspeedSMCFlash *fl = opaque;
616 AspeedSMCState *s = fl->controller;
617 int i;
618
619 trace_aspeed_smc_flash_write(fl->cs, addr, size, data,
620 aspeed_smc_flash_mode(fl));
621
622 if (!aspeed_smc_is_writable(fl)) {
623 aspeed_smc_error("flash is not writable at 0x%" HWADDR_PRIx, addr);
624 return;
625 }
626
627 switch (aspeed_smc_flash_mode(fl)) {
628 case CTRL_USERMODE:
629 if (aspeed_smc_do_snoop(fl, data, size)) {
630 break;
631 }
632
633 for (i = 0; i < size; i++) {
634 ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
635 }
636 break;
637 case CTRL_WRITEMODE:
638 aspeed_smc_flash_select(fl);
639 aspeed_smc_flash_setup(fl, addr);
640
641 for (i = 0; i < size; i++) {
642 ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
643 }
644
645 aspeed_smc_flash_unselect(fl);
646 break;
647 default:
648 aspeed_smc_error("invalid flash mode %d", aspeed_smc_flash_mode(fl));
649 }
650}
651
652static const MemoryRegionOps aspeed_smc_flash_ops = {
653 .read = aspeed_smc_flash_read,
654 .write = aspeed_smc_flash_write,
655 .endianness = DEVICE_LITTLE_ENDIAN,
656 .valid = {
657 .min_access_size = 1,
658 .max_access_size = 4,
659 },
660};
661
662static void aspeed_smc_flash_update_ctrl(AspeedSMCFlash *fl, uint32_t value)
663{
664 AspeedSMCState *s = fl->controller;
665 bool unselect;
666
667
668 unselect = (value & CTRL_CMD_MODE_MASK) != CTRL_USERMODE;
669
670
671 if (!(s->regs[s->r_ctrl0 + fl->cs] & CTRL_CE_STOP_ACTIVE) &&
672 value & CTRL_CE_STOP_ACTIVE) {
673 unselect = true;
674 }
675
676 s->regs[s->r_ctrl0 + fl->cs] = value;
677
678 s->snoop_index = unselect ? SNOOP_OFF : SNOOP_START;
679
680 aspeed_smc_flash_do_select(fl, unselect);
681}
682
683static void aspeed_smc_reset(DeviceState *d)
684{
685 AspeedSMCState *s = ASPEED_SMC(d);
686 AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
687 int i;
688
689 if (asc->resets) {
690 memcpy(s->regs, asc->resets, sizeof s->regs);
691 } else {
692 memset(s->regs, 0, sizeof s->regs);
693 }
694
695
696 for (i = 0; i < asc->cs_num_max; ++i) {
697 s->regs[s->r_ctrl0 + i] |= CTRL_CE_STOP_ACTIVE;
698 qemu_set_irq(s->cs_lines[i], true);
699 }
700
701
702 for (i = 0; i < asc->cs_num_max; ++i) {
703 aspeed_smc_flash_set_segment_region(s, i,
704 asc->segment_to_reg(s, &asc->segments[i]));
705 }
706
707 s->snoop_index = SNOOP_OFF;
708 s->snoop_dummies = 0;
709}
710
711static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
712{
713 AspeedSMCState *s = ASPEED_SMC(opaque);
714 AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(opaque);
715
716 addr >>= 2;
717
718 if (addr == s->r_conf ||
719 (addr >= s->r_timings &&
720 addr < s->r_timings + asc->nregs_timings) ||
721 addr == s->r_ce_ctrl ||
722 addr == R_CE_CMD_CTRL ||
723 addr == R_INTR_CTRL ||
724 addr == R_DUMMY_DATA ||
725 (aspeed_smc_has_wdt_control(asc) && addr == R_FMC_WDT2_CTRL) ||
726 (aspeed_smc_has_dma(asc) && addr == R_DMA_CTRL) ||
727 (aspeed_smc_has_dma(asc) && addr == R_DMA_FLASH_ADDR) ||
728 (aspeed_smc_has_dma(asc) && addr == R_DMA_DRAM_ADDR) ||
729 (aspeed_smc_has_dma(asc) && addr == R_DMA_LEN) ||
730 (aspeed_smc_has_dma(asc) && addr == R_DMA_CHECKSUM) ||
731 (addr >= R_SEG_ADDR0 &&
732 addr < R_SEG_ADDR0 + asc->cs_num_max) ||
733 (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + asc->cs_num_max)) {
734
735 trace_aspeed_smc_read(addr << 2, size, s->regs[addr]);
736
737 return s->regs[addr];
738 } else {
739 qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
740 __func__, addr);
741 return -1;
742 }
743}
744
745static uint8_t aspeed_smc_hclk_divisor(uint8_t hclk_mask)
746{
747
748 const uint8_t hclk_divisors[] = {
749 15, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 0
750 };
751 int i;
752
753 for (i = 0; i < ARRAY_SIZE(hclk_divisors); i++) {
754 if (hclk_mask == hclk_divisors[i]) {
755 return i + 1;
756 }
757 }
758
759 aspeed_smc_error("invalid HCLK mask %x", hclk_mask);
760 return 0;
761}
762
763
764
765
766
767
768static void aspeed_smc_dma_calibration(AspeedSMCState *s)
769{
770 uint8_t delay =
771 (s->regs[R_DMA_CTRL] >> DMA_CTRL_DELAY_SHIFT) & DMA_CTRL_DELAY_MASK;
772 uint8_t hclk_mask =
773 (s->regs[R_DMA_CTRL] >> DMA_CTRL_FREQ_SHIFT) & DMA_CTRL_FREQ_MASK;
774 uint8_t hclk_div = aspeed_smc_hclk_divisor(hclk_mask);
775 uint32_t hclk_shift = (hclk_div - 1) << 2;
776 uint8_t cs;
777
778
779
780
781
782 if (hclk_div && hclk_div < 6) {
783 s->regs[s->r_timings] &= ~(0xf << hclk_shift);
784 s->regs[s->r_timings] |= delay << hclk_shift;
785 }
786
787
788
789
790
791
792
793 cs = 0;
794 s->regs[s->r_ctrl0 + cs] &=
795 ~(CE_CTRL_CLOCK_FREQ_MASK << CE_CTRL_CLOCK_FREQ_SHIFT);
796 s->regs[s->r_ctrl0 + cs] |= CE_CTRL_CLOCK_FREQ(hclk_div);
797}
798
799
800
801
802
803
804
805static bool aspeed_smc_inject_read_failure(AspeedSMCState *s)
806{
807 uint8_t delay =
808 (s->regs[R_DMA_CTRL] >> DMA_CTRL_DELAY_SHIFT) & DMA_CTRL_DELAY_MASK;
809 uint8_t hclk_mask =
810 (s->regs[R_DMA_CTRL] >> DMA_CTRL_FREQ_SHIFT) & DMA_CTRL_FREQ_MASK;
811
812
813
814
815 switch (aspeed_smc_hclk_divisor(hclk_mask)) {
816 case 4 ... 16:
817 return false;
818 case 3:
819 return (delay & 0x7) < 1;
820 case 2:
821 return (delay & 0x7) < 2;
822 case 1:
823 return true;
824 default:
825 g_assert_not_reached();
826 }
827}
828
829
830
831
832
833static void aspeed_smc_dma_checksum(AspeedSMCState *s)
834{
835 MemTxResult result;
836 uint32_t data;
837
838 if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
839 aspeed_smc_error("invalid direction for DMA checksum");
840 return;
841 }
842
843 if (s->regs[R_DMA_CTRL] & DMA_CTRL_CALIB) {
844 aspeed_smc_dma_calibration(s);
845 }
846
847 while (s->regs[R_DMA_LEN]) {
848 data = address_space_ldl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
849 MEMTXATTRS_UNSPECIFIED, &result);
850 if (result != MEMTX_OK) {
851 aspeed_smc_error("Flash read failed @%08x",
852 s->regs[R_DMA_FLASH_ADDR]);
853 return;
854 }
855 trace_aspeed_smc_dma_checksum(s->regs[R_DMA_FLASH_ADDR], data);
856
857
858
859
860
861 s->regs[R_DMA_CHECKSUM] += data;
862 s->regs[R_DMA_FLASH_ADDR] += 4;
863 s->regs[R_DMA_LEN] -= 4;
864 }
865
866 if (s->inject_failure && aspeed_smc_inject_read_failure(s)) {
867 s->regs[R_DMA_CHECKSUM] = 0xbadc0de;
868 }
869
870}
871
872static void aspeed_smc_dma_rw(AspeedSMCState *s)
873{
874 MemTxResult result;
875 uint32_t data;
876
877 trace_aspeed_smc_dma_rw(s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE ?
878 "write" : "read",
879 s->regs[R_DMA_FLASH_ADDR],
880 s->regs[R_DMA_DRAM_ADDR],
881 s->regs[R_DMA_LEN]);
882 while (s->regs[R_DMA_LEN]) {
883 if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
884 data = address_space_ldl_le(&s->dram_as, s->regs[R_DMA_DRAM_ADDR],
885 MEMTXATTRS_UNSPECIFIED, &result);
886 if (result != MEMTX_OK) {
887 aspeed_smc_error("DRAM read failed @%08x",
888 s->regs[R_DMA_DRAM_ADDR]);
889 return;
890 }
891
892 address_space_stl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
893 data, MEMTXATTRS_UNSPECIFIED, &result);
894 if (result != MEMTX_OK) {
895 aspeed_smc_error("Flash write failed @%08x",
896 s->regs[R_DMA_FLASH_ADDR]);
897 return;
898 }
899 } else {
900 data = address_space_ldl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
901 MEMTXATTRS_UNSPECIFIED, &result);
902 if (result != MEMTX_OK) {
903 aspeed_smc_error("Flash read failed @%08x",
904 s->regs[R_DMA_FLASH_ADDR]);
905 return;
906 }
907
908 address_space_stl_le(&s->dram_as, s->regs[R_DMA_DRAM_ADDR],
909 data, MEMTXATTRS_UNSPECIFIED, &result);
910 if (result != MEMTX_OK) {
911 aspeed_smc_error("DRAM write failed @%08x",
912 s->regs[R_DMA_DRAM_ADDR]);
913 return;
914 }
915 }
916
917
918
919
920
921 s->regs[R_DMA_FLASH_ADDR] += 4;
922 s->regs[R_DMA_DRAM_ADDR] += 4;
923 s->regs[R_DMA_LEN] -= 4;
924 s->regs[R_DMA_CHECKSUM] += data;
925 }
926}
927
928static void aspeed_smc_dma_stop(AspeedSMCState *s)
929{
930
931
932
933
934 s->regs[R_INTR_CTRL] &= ~INTR_CTRL_DMA_STATUS;
935 s->regs[R_DMA_CHECKSUM] = 0;
936
937
938
939
940
941 qemu_irq_lower(s->irq);
942}
943
944
945
946
947
948static bool aspeed_smc_dma_in_progress(AspeedSMCState *s)
949{
950 return s->regs[R_DMA_CTRL] & DMA_CTRL_ENABLE &&
951 !(s->regs[R_INTR_CTRL] & INTR_CTRL_DMA_STATUS);
952}
953
954static void aspeed_smc_dma_done(AspeedSMCState *s)
955{
956 s->regs[R_INTR_CTRL] |= INTR_CTRL_DMA_STATUS;
957 if (s->regs[R_INTR_CTRL] & INTR_CTRL_DMA_EN) {
958 qemu_irq_raise(s->irq);
959 }
960}
961
962static void aspeed_smc_dma_ctrl(AspeedSMCState *s, uint32_t dma_ctrl)
963{
964 if (!(dma_ctrl & DMA_CTRL_ENABLE)) {
965 s->regs[R_DMA_CTRL] = dma_ctrl;
966
967 aspeed_smc_dma_stop(s);
968 return;
969 }
970
971 if (aspeed_smc_dma_in_progress(s)) {
972 aspeed_smc_error("DMA in progress !");
973 return;
974 }
975
976 s->regs[R_DMA_CTRL] = dma_ctrl;
977
978 if (s->regs[R_DMA_CTRL] & DMA_CTRL_CKSUM) {
979 aspeed_smc_dma_checksum(s);
980 } else {
981 aspeed_smc_dma_rw(s);
982 }
983
984 aspeed_smc_dma_done(s);
985}
986
987static inline bool aspeed_smc_dma_granted(AspeedSMCState *s)
988{
989 AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
990
991 if (!(asc->features & ASPEED_SMC_FEATURE_DMA_GRANT)) {
992 return true;
993 }
994
995 if (!(s->regs[R_DMA_CTRL] & DMA_CTRL_GRANT)) {
996 aspeed_smc_error("DMA not granted");
997 return false;
998 }
999
1000 return true;
1001}
1002
1003static void aspeed_2600_smc_dma_ctrl(AspeedSMCState *s, uint32_t dma_ctrl)
1004{
1005
1006 dma_ctrl |= s->regs[R_DMA_CTRL] & (DMA_CTRL_REQUEST | DMA_CTRL_GRANT);
1007
1008 if (dma_ctrl == 0xAEED0000) {
1009
1010 s->regs[R_DMA_CTRL] |= (DMA_CTRL_REQUEST | DMA_CTRL_GRANT);
1011 return;
1012 }
1013
1014
1015 if (dma_ctrl == 0xDEEA0000) {
1016 s->regs[R_DMA_CTRL] &= ~(DMA_CTRL_REQUEST | DMA_CTRL_GRANT);
1017 return;
1018 }
1019
1020 if (!aspeed_smc_dma_granted(s)) {
1021 aspeed_smc_error("DMA not granted");
1022 return;
1023 }
1024
1025 aspeed_smc_dma_ctrl(s, dma_ctrl);
1026 s->regs[R_DMA_CTRL] &= ~(DMA_CTRL_REQUEST | DMA_CTRL_GRANT);
1027}
1028
1029static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
1030 unsigned int size)
1031{
1032 AspeedSMCState *s = ASPEED_SMC(opaque);
1033 AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
1034 uint32_t value = data;
1035
1036 trace_aspeed_smc_write(addr, size, data);
1037
1038 addr >>= 2;
1039
1040 if (addr == s->r_conf ||
1041 (addr >= s->r_timings &&
1042 addr < s->r_timings + asc->nregs_timings) ||
1043 addr == s->r_ce_ctrl) {
1044 s->regs[addr] = value;
1045 } else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + asc->cs_num_max) {
1046 int cs = addr - s->r_ctrl0;
1047 aspeed_smc_flash_update_ctrl(&s->flashes[cs], value);
1048 } else if (addr >= R_SEG_ADDR0 &&
1049 addr < R_SEG_ADDR0 + asc->cs_num_max) {
1050 int cs = addr - R_SEG_ADDR0;
1051
1052 if (value != s->regs[R_SEG_ADDR0 + cs]) {
1053 aspeed_smc_flash_set_segment(s, cs, value);
1054 }
1055 } else if (addr == R_CE_CMD_CTRL) {
1056 s->regs[addr] = value & 0xff;
1057 } else if (addr == R_DUMMY_DATA) {
1058 s->regs[addr] = value & 0xff;
1059 } else if (aspeed_smc_has_wdt_control(asc) && addr == R_FMC_WDT2_CTRL) {
1060 s->regs[addr] = value & FMC_WDT2_CTRL_EN;
1061 } else if (addr == R_INTR_CTRL) {
1062 s->regs[addr] = value;
1063 } else if (aspeed_smc_has_dma(asc) && addr == R_DMA_CTRL) {
1064 asc->dma_ctrl(s, value);
1065 } else if (aspeed_smc_has_dma(asc) && addr == R_DMA_DRAM_ADDR &&
1066 aspeed_smc_dma_granted(s)) {
1067 s->regs[addr] = DMA_DRAM_ADDR(asc, value);
1068 } else if (aspeed_smc_has_dma(asc) && addr == R_DMA_FLASH_ADDR &&
1069 aspeed_smc_dma_granted(s)) {
1070 s->regs[addr] = DMA_FLASH_ADDR(asc, value);
1071 } else if (aspeed_smc_has_dma(asc) && addr == R_DMA_LEN &&
1072 aspeed_smc_dma_granted(s)) {
1073 s->regs[addr] = DMA_LENGTH(value);
1074 } else {
1075 qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
1076 __func__, addr);
1077 return;
1078 }
1079}
1080
1081static const MemoryRegionOps aspeed_smc_ops = {
1082 .read = aspeed_smc_read,
1083 .write = aspeed_smc_write,
1084 .endianness = DEVICE_LITTLE_ENDIAN,
1085};
1086
1087static void aspeed_smc_instance_init(Object *obj)
1088{
1089 AspeedSMCState *s = ASPEED_SMC(obj);
1090 AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
1091 int i;
1092
1093 for (i = 0; i < asc->cs_num_max; i++) {
1094 object_initialize_child(obj, "flash[*]", &s->flashes[i],
1095 TYPE_ASPEED_SMC_FLASH);
1096 }
1097}
1098
1099
1100
1101
1102static void aspeed_smc_dma_setup(AspeedSMCState *s, Error **errp)
1103{
1104 if (!s->dram_mr) {
1105 error_setg(errp, TYPE_ASPEED_SMC ": 'dram' link not set");
1106 return;
1107 }
1108
1109 address_space_init(&s->flash_as, &s->mmio_flash,
1110 TYPE_ASPEED_SMC ".dma-flash");
1111 address_space_init(&s->dram_as, s->dram_mr,
1112 TYPE_ASPEED_SMC ".dma-dram");
1113}
1114
1115static void aspeed_smc_realize(DeviceState *dev, Error **errp)
1116{
1117 SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
1118 AspeedSMCState *s = ASPEED_SMC(dev);
1119 AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
1120 int i;
1121 hwaddr offset = 0;
1122
1123
1124 s->r_conf = asc->r_conf;
1125 s->r_ce_ctrl = asc->r_ce_ctrl;
1126 s->r_ctrl0 = asc->r_ctrl0;
1127 s->r_timings = asc->r_timings;
1128 s->conf_enable_w0 = asc->conf_enable_w0;
1129
1130
1131 sysbus_init_irq(sbd, &s->irq);
1132
1133 s->spi = ssi_create_bus(dev, NULL);
1134
1135
1136 s->cs_lines = g_new0(qemu_irq, asc->cs_num_max);
1137 qdev_init_gpio_out_named(DEVICE(s), s->cs_lines, "cs", asc->cs_num_max);
1138
1139
1140 memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_smc_ops, s,
1141 TYPE_ASPEED_SMC, asc->nregs * 4);
1142 sysbus_init_mmio(sbd, &s->mmio);
1143
1144
1145
1146
1147
1148
1149 memory_region_init(&s->mmio_flash_container, OBJECT(s),
1150 TYPE_ASPEED_SMC ".container",
1151 asc->flash_window_size);
1152 sysbus_init_mmio(sbd, &s->mmio_flash_container);
1153
1154 memory_region_init_io(&s->mmio_flash, OBJECT(s),
1155 &aspeed_smc_flash_default_ops, s,
1156 TYPE_ASPEED_SMC ".flash",
1157 asc->flash_window_size);
1158 memory_region_add_subregion(&s->mmio_flash_container, 0x0,
1159 &s->mmio_flash);
1160
1161
1162
1163
1164
1165
1166
1167
1168 for (i = 0; i < asc->cs_num_max; ++i) {
1169 AspeedSMCFlash *fl = &s->flashes[i];
1170
1171 if (!object_property_set_link(OBJECT(fl), "controller", OBJECT(s),
1172 errp)) {
1173 return;
1174 }
1175 if (!object_property_set_uint(OBJECT(fl), "cs", i, errp)) {
1176 return;
1177 }
1178 if (!sysbus_realize(SYS_BUS_DEVICE(fl), errp)) {
1179 return;
1180 }
1181
1182 memory_region_add_subregion(&s->mmio_flash, offset, &fl->mmio);
1183 offset += asc->segments[i].size;
1184 }
1185
1186
1187 if (aspeed_smc_has_dma(asc)) {
1188 aspeed_smc_dma_setup(s, errp);
1189 }
1190}
1191
1192static const VMStateDescription vmstate_aspeed_smc = {
1193 .name = "aspeed.smc",
1194 .version_id = 2,
1195 .minimum_version_id = 2,
1196 .fields = (VMStateField[]) {
1197 VMSTATE_UINT32_ARRAY(regs, AspeedSMCState, ASPEED_SMC_R_MAX),
1198 VMSTATE_UINT8(snoop_index, AspeedSMCState),
1199 VMSTATE_UINT8(snoop_dummies, AspeedSMCState),
1200 VMSTATE_END_OF_LIST()
1201 }
1202};
1203
1204static Property aspeed_smc_properties[] = {
1205 DEFINE_PROP_BOOL("inject-failure", AspeedSMCState, inject_failure, false),
1206 DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr,
1207 TYPE_MEMORY_REGION, MemoryRegion *),
1208 DEFINE_PROP_END_OF_LIST(),
1209};
1210
1211static void aspeed_smc_class_init(ObjectClass *klass, void *data)
1212{
1213 DeviceClass *dc = DEVICE_CLASS(klass);
1214
1215 dc->realize = aspeed_smc_realize;
1216 dc->reset = aspeed_smc_reset;
1217 device_class_set_props(dc, aspeed_smc_properties);
1218 dc->vmsd = &vmstate_aspeed_smc;
1219}
1220
1221static const TypeInfo aspeed_smc_info = {
1222 .name = TYPE_ASPEED_SMC,
1223 .parent = TYPE_SYS_BUS_DEVICE,
1224 .instance_init = aspeed_smc_instance_init,
1225 .instance_size = sizeof(AspeedSMCState),
1226 .class_size = sizeof(AspeedSMCClass),
1227 .class_init = aspeed_smc_class_init,
1228 .abstract = true,
1229};
1230
1231static void aspeed_smc_flash_realize(DeviceState *dev, Error **errp)
1232{
1233 AspeedSMCFlash *s = ASPEED_SMC_FLASH(dev);
1234 g_autofree char *name = g_strdup_printf(TYPE_ASPEED_SMC_FLASH ".%d", s->cs);
1235
1236 if (!s->controller) {
1237 error_setg(errp, TYPE_ASPEED_SMC_FLASH ": 'controller' link not set");
1238 return;
1239 }
1240
1241 s->asc = ASPEED_SMC_GET_CLASS(s->controller);
1242
1243
1244
1245
1246
1247 memory_region_init_io(&s->mmio, OBJECT(s), &aspeed_smc_flash_ops,
1248 s, name, s->asc->segments[s->cs].size);
1249 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
1250}
1251
1252static Property aspeed_smc_flash_properties[] = {
1253 DEFINE_PROP_UINT8("cs", AspeedSMCFlash, cs, 0),
1254 DEFINE_PROP_LINK("controller", AspeedSMCFlash, controller, TYPE_ASPEED_SMC,
1255 AspeedSMCState *),
1256 DEFINE_PROP_END_OF_LIST(),
1257};
1258
1259static void aspeed_smc_flash_class_init(ObjectClass *klass, void *data)
1260{
1261 DeviceClass *dc = DEVICE_CLASS(klass);
1262
1263 dc->desc = "Aspeed SMC Flash device region";
1264 dc->realize = aspeed_smc_flash_realize;
1265 device_class_set_props(dc, aspeed_smc_flash_properties);
1266}
1267
1268static const TypeInfo aspeed_smc_flash_info = {
1269 .name = TYPE_ASPEED_SMC_FLASH,
1270 .parent = TYPE_SYS_BUS_DEVICE,
1271 .instance_size = sizeof(AspeedSMCFlash),
1272 .class_init = aspeed_smc_flash_class_init,
1273};
1274
1275
1276
1277
1278
1279
1280
1281static uint32_t aspeed_smc_segment_to_reg(const AspeedSMCState *s,
1282 const AspeedSegments *seg)
1283{
1284 uint32_t reg = 0;
1285 reg |= ((seg->addr >> 23) & SEG_START_MASK) << SEG_START_SHIFT;
1286 reg |= (((seg->addr + seg->size) >> 23) & SEG_END_MASK) << SEG_END_SHIFT;
1287 return reg;
1288}
1289
1290static void aspeed_smc_reg_to_segment(const AspeedSMCState *s,
1291 uint32_t reg, AspeedSegments *seg)
1292{
1293 seg->addr = ((reg >> SEG_START_SHIFT) & SEG_START_MASK) << 23;
1294 seg->size = (((reg >> SEG_END_SHIFT) & SEG_END_MASK) << 23) - seg->addr;
1295}
1296
1297static const AspeedSegments aspeed_2400_smc_segments[] = {
1298 { 0x10000000, 32 * MiB },
1299};
1300
1301static void aspeed_2400_smc_class_init(ObjectClass *klass, void *data)
1302{
1303 DeviceClass *dc = DEVICE_CLASS(klass);
1304 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1305
1306 dc->desc = "Aspeed 2400 SMC Controller";
1307 asc->r_conf = R_CONF;
1308 asc->r_ce_ctrl = R_CE_CTRL;
1309 asc->r_ctrl0 = R_CTRL0;
1310 asc->r_timings = R_TIMINGS;
1311 asc->nregs_timings = 1;
1312 asc->conf_enable_w0 = CONF_ENABLE_W0;
1313 asc->cs_num_max = 1;
1314 asc->segments = aspeed_2400_smc_segments;
1315 asc->flash_window_base = 0x10000000;
1316 asc->flash_window_size = 0x6000000;
1317 asc->features = 0x0;
1318 asc->nregs = ASPEED_SMC_R_SMC_MAX;
1319 asc->segment_to_reg = aspeed_smc_segment_to_reg;
1320 asc->reg_to_segment = aspeed_smc_reg_to_segment;
1321 asc->dma_ctrl = aspeed_smc_dma_ctrl;
1322}
1323
1324static const TypeInfo aspeed_2400_smc_info = {
1325 .name = "aspeed.smc-ast2400",
1326 .parent = TYPE_ASPEED_SMC,
1327 .class_init = aspeed_2400_smc_class_init,
1328};
1329
1330static const uint32_t aspeed_2400_fmc_resets[ASPEED_SMC_R_MAX] = {
1331
1332
1333
1334
1335 [R_CONF] = CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0,
1336};
1337
1338static const AspeedSegments aspeed_2400_fmc_segments[] = {
1339 { 0x20000000, 64 * MiB },
1340 { 0x24000000, 32 * MiB },
1341 { 0x26000000, 32 * MiB },
1342 { 0x28000000, 32 * MiB },
1343 { 0x2A000000, 32 * MiB }
1344};
1345
1346static void aspeed_2400_fmc_class_init(ObjectClass *klass, void *data)
1347{
1348 DeviceClass *dc = DEVICE_CLASS(klass);
1349 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1350
1351 dc->desc = "Aspeed 2400 FMC Controller";
1352 asc->r_conf = R_CONF;
1353 asc->r_ce_ctrl = R_CE_CTRL;
1354 asc->r_ctrl0 = R_CTRL0;
1355 asc->r_timings = R_TIMINGS;
1356 asc->nregs_timings = 1;
1357 asc->conf_enable_w0 = CONF_ENABLE_W0;
1358 asc->cs_num_max = 5;
1359 asc->segments = aspeed_2400_fmc_segments;
1360 asc->segment_addr_mask = 0xffff0000;
1361 asc->resets = aspeed_2400_fmc_resets;
1362 asc->flash_window_base = 0x20000000;
1363 asc->flash_window_size = 0x10000000;
1364 asc->features = ASPEED_SMC_FEATURE_DMA;
1365 asc->dma_flash_mask = 0x0FFFFFFC;
1366 asc->dma_dram_mask = 0x1FFFFFFC;
1367 asc->nregs = ASPEED_SMC_R_MAX;
1368 asc->segment_to_reg = aspeed_smc_segment_to_reg;
1369 asc->reg_to_segment = aspeed_smc_reg_to_segment;
1370 asc->dma_ctrl = aspeed_smc_dma_ctrl;
1371}
1372
1373static const TypeInfo aspeed_2400_fmc_info = {
1374 .name = "aspeed.fmc-ast2400",
1375 .parent = TYPE_ASPEED_SMC,
1376 .class_init = aspeed_2400_fmc_class_init,
1377};
1378
1379static const AspeedSegments aspeed_2400_spi1_segments[] = {
1380 { 0x30000000, 64 * MiB },
1381};
1382
1383static int aspeed_2400_spi1_addr_width(const AspeedSMCState *s)
1384{
1385 return s->regs[R_SPI_CTRL0] & CTRL_AST2400_SPI_4BYTE ? 4 : 3;
1386}
1387
1388static void aspeed_2400_spi1_class_init(ObjectClass *klass, void *data)
1389{
1390 DeviceClass *dc = DEVICE_CLASS(klass);
1391 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1392
1393 dc->desc = "Aspeed 2400 SPI1 Controller";
1394 asc->r_conf = R_SPI_CONF;
1395 asc->r_ce_ctrl = 0xff;
1396 asc->r_ctrl0 = R_SPI_CTRL0;
1397 asc->r_timings = R_SPI_TIMINGS;
1398 asc->nregs_timings = 1;
1399 asc->conf_enable_w0 = SPI_CONF_ENABLE_W0;
1400 asc->cs_num_max = 1;
1401 asc->segments = aspeed_2400_spi1_segments;
1402 asc->flash_window_base = 0x30000000;
1403 asc->flash_window_size = 0x10000000;
1404 asc->features = 0x0;
1405 asc->nregs = ASPEED_SMC_R_SPI_MAX;
1406 asc->segment_to_reg = aspeed_smc_segment_to_reg;
1407 asc->reg_to_segment = aspeed_smc_reg_to_segment;
1408 asc->dma_ctrl = aspeed_smc_dma_ctrl;
1409 asc->addr_width = aspeed_2400_spi1_addr_width;
1410}
1411
1412static const TypeInfo aspeed_2400_spi1_info = {
1413 .name = "aspeed.spi1-ast2400",
1414 .parent = TYPE_ASPEED_SMC,
1415 .class_init = aspeed_2400_spi1_class_init,
1416};
1417
1418static const uint32_t aspeed_2500_fmc_resets[ASPEED_SMC_R_MAX] = {
1419 [R_CONF] = (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0 |
1420 CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1),
1421};
1422
1423static const AspeedSegments aspeed_2500_fmc_segments[] = {
1424 { 0x20000000, 128 * MiB },
1425 { 0x28000000, 32 * MiB },
1426 { 0x2A000000, 32 * MiB },
1427};
1428
1429static void aspeed_2500_fmc_class_init(ObjectClass *klass, void *data)
1430{
1431 DeviceClass *dc = DEVICE_CLASS(klass);
1432 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1433
1434 dc->desc = "Aspeed 2600 FMC Controller";
1435 asc->r_conf = R_CONF;
1436 asc->r_ce_ctrl = R_CE_CTRL;
1437 asc->r_ctrl0 = R_CTRL0;
1438 asc->r_timings = R_TIMINGS;
1439 asc->nregs_timings = 1;
1440 asc->conf_enable_w0 = CONF_ENABLE_W0;
1441 asc->cs_num_max = 3;
1442 asc->segments = aspeed_2500_fmc_segments;
1443 asc->segment_addr_mask = 0xffff0000;
1444 asc->resets = aspeed_2500_fmc_resets;
1445 asc->flash_window_base = 0x20000000;
1446 asc->flash_window_size = 0x10000000;
1447 asc->features = ASPEED_SMC_FEATURE_DMA;
1448 asc->dma_flash_mask = 0x0FFFFFFC;
1449 asc->dma_dram_mask = 0x3FFFFFFC;
1450 asc->nregs = ASPEED_SMC_R_MAX;
1451 asc->segment_to_reg = aspeed_smc_segment_to_reg;
1452 asc->reg_to_segment = aspeed_smc_reg_to_segment;
1453 asc->dma_ctrl = aspeed_smc_dma_ctrl;
1454}
1455
1456static const TypeInfo aspeed_2500_fmc_info = {
1457 .name = "aspeed.fmc-ast2500",
1458 .parent = TYPE_ASPEED_SMC,
1459 .class_init = aspeed_2500_fmc_class_init,
1460};
1461
1462static const AspeedSegments aspeed_2500_spi1_segments[] = {
1463 { 0x30000000, 32 * MiB },
1464 { 0x32000000, 96 * MiB },
1465};
1466
1467static void aspeed_2500_spi1_class_init(ObjectClass *klass, void *data)
1468{
1469 DeviceClass *dc = DEVICE_CLASS(klass);
1470 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1471
1472 dc->desc = "Aspeed 2600 SPI1 Controller";
1473 asc->r_conf = R_CONF;
1474 asc->r_ce_ctrl = R_CE_CTRL;
1475 asc->r_ctrl0 = R_CTRL0;
1476 asc->r_timings = R_TIMINGS;
1477 asc->nregs_timings = 1;
1478 asc->conf_enable_w0 = CONF_ENABLE_W0;
1479 asc->cs_num_max = 2;
1480 asc->segments = aspeed_2500_spi1_segments;
1481 asc->segment_addr_mask = 0xffff0000;
1482 asc->flash_window_base = 0x30000000;
1483 asc->flash_window_size = 0x8000000;
1484 asc->features = 0x0;
1485 asc->nregs = ASPEED_SMC_R_MAX;
1486 asc->segment_to_reg = aspeed_smc_segment_to_reg;
1487 asc->reg_to_segment = aspeed_smc_reg_to_segment;
1488 asc->dma_ctrl = aspeed_smc_dma_ctrl;
1489}
1490
1491static const TypeInfo aspeed_2500_spi1_info = {
1492 .name = "aspeed.spi1-ast2500",
1493 .parent = TYPE_ASPEED_SMC,
1494 .class_init = aspeed_2500_spi1_class_init,
1495};
1496
1497static const AspeedSegments aspeed_2500_spi2_segments[] = {
1498 { 0x38000000, 32 * MiB },
1499 { 0x3A000000, 96 * MiB },
1500};
1501
1502static void aspeed_2500_spi2_class_init(ObjectClass *klass, void *data)
1503{
1504 DeviceClass *dc = DEVICE_CLASS(klass);
1505 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1506
1507 dc->desc = "Aspeed 2600 SPI2 Controller";
1508 asc->r_conf = R_CONF;
1509 asc->r_ce_ctrl = R_CE_CTRL;
1510 asc->r_ctrl0 = R_CTRL0;
1511 asc->r_timings = R_TIMINGS;
1512 asc->nregs_timings = 1;
1513 asc->conf_enable_w0 = CONF_ENABLE_W0;
1514 asc->cs_num_max = 2;
1515 asc->segments = aspeed_2500_spi2_segments;
1516 asc->segment_addr_mask = 0xffff0000;
1517 asc->flash_window_base = 0x38000000;
1518 asc->flash_window_size = 0x8000000;
1519 asc->features = 0x0;
1520 asc->nregs = ASPEED_SMC_R_MAX;
1521 asc->segment_to_reg = aspeed_smc_segment_to_reg;
1522 asc->reg_to_segment = aspeed_smc_reg_to_segment;
1523 asc->dma_ctrl = aspeed_smc_dma_ctrl;
1524}
1525
1526static const TypeInfo aspeed_2500_spi2_info = {
1527 .name = "aspeed.spi2-ast2500",
1528 .parent = TYPE_ASPEED_SMC,
1529 .class_init = aspeed_2500_spi2_class_init,
1530};
1531
1532
1533
1534
1535
1536
1537
1538
1539#define AST2600_SEG_ADDR_MASK 0x0ff00000
1540
1541static uint32_t aspeed_2600_smc_segment_to_reg(const AspeedSMCState *s,
1542 const AspeedSegments *seg)
1543{
1544 uint32_t reg = 0;
1545
1546
1547 if (!seg->size) {
1548 return 0;
1549 }
1550
1551 reg |= (seg->addr & AST2600_SEG_ADDR_MASK) >> 16;
1552 reg |= (seg->addr + seg->size - 1) & AST2600_SEG_ADDR_MASK;
1553 return reg;
1554}
1555
1556static void aspeed_2600_smc_reg_to_segment(const AspeedSMCState *s,
1557 uint32_t reg, AspeedSegments *seg)
1558{
1559 uint32_t start_offset = (reg << 16) & AST2600_SEG_ADDR_MASK;
1560 uint32_t end_offset = reg & AST2600_SEG_ADDR_MASK;
1561 AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
1562
1563 if (reg) {
1564 seg->addr = asc->flash_window_base + start_offset;
1565 seg->size = end_offset + MiB - start_offset;
1566 } else {
1567 seg->addr = asc->flash_window_base;
1568 seg->size = 0;
1569 }
1570}
1571
1572static const uint32_t aspeed_2600_fmc_resets[ASPEED_SMC_R_MAX] = {
1573 [R_CONF] = (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0 |
1574 CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1 |
1575 CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE2),
1576};
1577
1578static const AspeedSegments aspeed_2600_fmc_segments[] = {
1579 { 0x0, 128 * MiB },
1580 { 128 * MiB, 128 * MiB },
1581 { 0x0, 0 },
1582};
1583
1584static void aspeed_2600_fmc_class_init(ObjectClass *klass, void *data)
1585{
1586 DeviceClass *dc = DEVICE_CLASS(klass);
1587 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1588
1589 dc->desc = "Aspeed 2600 FMC Controller";
1590 asc->r_conf = R_CONF;
1591 asc->r_ce_ctrl = R_CE_CTRL;
1592 asc->r_ctrl0 = R_CTRL0;
1593 asc->r_timings = R_TIMINGS;
1594 asc->nregs_timings = 1;
1595 asc->conf_enable_w0 = CONF_ENABLE_W0;
1596 asc->cs_num_max = 3;
1597 asc->segments = aspeed_2600_fmc_segments;
1598 asc->segment_addr_mask = 0x0ff00ff0;
1599 asc->resets = aspeed_2600_fmc_resets;
1600 asc->flash_window_base = 0x20000000;
1601 asc->flash_window_size = 0x10000000;
1602 asc->features = ASPEED_SMC_FEATURE_DMA |
1603 ASPEED_SMC_FEATURE_WDT_CONTROL;
1604 asc->dma_flash_mask = 0x0FFFFFFC;
1605 asc->dma_dram_mask = 0x3FFFFFFC;
1606 asc->nregs = ASPEED_SMC_R_MAX;
1607 asc->segment_to_reg = aspeed_2600_smc_segment_to_reg;
1608 asc->reg_to_segment = aspeed_2600_smc_reg_to_segment;
1609 asc->dma_ctrl = aspeed_2600_smc_dma_ctrl;
1610}
1611
1612static const TypeInfo aspeed_2600_fmc_info = {
1613 .name = "aspeed.fmc-ast2600",
1614 .parent = TYPE_ASPEED_SMC,
1615 .class_init = aspeed_2600_fmc_class_init,
1616};
1617
1618static const AspeedSegments aspeed_2600_spi1_segments[] = {
1619 { 0x0, 128 * MiB },
1620 { 0x0, 0 },
1621};
1622
1623static void aspeed_2600_spi1_class_init(ObjectClass *klass, void *data)
1624{
1625 DeviceClass *dc = DEVICE_CLASS(klass);
1626 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1627
1628 dc->desc = "Aspeed 2600 SPI1 Controller";
1629 asc->r_conf = R_CONF;
1630 asc->r_ce_ctrl = R_CE_CTRL;
1631 asc->r_ctrl0 = R_CTRL0;
1632 asc->r_timings = R_TIMINGS;
1633 asc->nregs_timings = 2;
1634 asc->conf_enable_w0 = CONF_ENABLE_W0;
1635 asc->cs_num_max = 2;
1636 asc->segments = aspeed_2600_spi1_segments;
1637 asc->segment_addr_mask = 0x0ff00ff0;
1638 asc->flash_window_base = 0x30000000;
1639 asc->flash_window_size = 0x10000000;
1640 asc->features = ASPEED_SMC_FEATURE_DMA |
1641 ASPEED_SMC_FEATURE_DMA_GRANT;
1642 asc->dma_flash_mask = 0x0FFFFFFC;
1643 asc->dma_dram_mask = 0x3FFFFFFC;
1644 asc->nregs = ASPEED_SMC_R_MAX;
1645 asc->segment_to_reg = aspeed_2600_smc_segment_to_reg;
1646 asc->reg_to_segment = aspeed_2600_smc_reg_to_segment;
1647 asc->dma_ctrl = aspeed_2600_smc_dma_ctrl;
1648}
1649
1650static const TypeInfo aspeed_2600_spi1_info = {
1651 .name = "aspeed.spi1-ast2600",
1652 .parent = TYPE_ASPEED_SMC,
1653 .class_init = aspeed_2600_spi1_class_init,
1654};
1655
1656static const AspeedSegments aspeed_2600_spi2_segments[] = {
1657 { 0x0, 128 * MiB },
1658 { 0x0, 0 },
1659 { 0x0, 0 },
1660};
1661
1662static void aspeed_2600_spi2_class_init(ObjectClass *klass, void *data)
1663{
1664 DeviceClass *dc = DEVICE_CLASS(klass);
1665 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1666
1667 dc->desc = "Aspeed 2600 SPI2 Controller";
1668 asc->r_conf = R_CONF;
1669 asc->r_ce_ctrl = R_CE_CTRL;
1670 asc->r_ctrl0 = R_CTRL0;
1671 asc->r_timings = R_TIMINGS;
1672 asc->nregs_timings = 3;
1673 asc->conf_enable_w0 = CONF_ENABLE_W0;
1674 asc->cs_num_max = 3;
1675 asc->segments = aspeed_2600_spi2_segments;
1676 asc->segment_addr_mask = 0x0ff00ff0;
1677 asc->flash_window_base = 0x50000000;
1678 asc->flash_window_size = 0x10000000;
1679 asc->features = ASPEED_SMC_FEATURE_DMA |
1680 ASPEED_SMC_FEATURE_DMA_GRANT;
1681 asc->dma_flash_mask = 0x0FFFFFFC;
1682 asc->dma_dram_mask = 0x3FFFFFFC;
1683 asc->nregs = ASPEED_SMC_R_MAX;
1684 asc->segment_to_reg = aspeed_2600_smc_segment_to_reg;
1685 asc->reg_to_segment = aspeed_2600_smc_reg_to_segment;
1686 asc->dma_ctrl = aspeed_2600_smc_dma_ctrl;
1687}
1688
1689static const TypeInfo aspeed_2600_spi2_info = {
1690 .name = "aspeed.spi2-ast2600",
1691 .parent = TYPE_ASPEED_SMC,
1692 .class_init = aspeed_2600_spi2_class_init,
1693};
1694
1695
1696
1697
1698
1699#define AST1030_SEG_ADDR_MASK 0x0ff80000
1700
1701static uint32_t aspeed_1030_smc_segment_to_reg(const AspeedSMCState *s,
1702 const AspeedSegments *seg)
1703{
1704 uint32_t reg = 0;
1705
1706
1707 if (!seg->size) {
1708 return 0;
1709 }
1710
1711 reg |= (seg->addr & AST1030_SEG_ADDR_MASK) >> 16;
1712 reg |= (seg->addr + seg->size - 1) & AST1030_SEG_ADDR_MASK;
1713 return reg;
1714}
1715
1716static void aspeed_1030_smc_reg_to_segment(const AspeedSMCState *s,
1717 uint32_t reg, AspeedSegments *seg)
1718{
1719 uint32_t start_offset = (reg << 16) & AST1030_SEG_ADDR_MASK;
1720 uint32_t end_offset = reg & AST1030_SEG_ADDR_MASK;
1721 AspeedSMCClass *asc = ASPEED_SMC_GET_CLASS(s);
1722
1723 if (reg) {
1724 seg->addr = asc->flash_window_base + start_offset;
1725 seg->size = end_offset + (512 * KiB) - start_offset;
1726 } else {
1727 seg->addr = asc->flash_window_base;
1728 seg->size = 0;
1729 }
1730}
1731
1732static const uint32_t aspeed_1030_fmc_resets[ASPEED_SMC_R_MAX] = {
1733 [R_CONF] = (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0 |
1734 CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1),
1735};
1736
1737static const AspeedSegments aspeed_1030_fmc_segments[] = {
1738 { 0x0, 128 * MiB },
1739 { 128 * MiB, 128 * MiB },
1740 { 0x0, 0 },
1741};
1742
1743static void aspeed_1030_fmc_class_init(ObjectClass *klass, void *data)
1744{
1745 DeviceClass *dc = DEVICE_CLASS(klass);
1746 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1747
1748 dc->desc = "Aspeed 1030 FMC Controller";
1749 asc->r_conf = R_CONF;
1750 asc->r_ce_ctrl = R_CE_CTRL;
1751 asc->r_ctrl0 = R_CTRL0;
1752 asc->r_timings = R_TIMINGS;
1753 asc->nregs_timings = 2;
1754 asc->conf_enable_w0 = CONF_ENABLE_W0;
1755 asc->cs_num_max = 2;
1756 asc->segments = aspeed_1030_fmc_segments;
1757 asc->segment_addr_mask = 0x0ff80ff8;
1758 asc->resets = aspeed_1030_fmc_resets;
1759 asc->flash_window_base = 0x80000000;
1760 asc->flash_window_size = 0x10000000;
1761 asc->features = ASPEED_SMC_FEATURE_DMA;
1762 asc->dma_flash_mask = 0x0FFFFFFC;
1763 asc->dma_dram_mask = 0x000BFFFC;
1764 asc->nregs = ASPEED_SMC_R_MAX;
1765 asc->segment_to_reg = aspeed_1030_smc_segment_to_reg;
1766 asc->reg_to_segment = aspeed_1030_smc_reg_to_segment;
1767 asc->dma_ctrl = aspeed_2600_smc_dma_ctrl;
1768}
1769
1770static const TypeInfo aspeed_1030_fmc_info = {
1771 .name = "aspeed.fmc-ast1030",
1772 .parent = TYPE_ASPEED_SMC,
1773 .class_init = aspeed_1030_fmc_class_init,
1774};
1775
1776static const AspeedSegments aspeed_1030_spi1_segments[] = {
1777 { 0x0, 128 * MiB },
1778 { 0x0, 0 },
1779};
1780
1781static void aspeed_1030_spi1_class_init(ObjectClass *klass, void *data)
1782{
1783 DeviceClass *dc = DEVICE_CLASS(klass);
1784 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1785
1786 dc->desc = "Aspeed 1030 SPI1 Controller";
1787 asc->r_conf = R_CONF;
1788 asc->r_ce_ctrl = R_CE_CTRL;
1789 asc->r_ctrl0 = R_CTRL0;
1790 asc->r_timings = R_TIMINGS;
1791 asc->nregs_timings = 2;
1792 asc->conf_enable_w0 = CONF_ENABLE_W0;
1793 asc->cs_num_max = 2;
1794 asc->segments = aspeed_1030_spi1_segments;
1795 asc->segment_addr_mask = 0x0ff00ff0;
1796 asc->flash_window_base = 0x90000000;
1797 asc->flash_window_size = 0x10000000;
1798 asc->features = ASPEED_SMC_FEATURE_DMA;
1799 asc->dma_flash_mask = 0x0FFFFFFC;
1800 asc->dma_dram_mask = 0x000BFFFC;
1801 asc->nregs = ASPEED_SMC_R_MAX;
1802 asc->segment_to_reg = aspeed_2600_smc_segment_to_reg;
1803 asc->reg_to_segment = aspeed_2600_smc_reg_to_segment;
1804 asc->dma_ctrl = aspeed_2600_smc_dma_ctrl;
1805}
1806
1807static const TypeInfo aspeed_1030_spi1_info = {
1808 .name = "aspeed.spi1-ast1030",
1809 .parent = TYPE_ASPEED_SMC,
1810 .class_init = aspeed_1030_spi1_class_init,
1811};
1812static const AspeedSegments aspeed_1030_spi2_segments[] = {
1813 { 0x0, 128 * MiB },
1814 { 0x0, 0 },
1815};
1816
1817static void aspeed_1030_spi2_class_init(ObjectClass *klass, void *data)
1818{
1819 DeviceClass *dc = DEVICE_CLASS(klass);
1820 AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass);
1821
1822 dc->desc = "Aspeed 1030 SPI2 Controller";
1823 asc->r_conf = R_CONF;
1824 asc->r_ce_ctrl = R_CE_CTRL;
1825 asc->r_ctrl0 = R_CTRL0;
1826 asc->r_timings = R_TIMINGS;
1827 asc->nregs_timings = 2;
1828 asc->conf_enable_w0 = CONF_ENABLE_W0;
1829 asc->cs_num_max = 2;
1830 asc->segments = aspeed_1030_spi2_segments;
1831 asc->segment_addr_mask = 0x0ff00ff0;
1832 asc->flash_window_base = 0xb0000000;
1833 asc->flash_window_size = 0x10000000;
1834 asc->features = ASPEED_SMC_FEATURE_DMA;
1835 asc->dma_flash_mask = 0x0FFFFFFC;
1836 asc->dma_dram_mask = 0x000BFFFC;
1837 asc->nregs = ASPEED_SMC_R_MAX;
1838 asc->segment_to_reg = aspeed_2600_smc_segment_to_reg;
1839 asc->reg_to_segment = aspeed_2600_smc_reg_to_segment;
1840 asc->dma_ctrl = aspeed_2600_smc_dma_ctrl;
1841}
1842
1843static const TypeInfo aspeed_1030_spi2_info = {
1844 .name = "aspeed.spi2-ast1030",
1845 .parent = TYPE_ASPEED_SMC,
1846 .class_init = aspeed_1030_spi2_class_init,
1847};
1848
1849static void aspeed_smc_register_types(void)
1850{
1851 type_register_static(&aspeed_smc_flash_info);
1852 type_register_static(&aspeed_smc_info);
1853 type_register_static(&aspeed_2400_smc_info);
1854 type_register_static(&aspeed_2400_fmc_info);
1855 type_register_static(&aspeed_2400_spi1_info);
1856 type_register_static(&aspeed_2500_fmc_info);
1857 type_register_static(&aspeed_2500_spi1_info);
1858 type_register_static(&aspeed_2500_spi2_info);
1859 type_register_static(&aspeed_2600_fmc_info);
1860 type_register_static(&aspeed_2600_spi1_info);
1861 type_register_static(&aspeed_2600_spi2_info);
1862 type_register_static(&aspeed_1030_fmc_info);
1863 type_register_static(&aspeed_1030_spi1_info);
1864 type_register_static(&aspeed_1030_spi2_info);
1865}
1866
1867type_init(aspeed_smc_register_types)
1868