aspeed_sdmc.c 13 KB

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