aspeed_sdmc.c 15 KB

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