2
0

aspeed_sdmc.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. /*
  2. * ASPEED SDRAM Memory Controller
  3. *
  4. * Copyright (C) 2016 IBM Corp.
  5. *
  6. * This code is licensed under the GPL version 2 or later. See
  7. * the COPYING file in the top-level directory.
  8. */
  9. #include "qemu/osdep.h"
  10. #include "qemu/log.h"
  11. #include "qemu/module.h"
  12. #include "qemu/error-report.h"
  13. #include "hw/misc/aspeed_sdmc.h"
  14. #include "hw/misc/aspeed_scu.h"
  15. #include "hw/qdev-properties.h"
  16. #include "migration/vmstate.h"
  17. #include "qapi/error.h"
  18. #include "trace.h"
  19. #include "qemu/units.h"
  20. #include "qemu/cutils.h"
  21. #include "qapi/visitor.h"
  22. /* Protection Key Register */
  23. #define R_PROT (0x00 / 4)
  24. #define PROT_UNLOCKED 0x01
  25. #define PROT_HARDLOCKED 0x10 /* AST2600 */
  26. #define PROT_SOFTLOCKED 0x00
  27. #define PROT_KEY_UNLOCK 0xFC600309
  28. #define PROT_KEY_HARDLOCK 0xDEADDEAD /* AST2600 */
  29. /* Configuration Register */
  30. #define R_CONF (0x04 / 4)
  31. /* Interrupt control/status */
  32. #define R_ISR (0x50 / 4)
  33. /* Control/Status Register #1 (ast2500) */
  34. #define R_STATUS1 (0x60 / 4)
  35. #define PHY_BUSY_STATE BIT(0)
  36. #define PHY_PLL_LOCK_STATUS BIT(4)
  37. /* Reserved */
  38. #define R_MCR6C (0x6c / 4)
  39. #define R_ECC_TEST_CTRL (0x70 / 4)
  40. #define ECC_TEST_FINISHED BIT(12)
  41. #define ECC_TEST_FAIL BIT(13)
  42. #define R_TEST_START_LEN (0x74 / 4)
  43. #define R_TEST_FAIL_DQ (0x78 / 4)
  44. #define R_TEST_INIT_VAL (0x7c / 4)
  45. #define R_DRAM_SW (0x88 / 4)
  46. #define R_DRAM_TIME (0x8c / 4)
  47. #define R_ECC_ERR_INJECT (0xb4 / 4)
  48. /*
  49. * Configuration register Ox4 (for Aspeed AST2400 SOC)
  50. *
  51. * These are for the record and future use. ASPEED_SDMC_DRAM_SIZE is
  52. * what we care about right now as it is checked by U-Boot to
  53. * determine the RAM size.
  54. */
  55. #define ASPEED_SDMC_RESERVED 0xFFFFF800 /* 31:11 reserved */
  56. #define ASPEED_SDMC_AST2300_COMPAT (1 << 10)
  57. #define ASPEED_SDMC_SCRAMBLE_PATTERN (1 << 9)
  58. #define ASPEED_SDMC_DATA_SCRAMBLE (1 << 8)
  59. #define ASPEED_SDMC_ECC_ENABLE (1 << 7)
  60. #define ASPEED_SDMC_VGA_COMPAT (1 << 6) /* readonly */
  61. #define ASPEED_SDMC_DRAM_BANK (1 << 5)
  62. #define ASPEED_SDMC_DRAM_BURST (1 << 4)
  63. #define ASPEED_SDMC_VGA_APERTURE(x) ((x & 0x3) << 2) /* readonly */
  64. #define ASPEED_SDMC_VGA_8MB 0x0
  65. #define ASPEED_SDMC_VGA_16MB 0x1
  66. #define ASPEED_SDMC_VGA_32MB 0x2
  67. #define ASPEED_SDMC_VGA_64MB 0x3
  68. #define ASPEED_SDMC_DRAM_SIZE(x) (x & 0x3)
  69. #define ASPEED_SDMC_DRAM_64MB 0x0
  70. #define ASPEED_SDMC_DRAM_128MB 0x1
  71. #define ASPEED_SDMC_DRAM_256MB 0x2
  72. #define ASPEED_SDMC_DRAM_512MB 0x3
  73. #define ASPEED_SDMC_READONLY_MASK \
  74. (ASPEED_SDMC_RESERVED | ASPEED_SDMC_VGA_COMPAT | \
  75. ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB))
  76. /*
  77. * Configuration register Ox4 (for Aspeed AST2500 SOC and higher)
  78. *
  79. * Incompatibilities are annotated in the list. ASPEED_SDMC_HW_VERSION
  80. * should be set to 1 for the AST2500 SOC.
  81. */
  82. #define ASPEED_SDMC_HW_VERSION(x) ((x & 0xf) << 28) /* readonly */
  83. #define ASPEED_SDMC_SW_VERSION ((x & 0xff) << 20)
  84. #define ASPEED_SDMC_CACHE_INITIAL_DONE (1 << 19) /* readonly */
  85. #define ASPEED_SDMC_AST2500_RESERVED 0x7C000 /* 18:14 reserved */
  86. #define ASPEED_SDMC_CACHE_DDR4_CONF (1 << 13)
  87. #define ASPEED_SDMC_CACHE_INITIAL (1 << 12)
  88. #define ASPEED_SDMC_CACHE_RANGE_CTRL (1 << 11)
  89. #define ASPEED_SDMC_CACHE_ENABLE (1 << 10) /* differs from AST2400 */
  90. #define ASPEED_SDMC_DRAM_TYPE (1 << 4) /* differs from AST2400 */
  91. /* DRAM size definitions differs */
  92. #define ASPEED_SDMC_AST2500_128MB 0x0
  93. #define ASPEED_SDMC_AST2500_256MB 0x1
  94. #define ASPEED_SDMC_AST2500_512MB 0x2
  95. #define ASPEED_SDMC_AST2500_1024MB 0x3
  96. #define ASPEED_SDMC_AST2600_256MB 0x0
  97. #define ASPEED_SDMC_AST2600_512MB 0x1
  98. #define ASPEED_SDMC_AST2600_1024MB 0x2
  99. #define ASPEED_SDMC_AST2600_2048MB 0x3
  100. #define ASPEED_SDMC_AST2500_READONLY_MASK \
  101. (ASPEED_SDMC_HW_VERSION(0xf) | ASPEED_SDMC_CACHE_INITIAL_DONE | \
  102. ASPEED_SDMC_AST2500_RESERVED | ASPEED_SDMC_VGA_COMPAT | \
  103. ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB))
  104. static uint64_t aspeed_sdmc_read(void *opaque, hwaddr addr, unsigned size)
  105. {
  106. AspeedSDMCState *s = ASPEED_SDMC(opaque);
  107. addr >>= 2;
  108. if (addr >= ARRAY_SIZE(s->regs)) {
  109. qemu_log_mask(LOG_GUEST_ERROR,
  110. "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n",
  111. __func__, addr * 4);
  112. return 0;
  113. }
  114. return s->regs[addr];
  115. }
  116. static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
  117. unsigned int size)
  118. {
  119. AspeedSDMCState *s = ASPEED_SDMC(opaque);
  120. AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
  121. addr >>= 2;
  122. if (addr >= ARRAY_SIZE(s->regs)) {
  123. qemu_log_mask(LOG_GUEST_ERROR,
  124. "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n",
  125. __func__, addr);
  126. return;
  127. }
  128. asc->write(s, addr, data);
  129. }
  130. static const MemoryRegionOps aspeed_sdmc_ops = {
  131. .read = aspeed_sdmc_read,
  132. .write = aspeed_sdmc_write,
  133. .endianness = DEVICE_LITTLE_ENDIAN,
  134. .valid.min_access_size = 4,
  135. .valid.max_access_size = 4,
  136. };
  137. static void aspeed_sdmc_reset(DeviceState *dev)
  138. {
  139. AspeedSDMCState *s = ASPEED_SDMC(dev);
  140. AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
  141. memset(s->regs, 0, sizeof(s->regs));
  142. /* Set ram size bit and defaults values */
  143. s->regs[R_CONF] = asc->compute_conf(s, 0);
  144. /*
  145. * PHY status:
  146. * - set phy status ok (set bit 1)
  147. * - initial PVT calibration ok (clear bit 3)
  148. * - runtime calibration ok (clear bit 5)
  149. */
  150. s->regs[0x100] = BIT(1);
  151. /* PHY eye window: set all as passing */
  152. s->regs[0x100 | (0x68 / 4)] = 0xff;
  153. s->regs[0x100 | (0x7c / 4)] = 0xff;
  154. s->regs[0x100 | (0x50 / 4)] = 0xfffffff;
  155. }
  156. static void aspeed_sdmc_get_ram_size(Object *obj, Visitor *v, const char *name,
  157. void *opaque, Error **errp)
  158. {
  159. AspeedSDMCState *s = ASPEED_SDMC(obj);
  160. int64_t value = s->ram_size;
  161. visit_type_int(v, name, &value, errp);
  162. }
  163. static void aspeed_sdmc_set_ram_size(Object *obj, Visitor *v, const char *name,
  164. void *opaque, Error **errp)
  165. {
  166. int i;
  167. char *sz;
  168. int64_t value;
  169. AspeedSDMCState *s = ASPEED_SDMC(obj);
  170. AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
  171. if (!visit_type_int(v, name, &value, errp)) {
  172. return;
  173. }
  174. for (i = 0; asc->valid_ram_sizes[i]; i++) {
  175. if (value == asc->valid_ram_sizes[i]) {
  176. s->ram_size = value;
  177. return;
  178. }
  179. }
  180. sz = size_to_str(value);
  181. error_setg(errp, "Invalid RAM size %s", sz);
  182. g_free(sz);
  183. }
  184. static void aspeed_sdmc_initfn(Object *obj)
  185. {
  186. object_property_add(obj, "ram-size", "int",
  187. aspeed_sdmc_get_ram_size, aspeed_sdmc_set_ram_size,
  188. NULL, NULL);
  189. }
  190. static void aspeed_sdmc_realize(DeviceState *dev, Error **errp)
  191. {
  192. SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
  193. AspeedSDMCState *s = ASPEED_SDMC(dev);
  194. AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
  195. assert(asc->max_ram_size < 4 * GiB); /* 32-bit address bus */
  196. s->max_ram_size = asc->max_ram_size;
  197. memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_sdmc_ops, s,
  198. TYPE_ASPEED_SDMC, 0x1000);
  199. sysbus_init_mmio(sbd, &s->iomem);
  200. }
  201. static const VMStateDescription vmstate_aspeed_sdmc = {
  202. .name = "aspeed.sdmc",
  203. .version_id = 1,
  204. .minimum_version_id = 1,
  205. .fields = (VMStateField[]) {
  206. VMSTATE_UINT32_ARRAY(regs, AspeedSDMCState, ASPEED_SDMC_NR_REGS),
  207. VMSTATE_END_OF_LIST()
  208. }
  209. };
  210. static Property aspeed_sdmc_properties[] = {
  211. DEFINE_PROP_UINT64("max-ram-size", AspeedSDMCState, max_ram_size, 0),
  212. DEFINE_PROP_END_OF_LIST(),
  213. };
  214. static void aspeed_sdmc_class_init(ObjectClass *klass, void *data)
  215. {
  216. DeviceClass *dc = DEVICE_CLASS(klass);
  217. dc->realize = aspeed_sdmc_realize;
  218. dc->reset = aspeed_sdmc_reset;
  219. dc->desc = "ASPEED SDRAM Memory Controller";
  220. dc->vmsd = &vmstate_aspeed_sdmc;
  221. device_class_set_props(dc, aspeed_sdmc_properties);
  222. }
  223. static const TypeInfo aspeed_sdmc_info = {
  224. .name = TYPE_ASPEED_SDMC,
  225. .parent = TYPE_SYS_BUS_DEVICE,
  226. .instance_size = sizeof(AspeedSDMCState),
  227. .instance_init = aspeed_sdmc_initfn,
  228. .class_init = aspeed_sdmc_class_init,
  229. .class_size = sizeof(AspeedSDMCClass),
  230. .abstract = true,
  231. };
  232. static int aspeed_sdmc_get_ram_bits(AspeedSDMCState *s)
  233. {
  234. AspeedSDMCClass *asc = ASPEED_SDMC_GET_CLASS(s);
  235. int i;
  236. /*
  237. * The bitfield value encoding the RAM size is the index of the
  238. * possible RAM size array
  239. */
  240. for (i = 0; asc->valid_ram_sizes[i]; i++) {
  241. if (s->ram_size == asc->valid_ram_sizes[i]) {
  242. return i;
  243. }
  244. }
  245. /*
  246. * Invalid RAM sizes should have been excluded when setting the
  247. * SoC RAM size.
  248. */
  249. g_assert_not_reached();
  250. }
  251. static uint32_t aspeed_2400_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
  252. {
  253. uint32_t fixed_conf = ASPEED_SDMC_VGA_COMPAT |
  254. ASPEED_SDMC_DRAM_SIZE(aspeed_sdmc_get_ram_bits(s));
  255. /* Make sure readonly bits are kept */
  256. data &= ~ASPEED_SDMC_READONLY_MASK;
  257. return data | fixed_conf;
  258. }
  259. static void aspeed_2400_sdmc_write(AspeedSDMCState *s, uint32_t reg,
  260. uint32_t data)
  261. {
  262. if (reg == R_PROT) {
  263. s->regs[reg] = (data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
  264. return;
  265. }
  266. if (!s->regs[R_PROT]) {
  267. qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
  268. return;
  269. }
  270. switch (reg) {
  271. case R_CONF:
  272. data = aspeed_2400_sdmc_compute_conf(s, data);
  273. break;
  274. default:
  275. break;
  276. }
  277. s->regs[reg] = data;
  278. }
  279. static const uint64_t
  280. aspeed_2400_ram_sizes[] = { 64 * MiB, 128 * MiB, 256 * MiB, 512 * MiB, 0};
  281. static void aspeed_2400_sdmc_class_init(ObjectClass *klass, void *data)
  282. {
  283. DeviceClass *dc = DEVICE_CLASS(klass);
  284. AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass);
  285. dc->desc = "ASPEED 2400 SDRAM Memory Controller";
  286. asc->max_ram_size = 512 * MiB;
  287. asc->compute_conf = aspeed_2400_sdmc_compute_conf;
  288. asc->write = aspeed_2400_sdmc_write;
  289. asc->valid_ram_sizes = aspeed_2400_ram_sizes;
  290. }
  291. static const TypeInfo aspeed_2400_sdmc_info = {
  292. .name = TYPE_ASPEED_2400_SDMC,
  293. .parent = TYPE_ASPEED_SDMC,
  294. .class_init = aspeed_2400_sdmc_class_init,
  295. };
  296. static uint32_t aspeed_2500_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
  297. {
  298. uint32_t fixed_conf = ASPEED_SDMC_HW_VERSION(1) |
  299. ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
  300. ASPEED_SDMC_CACHE_INITIAL_DONE |
  301. ASPEED_SDMC_DRAM_SIZE(aspeed_sdmc_get_ram_bits(s));
  302. /* Make sure readonly bits are kept */
  303. data &= ~ASPEED_SDMC_AST2500_READONLY_MASK;
  304. return data | fixed_conf;
  305. }
  306. static void aspeed_2500_sdmc_write(AspeedSDMCState *s, uint32_t reg,
  307. uint32_t data)
  308. {
  309. if (reg == R_PROT) {
  310. s->regs[reg] = (data == PROT_KEY_UNLOCK) ? PROT_UNLOCKED : PROT_SOFTLOCKED;
  311. return;
  312. }
  313. if (!s->regs[R_PROT]) {
  314. qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked!\n", __func__);
  315. return;
  316. }
  317. switch (reg) {
  318. case R_CONF:
  319. data = aspeed_2500_sdmc_compute_conf(s, data);
  320. break;
  321. case R_STATUS1:
  322. /* Will never return 'busy' */
  323. data &= ~PHY_BUSY_STATE;
  324. break;
  325. case R_ECC_TEST_CTRL:
  326. /* Always done, always happy */
  327. data |= ECC_TEST_FINISHED;
  328. data &= ~ECC_TEST_FAIL;
  329. break;
  330. default:
  331. break;
  332. }
  333. s->regs[reg] = data;
  334. }
  335. static const uint64_t
  336. aspeed_2500_ram_sizes[] = { 128 * MiB, 256 * MiB, 512 * MiB, 1024 * MiB, 0};
  337. static void aspeed_2500_sdmc_class_init(ObjectClass *klass, void *data)
  338. {
  339. DeviceClass *dc = DEVICE_CLASS(klass);
  340. AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass);
  341. dc->desc = "ASPEED 2500 SDRAM Memory Controller";
  342. asc->max_ram_size = 1 * GiB;
  343. asc->compute_conf = aspeed_2500_sdmc_compute_conf;
  344. asc->write = aspeed_2500_sdmc_write;
  345. asc->valid_ram_sizes = aspeed_2500_ram_sizes;
  346. }
  347. static const TypeInfo aspeed_2500_sdmc_info = {
  348. .name = TYPE_ASPEED_2500_SDMC,
  349. .parent = TYPE_ASPEED_SDMC,
  350. .class_init = aspeed_2500_sdmc_class_init,
  351. };
  352. static uint32_t aspeed_2600_sdmc_compute_conf(AspeedSDMCState *s, uint32_t data)
  353. {
  354. uint32_t fixed_conf = ASPEED_SDMC_HW_VERSION(3) |
  355. ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
  356. ASPEED_SDMC_DRAM_SIZE(aspeed_sdmc_get_ram_bits(s));
  357. /* Make sure readonly bits are kept (use ast2500 mask) */
  358. data &= ~ASPEED_SDMC_AST2500_READONLY_MASK;
  359. return data | fixed_conf;
  360. }
  361. static void aspeed_2600_sdmc_write(AspeedSDMCState *s, uint32_t reg,
  362. uint32_t data)
  363. {
  364. /* Unprotected registers */
  365. switch (reg) {
  366. case R_ISR:
  367. case R_MCR6C:
  368. case R_TEST_START_LEN:
  369. case R_TEST_FAIL_DQ:
  370. case R_TEST_INIT_VAL:
  371. case R_DRAM_SW:
  372. case R_DRAM_TIME:
  373. case R_ECC_ERR_INJECT:
  374. s->regs[reg] = data;
  375. return;
  376. }
  377. if (s->regs[R_PROT] == PROT_HARDLOCKED) {
  378. qemu_log_mask(LOG_GUEST_ERROR, "%s: SDMC is locked until system reset!\n",
  379. __func__);
  380. return;
  381. }
  382. if (reg != R_PROT && s->regs[R_PROT] == PROT_SOFTLOCKED) {
  383. qemu_log_mask(LOG_GUEST_ERROR,
  384. "%s: SDMC is locked! (write to MCR%02x blocked)\n",
  385. __func__, reg * 4);
  386. return;
  387. }
  388. switch (reg) {
  389. case R_PROT:
  390. if (data == PROT_KEY_UNLOCK) {
  391. data = PROT_UNLOCKED;
  392. } else if (data == PROT_KEY_HARDLOCK) {
  393. data = PROT_HARDLOCKED;
  394. } else {
  395. data = PROT_SOFTLOCKED;
  396. }
  397. break;
  398. case R_CONF:
  399. data = aspeed_2600_sdmc_compute_conf(s, data);
  400. break;
  401. case R_STATUS1:
  402. /* Will never return 'busy'. 'lock status' is always set */
  403. data &= ~PHY_BUSY_STATE;
  404. data |= PHY_PLL_LOCK_STATUS;
  405. break;
  406. case R_ECC_TEST_CTRL:
  407. /* Always done, always happy */
  408. data |= ECC_TEST_FINISHED;
  409. data &= ~ECC_TEST_FAIL;
  410. break;
  411. default:
  412. break;
  413. }
  414. s->regs[reg] = data;
  415. }
  416. static const uint64_t
  417. aspeed_2600_ram_sizes[] = { 256 * MiB, 512 * MiB, 1024 * MiB, 2048 * MiB, 0};
  418. static void aspeed_2600_sdmc_class_init(ObjectClass *klass, void *data)
  419. {
  420. DeviceClass *dc = DEVICE_CLASS(klass);
  421. AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass);
  422. dc->desc = "ASPEED 2600 SDRAM Memory Controller";
  423. asc->max_ram_size = 2 * GiB;
  424. asc->compute_conf = aspeed_2600_sdmc_compute_conf;
  425. asc->write = aspeed_2600_sdmc_write;
  426. asc->valid_ram_sizes = aspeed_2600_ram_sizes;
  427. }
  428. static const TypeInfo aspeed_2600_sdmc_info = {
  429. .name = TYPE_ASPEED_2600_SDMC,
  430. .parent = TYPE_ASPEED_SDMC,
  431. .class_init = aspeed_2600_sdmc_class_init,
  432. };
  433. static void aspeed_sdmc_register_types(void)
  434. {
  435. type_register_static(&aspeed_sdmc_info);
  436. type_register_static(&aspeed_2400_sdmc_info);
  437. type_register_static(&aspeed_2500_sdmc_info);
  438. type_register_static(&aspeed_2600_sdmc_info);
  439. }
  440. type_init(aspeed_sdmc_register_types);