spinand_acts.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896
  1. /*
  2. * Copyright (c) 2018 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. //#define DT_DRV_COMPAT actions_acts_flash
  7. #include <errno.h>
  8. #include <disk/disk_access.h>
  9. #include "spinand_acts.h"
  10. #include <drivers/spinand.h>
  11. #include <board.h>
  12. #ifdef CONFIG_ACTS_DVFS_DYNAMIC_LEVEL
  13. #include <dvfs.h>
  14. #endif
  15. #ifdef CONFIG_BOARD_NANDBOOT
  16. #define TRY_DELAYCHAIN 40
  17. #else
  18. #define TRY_DELAYCHAIN 20
  19. #endif
  20. #define ID_TBL_MAGIC 0x53648673
  21. #define ID_TBL_ADDR soc_boot_get_nandid_tbl_addr()
  22. #define STA_NODISK 0x02 /* No medium in the drive */
  23. #define STA_DISK_OK 0x08 /* Medium OK in the drive */
  24. #define LIB_LOG_LEVEL WARN_LEVEL
  25. #define HEAP_SIZE (14*1024)
  26. uint32_t api_bss[HEAP_SIZE/4];
  27. struct k_mutex mutex;
  28. static struct k_sem checkrb_sem;
  29. #define SECTOR_SIZE 512
  30. #include <logging/log.h>
  31. LOG_MODULE_REGISTER(spinand_acts, CONFIG_FLASH_LOG_LEVEL);
  32. #define LOG printk
  33. //#define LOG LOG_INF
  34. #ifndef CONFIG_SPINAND_DATA
  35. #define CONFIG_SPINAND_DATA 1
  36. #endif
  37. static bool spinand_initial;
  38. static bool spinand_resume;
  39. static bool spinand_poweroff;
  40. static u32_t start_cycle;
  41. #ifndef CONFIG_SPINAND_POWER_CONTROL_SECONDS
  42. #ifdef CONFIG_SPINAND_TEST_FRAMEWORKS
  43. #define CONFIG_SPINAND_POWER_CONTROL_SECONDS 0
  44. #else
  45. #define CONFIG_SPINAND_POWER_CONTROL_SECONDS 5
  46. #endif
  47. #endif
  48. #ifdef CONFIG_PM_DEVICE
  49. K_THREAD_STACK_DEFINE(spinand_workq_stack, 1024);
  50. struct k_work_q spinand_workq;
  51. struct k_delayed_work power_control;
  52. int spinand_resume_init(struct spinand_info *sni);
  53. void spinand_workqueue_poweroff(struct k_work *work);
  54. #endif
  55. void set_spinand_spimfp();
  56. static uint8_t spinand_dvfs_clk;
  57. static uint32_t spinand_max_sectors;
  58. void *spinand_panic(const char *fmt, void *sni)
  59. {
  60. #ifdef CONFIG_SPINAND_LIB
  61. //spinand_dump_zoneinfo((struct spinand_info *)sni);
  62. #endif
  63. LOG("%s\n", fmt);
  64. k_panic();
  65. return NULL;
  66. }
  67. void *spinand_checkrb_sem(void *sni)
  68. {
  69. k_sem_take(&checkrb_sem, K_FOREVER);
  70. return NULL;
  71. }
  72. static struct nand_info system_spinand = {
  73. .base = SPI0_REG_BASE+(0x4000*CONFIG_SPINAND_USE_SPICONTROLER),
  74. .bus_width = CONFIG_SPINAND_FLASH_BUS_WIDTH,
  75. .delay_chain = 0,
  76. .spi_mode = 3,
  77. .data = CONFIG_SPINAND_DATA,
  78. .dma_base = DMA_REG_BASE+0x100+(CONFIG_DMA_SPINAND_RESEVER_CHAN*0x100), //DMA9
  79. .printf = (void *)printk,
  80. .loglevel = LIB_LOG_LEVEL,
  81. .panic = (void *)spinand_panic,
  82. //.checkrb_sem = (void *)spinand_checkrb_sem,
  83. };
  84. static struct spinand_info spinand_acts_data = {
  85. .protect = 1,
  86. };
  87. #ifdef CONFIG_ACTIONS_PRINTK_DMA
  88. extern int check_panic_exe(void);
  89. #endif
  90. static int spinand_not_allow_operate(void)
  91. {
  92. #ifdef CONFIG_ACTIONS_PRINTK_DMA
  93. if (k_is_in_isr() && !check_panic_exe()) {
  94. printk("spinand not allow write in irq\n");
  95. k_panic();
  96. return 1;
  97. }
  98. #endif
  99. return 0;
  100. }
  101. static void spinand_lock(void)
  102. {
  103. if (!k_is_in_isr()){
  104. k_mutex_lock(&mutex, K_FOREVER);
  105. }
  106. }
  107. static void spinand_unlock(void)
  108. {
  109. if (!k_is_in_isr()){
  110. k_mutex_unlock(&mutex);
  111. }
  112. }
  113. static int spinand_acts_read(const struct device *dev, uint64_t offset, void *data, uint64_t len)
  114. {
  115. if (((offset % 512) != 0) || ((len % 512 != 0))) {
  116. LOG("offset=0x%x; len=0x%x not sector align.\n", (u32_t)offset, (u32_t)len);
  117. return -1;
  118. }
  119. if (spinand_not_allow_operate()) {
  120. return -1;
  121. }
  122. spinand_lock();
  123. struct spinand_info *sni = &spinand_acts_data;
  124. int ret = 0;
  125. offset >>= 9;
  126. len >>= 9;
  127. #ifdef CONFIG_PM_DEVICE
  128. start_cycle = k_cycle_get_32();
  129. if (spinand_resume) {
  130. ret = spinand_resume_init(sni);
  131. if (ret != 0) {
  132. LOG("spinand resume err, spinand read err!\n");
  133. spinand_unlock();
  134. return ret;
  135. }
  136. }
  137. #endif
  138. if (!spinand_initial) {
  139. LOG("%s spinand init failed, please check...\n", __func__);
  140. spinand_unlock();
  141. return -1;
  142. }
  143. //printk("read offset = %d; len = %d;\n", offset, len);
  144. if ((offset + len) > spinand_max_sectors) {
  145. LOG("%s error! read from 0x%x len 0x%llx excceed storage capacity 0x%x.\n", __func__, (s32_t)offset, len, spinand_max_sectors);
  146. spinand_unlock();
  147. return -1;
  148. }
  149. #ifndef CONFIG_SPINAND_LIB
  150. ret = p_spinand_api->read(sni, offset, data, len);
  151. #else
  152. ret = spinand_read(sni, offset, data, len);
  153. #endif
  154. spinand_unlock();
  155. return ret;
  156. }
  157. static int spinand_acts_write(const struct device *dev, uint64_t offset, const void *data, uint64_t len)
  158. {
  159. if (((offset % 512) != 0) || ((len % 512 != 0))) {
  160. LOG("offset=0x%x; len=0x%x not sector align.\n", (u32_t)offset, (u32_t)len);
  161. return -1;
  162. }
  163. if (spinand_not_allow_operate()) {
  164. return -1;
  165. }
  166. spinand_lock();
  167. struct spinand_info *sni = &spinand_acts_data;
  168. int ret = 0;
  169. offset >>= 9;
  170. len >>= 9;
  171. #ifdef CONFIG_PM_DEVICE
  172. start_cycle = k_cycle_get_32();
  173. if (spinand_resume) {
  174. ret = spinand_resume_init(sni);
  175. if (ret != 0) {
  176. LOG("spinand resume err, spinand write err!\n");
  177. spinand_unlock();
  178. return ret;
  179. }
  180. }
  181. #endif
  182. if (!spinand_initial) {
  183. LOG("%s spinand init failed, please check...\n", __func__);
  184. spinand_unlock();
  185. return -1;
  186. }
  187. //printk("write offset = %d; len = %d;\n", offset, len);
  188. if ((offset + len) > spinand_max_sectors) {
  189. LOG("%s error! write from 0x%x len 0x%llx excceed storage capacity 0x%x.\n", __func__, (s32_t)offset, len, spinand_max_sectors);
  190. spinand_unlock();
  191. return -1;
  192. }
  193. #ifndef CONFIG_SPINAND_LIB
  194. ret = p_spinand_api->write(sni, offset, data, len);
  195. #else
  196. ret = spinand_write(sni, offset, data, len);
  197. #endif
  198. spinand_unlock();
  199. return ret;
  200. }
  201. static int spinand_acts_erase(const struct device *dev, uint64_t offset, uint64_t size)
  202. {
  203. if (((offset % 512) != 0) || ((size % 512 != 0))) {
  204. LOG("offset=0x%x; len=0x%x not sector align.\n", (u32_t)offset, (u32_t)size);
  205. return -1;
  206. }
  207. if (spinand_not_allow_operate()) {
  208. return -1;
  209. }
  210. spinand_lock();
  211. struct spinand_info *sni = &spinand_acts_data;
  212. int ret = 0;
  213. offset >>= 9;
  214. size >>= 9;
  215. #ifdef CONFIG_PM_DEVICE
  216. start_cycle = k_cycle_get_32();
  217. if (spinand_resume) {
  218. ret = spinand_resume_init(sni);
  219. if (ret != 0) {
  220. LOG("spinand resume err, spinand erase err!\n");
  221. spinand_unlock();
  222. return ret;
  223. }
  224. }
  225. #endif
  226. if (!spinand_initial) {
  227. LOG("%s spinand init failed, please check...\n", __func__);
  228. spinand_unlock();
  229. return -1;
  230. }
  231. printk("erase offset = %d; len = %lld;\n", (s32_t)offset, size);
  232. #ifndef CONFIG_SPINAND_LIB
  233. ret = p_spinand_api->erase(sni, offset, size);
  234. #else
  235. ret = spinand_erase(sni, offset, size);
  236. #endif
  237. spinand_unlock();
  238. return ret;
  239. }
  240. static int spinand_acts_flush(const struct device *dev, bool efficient)
  241. {
  242. if (spinand_not_allow_operate()) {
  243. return -1;
  244. }
  245. spinand_lock();
  246. //offset, len shuold align with 512B.
  247. struct spinand_info *sni = &spinand_acts_data;
  248. int ret = 0;
  249. #ifdef CONFIG_PM_DEVICE
  250. start_cycle = k_cycle_get_32();
  251. if (spinand_resume) {
  252. ret = spinand_resume_init(sni);
  253. if (ret != 0) {
  254. LOG("spinand resume err, spinand flush err!\n");
  255. spinand_unlock();
  256. return ret;
  257. }
  258. }
  259. #endif
  260. if (!spinand_initial) {
  261. LOG("%s spinand init failed, please check...\n", __func__);
  262. spinand_unlock();
  263. return -1;
  264. }
  265. #ifndef CONFIG_SPINAND_LIB
  266. ret = p_spinand_api->flush(sni);
  267. #else
  268. ret = spinand_flush(sni, efficient);
  269. #endif
  270. spinand_unlock();
  271. return ret;
  272. }
  273. void spinand_change_print_level(const struct device *dev, u8_t level)
  274. {
  275. struct spinand_info *sni = DEV_DATA(dev);
  276. LOG("spinand print level change from %d to %d.\n", sni->spi->loglevel, level);
  277. sni->spi->loglevel = level;
  278. }
  279. int get_storage_params(struct spinand_info *sni, u8_t *id, struct FlashChipInfo **ChipInfo)
  280. {
  281. int i, j;
  282. struct NandIdTblHeader *id_tbl_header = (struct NandIdTblHeader *)sni->id_tbl;
  283. struct FlashChipInfo *id_tbl = (struct FlashChipInfo *)((uint8_t *)sni->id_tbl + sizeof(struct NandIdTblHeader));
  284. if (id_tbl_header->magic != ID_TBL_MAGIC)
  285. {
  286. LOG("id tbl magic err! 0x%x \n", id_tbl_header->magic);
  287. return -1;
  288. }
  289. for (i = 0; i < id_tbl_header->num; i++)
  290. {
  291. for (j = 0; j < NAND_CHIPID_LENGTH / 2; j++)
  292. {
  293. /* skip compare the 0xff value */
  294. if ((id_tbl[i].ChipID[j] != 0xff) && (id_tbl[i].ChipID[j] != id[j]))
  295. {
  296. //LOG("id not match; id_tbl[%d].ChipID[%d] = 0x%x; id[%d] = 0x%x\n", i, j, id_tbl[i].ChipID[j], j, id[j]);
  297. break;
  298. }
  299. //LOG("id match; id_tbl[%d].ChipID[%d] = 0x%x; id[%d] = 0x%x\n", i, j, id_tbl[i].ChipID[j], j, id[j]);
  300. }
  301. if (j == NAND_CHIPID_LENGTH / 2)
  302. {
  303. *ChipInfo = &id_tbl[i];
  304. //LOG("get chipinfo.\n");
  305. return 0;
  306. }
  307. }
  308. LOG("spinand id not match, please check!\n");
  309. return -1;
  310. }
  311. int spinand_get_chipid(struct spinand_info *sni, u32_t *chipid)
  312. {
  313. int i = 0;
  314. struct FlashChipInfo *NandFlashInfo;
  315. retry:
  316. #ifndef CONFIG_SPINAND_LIB
  317. *chipid = p_spinand_api->read_chipid(sni);
  318. #else
  319. *chipid = spinand_read_chipid(sni);
  320. #endif
  321. //LOG("nand id = 0x%x\n", *chipid);
  322. if (*chipid == 0x0 || *chipid == 0xffffffff) {
  323. if (i++ < 3) {
  324. LOG("Can't get spinand id, retry %d...\n", i);
  325. goto retry;
  326. } else {
  327. LOG("Can't get spinand id, Please check!\n");
  328. return -1;
  329. }
  330. }
  331. if (get_storage_params(sni, (u8_t *)chipid, &NandFlashInfo) != 0) {
  332. LOG("Get chipid = 0x%x; But Can't get this chipid in idtbl.\n", *chipid);
  333. return -1;
  334. }
  335. return 0;
  336. }
  337. int spinand_get_delaychain(struct spinand_info *sni)
  338. {
  339. uint32_t chipid = 0;
  340. struct FlashChipInfo *NandFlashInfo;
  341. uint8_t t_dc = 0;
  342. int ret = 0;
  343. t_dc = sni->spi->delay_chain;
  344. sni->spi->delay_chain = TRY_DELAYCHAIN;
  345. ret = spinand_get_chipid(sni, &chipid);
  346. sni->spi->delay_chain = t_dc;
  347. if (ret != 0) {
  348. LOG("spinand get chipid err!\n");
  349. return -EINVAL;
  350. }
  351. if (get_storage_params(sni, (u8_t *)&chipid, &NandFlashInfo) != 0) {
  352. LOG("Can't get flashinfo.\n");
  353. return -1;
  354. }
  355. LOG("spinand chipid: 0x%x; chipname: %s \n", chipid, NandFlashInfo->FlashMark);
  356. return NandFlashInfo->delayChain;
  357. }
  358. uint32_t spinand_get_storage_capacity(struct spinand_info *sni)
  359. {
  360. uint32_t chipid = 0;
  361. uint32_t max_sectors = 0;
  362. uint32_t zone_num = 0;
  363. struct FlashChipInfo *NandFlashInfo;
  364. if (spinand_get_chipid(sni, &chipid) != 0) {
  365. LOG("spinand get chipid err!\n");
  366. return 0;
  367. }
  368. if (get_storage_params(sni, (u8_t *)&chipid, &NandFlashInfo) != 0) {
  369. LOG("Can't get flashinfo.\n");
  370. return 0;
  371. }
  372. zone_num = NandFlashInfo->TotalBlkNumPerDie / NandFlashInfo->DefaultLBlkNumPer1024Blk;
  373. max_sectors = zone_num * NandFlashInfo->DefaultLBlkNumPer1024Blk * NandFlashInfo->SectorNumPerPage * NandFlashInfo->PageNumPerPhyBlk;
  374. return max_sectors;
  375. }
  376. int spinand_storage_ioctl(const struct device *dev, uint8_t cmd, void *buff)
  377. {
  378. spinand_lock();
  379. struct spinand_info *sni = &spinand_acts_data;
  380. uint32_t chipid = 0;
  381. int ret;
  382. #ifdef CONFIG_PM_DEVICE
  383. start_cycle = k_cycle_get_32();
  384. if (spinand_resume) {
  385. ret = spinand_resume_init(sni);
  386. if (ret != 0) {
  387. LOG("spinand resume err, spinand ioctl err!\n");
  388. spinand_unlock();
  389. return ret;
  390. }
  391. }
  392. #endif
  393. if (!spinand_initial) {
  394. LOG("%s spinand init failed, please check...\n", __func__);
  395. spinand_unlock();
  396. return -1;
  397. }
  398. switch (cmd) {
  399. case DISK_IOCTL_CTRL_SYNC:
  400. spinand_acts_flush(dev, 1);
  401. break;
  402. case DISK_IOCTL_GET_SECTOR_COUNT:
  403. if (spinand_max_sectors == 0) {
  404. LOG("Can't get spinand storage capacity.\n");
  405. spinand_unlock();
  406. return -1;
  407. }
  408. *(uint32_t *)buff = spinand_max_sectors;
  409. break;
  410. case DISK_IOCTL_GET_SECTOR_SIZE:
  411. *(uint32_t *)buff = SECTOR_SIZE;
  412. break;
  413. case DISK_IOCTL_GET_ERASE_BLOCK_SZ:
  414. *(uint32_t *)buff = SECTOR_SIZE;
  415. break;
  416. case DISK_IOCTL_HW_DETECT:
  417. if (spinand_get_chipid(sni, &chipid) != 0) {
  418. *(uint8_t *)buff = STA_NODISK;
  419. } else {
  420. *(uint8_t *)buff = STA_DISK_OK;
  421. }
  422. break;
  423. default:
  424. spinand_unlock();
  425. return -EINVAL;
  426. }
  427. spinand_unlock();
  428. return 0;
  429. }
  430. static int spinand_env_init(struct spinand_info *sni)
  431. {
  432. uint8_t feture;
  433. uint32_t chipid = 0;
  434. int delay_chain = 0;
  435. uint8_t max_delaychain;
  436. /* enable spi controller clock */
  437. acts_clock_peripheral_enable(CLOCK_ID_SPI0+CONFIG_SPINAND_USE_SPICONTROLER);
  438. /* reset spi controller */
  439. acts_reset_peripheral(RESET_ID_SPI0+CONFIG_SPINAND_USE_SPICONTROLER);
  440. set_spinand_spimfp();
  441. //LOG("GOIO64 = 0x%x \n", sys_read32(0x40068100));
  442. /* setup SPI clock rate to 32MHz, use a lower clk to try chipid and capacity.*/
  443. clk_set_rate(CLOCK_ID_SPI0+CONFIG_SPINAND_USE_SPICONTROLER, MHZ(32));
  444. if (sni->spi->delay_chain == 0) {
  445. delay_chain = spinand_get_delaychain(sni);
  446. if (CONFIG_SPINAND_USE_SPICONTROLER == 0)
  447. max_delaychain = 63;
  448. else
  449. max_delaychain = 31;
  450. if (delay_chain < 0 || delay_chain > max_delaychain) {
  451. LOG("spinand get delaychain failed!\n");
  452. return -1;
  453. }
  454. sni->spi->delay_chain = delay_chain;
  455. //sni->spi->delay_chain = 0;
  456. LOG("spinand set delaychain %d.\n", sni->spi->delay_chain);
  457. } else {
  458. LOG("spinand set delaychain %d.\n", sni->spi->delay_chain);
  459. }
  460. if (spinand_get_chipid(sni, &chipid) != 0) {
  461. return -1;
  462. }
  463. spinand_max_sectors = spinand_get_storage_capacity(sni);
  464. if (spinand_max_sectors == 0) {
  465. LOG("spinand get storage capacity failed!\n");
  466. return -1;
  467. }
  468. LOG("spinand contain sectors 0x%x.\n", spinand_max_sectors);
  469. /* setup SPI clock rate */
  470. clk_set_rate(CLOCK_ID_SPI0+CONFIG_SPINAND_USE_SPICONTROLER, MHZ(spinand_dvfs_clk));
  471. //if use 4xIO, SIO2 & SIO3 do not need pull up, otherwise, SIO2 & SIO3 need setting pull up.
  472. if (sni->spi->bus_width == 4) {
  473. LOG("spinand use 4xIO.\n");
  474. #ifndef CONFIG_SPINAND_LIB
  475. feture = p_spinand_api->spinand_get_feature(sni, 0xB0);
  476. p_spinand_api->spinand_set_feature(sni, 0xB0, feture | 0x1);
  477. #else
  478. feture = spinand_get_feature(sni, 0xB0);
  479. spinand_set_feature(sni, 0xB0, feture | 0x1);
  480. #endif
  481. } else {
  482. LOG("spinand use 1xIO.\n");
  483. }
  484. //Compatible for HYF1GQ4UT.
  485. if (chipid == 0x15011501) {
  486. #ifdef SPINAND_ROM
  487. p_spinand_api->spinand_set_feature(sni, 0xA0, 0x2);
  488. #else
  489. spinand_set_feature(sni, 0xA0, 0x2);
  490. #endif
  491. }
  492. //For debug only.
  493. if (0) {
  494. LOG("MRCR0 = 0x%x \n", sys_read32(RMU_MRCR0));
  495. //bit7 for spi3
  496. LOG("CMU_DEVCKEN0 = 0x%x \n", sys_read32(CMU_DEVCLKEN0));
  497. LOG("CORE_PLL = 0x%x \n", sys_read32(COREPLL_CTL));
  498. LOG("SPI3CLK = 0x%x \n", sys_read32(CMU_SPI3CLK));
  499. LOG("GOIO64 = 0x%x \n", sys_read32(0x40068100));
  500. struct board_pinmux_info pinmux_info;
  501. board_get_spinand_pinmux_info(&pinmux_info);
  502. int i;
  503. LOG("spinand pinctrl list:\n");
  504. for (i = 0; i < pinmux_info.pins_num; i++) {
  505. LOG("GPIO%d = 0x%x\n", pinmux_info.pins_config[i].pin_num, pinmux_info.pins_config[i].mode);
  506. }
  507. }
  508. return 0;
  509. }
  510. #ifdef CONFIG_ACTS_DVFS_DYNAMIC_LEVEL
  511. __dvfs_notifier_func static void spinand_dvfs_notify(void *user_data, struct dvfs_freqs *dvfs_freq)
  512. {
  513. struct dvfs_level *old_dvfs_level, *new_dvfs_level;
  514. if (!dvfs_freq) {
  515. LOG("dvfs notify invalid param");
  516. return ;
  517. }
  518. if (dvfs_freq->old_level == dvfs_freq->new_level)
  519. return;
  520. old_dvfs_level = dvfs_get_info_by_level_id(dvfs_freq->old_level);
  521. new_dvfs_level = dvfs_get_info_by_level_id(dvfs_freq->new_level);
  522. if (old_dvfs_level->vdd_volt == new_dvfs_level->vdd_volt) {
  523. return;
  524. }
  525. if (dvfs_freq->state == DVFS_EVENT_PRE_CHANGE) {
  526. spinand_lock();
  527. }
  528. if (old_dvfs_level->vdd_volt > new_dvfs_level->vdd_volt) {
  529. /* vdd voltage decrease */
  530. if (dvfs_freq->state == DVFS_EVENT_PRE_CHANGE) {
  531. if (new_dvfs_level->vdd_volt >= 1100){
  532. clk_set_rate(CLOCK_ID_SPI0+CONFIG_SPINAND_USE_SPICONTROLER, MHZ(CONFIG_SPINAND_FLASH_FREQ_MHZ));
  533. spinand_dvfs_clk = CONFIG_SPINAND_FLASH_FREQ_MHZ;
  534. } else {
  535. clk_set_rate(CLOCK_ID_SPI0+CONFIG_SPINAND_USE_SPICONTROLER, MHZ(64));
  536. spinand_dvfs_clk = 64;
  537. }
  538. }
  539. } else {
  540. /* vdd voltage increase */
  541. if (dvfs_freq->state == DVFS_EVENT_POST_CHANGE) {
  542. if (new_dvfs_level->vdd_volt >= 1100){
  543. clk_set_rate(CLOCK_ID_SPI0+CONFIG_SPINAND_USE_SPICONTROLER, MHZ(CONFIG_SPINAND_FLASH_FREQ_MHZ));
  544. spinand_dvfs_clk = CONFIG_SPINAND_FLASH_FREQ_MHZ;
  545. } else {
  546. clk_set_rate(CLOCK_ID_SPI0+CONFIG_SPINAND_USE_SPICONTROLER, MHZ(64));
  547. spinand_dvfs_clk = 64;
  548. }
  549. }
  550. }
  551. if (dvfs_freq->state == DVFS_EVENT_POST_CHANGE) {
  552. spinand_unlock();
  553. }
  554. LOG("spi%dclk update by vdd:%d => %d \n",
  555. CONFIG_SPINAND_USE_SPICONTROLER, old_dvfs_level->vdd_volt, new_dvfs_level->vdd_volt);
  556. }
  557. static struct dvfs_notifier __dvfs_notifier_data spinand_dvfs_notifier = {
  558. .dvfs_notify_func_t = spinand_dvfs_notify,
  559. .user_data = NULL,
  560. };
  561. #endif
  562. void set_spinand_gpiohighz()
  563. {
  564. struct board_pinmux_info pinmux_info;
  565. board_get_spinand_gpiohighz_info(&pinmux_info);
  566. acts_pinmux_setup_pins(pinmux_info.pins_config, pinmux_info.pins_num);
  567. }
  568. void set_spinand_spimfp()
  569. {
  570. struct board_pinmux_info pinmux_info;
  571. board_get_spinand_pinmux_info(&pinmux_info);
  572. acts_pinmux_setup_pins(pinmux_info.pins_config, pinmux_info.pins_num);
  573. // wait for power Stable
  574. k_msleep(4);
  575. }
  576. static void spi_isr(void *arg)
  577. {
  578. struct k_sem *sem = (struct k_sem *)arg;
  579. //clear checkrb isr pending
  580. if (CONFIG_SPINAND_USE_SPICONTROLER == 0) {
  581. sys_write32(sys_read32(SPI0_REG_BASE + 0x1c) | (1 << 7), SPI0_REG_BASE + 0x1c);
  582. } else {
  583. sys_write32(sys_read32(SPI0_REG_BASE+(0x4000*CONFIG_SPINAND_USE_SPICONTROLER) + 0x18) | (1 << 7), SPI0_REG_BASE+(0x4000*CONFIG_SPINAND_USE_SPICONTROLER) + 0x18);
  584. }
  585. k_sem_give(sem);
  586. }
  587. static int spinand_acts_init(const struct device *dev)
  588. {
  589. int ret = 0;
  590. //const struct spinand_acts_config *config = DEV_CFG(dev);
  591. struct spinand_info *sni = &spinand_acts_data;
  592. sni->bss = api_bss;
  593. memset(sni->bss, 0x0, HEAP_SIZE);
  594. sni->id_tbl = (void *)soc_boot_get_nandid_tbl_addr();
  595. sni->spi = &system_spinand;
  596. spinand_initial = false;
  597. spinand_resume = false;
  598. spinand_poweroff = false;
  599. //default clk is 96MHz.
  600. spinand_dvfs_clk = CONFIG_SPINAND_FLASH_FREQ_MHZ;
  601. if (sni->spi->checkrb_sem != NULL) {
  602. //sys_write32(sys_read32(NVIC_ISER0) | (1 << 15), NVIC_ISER0);
  603. k_sem_init(&checkrb_sem, 0, 1);
  604. IRQ_CONNECT(IRQ_ID_SPI0+CONFIG_SPINAND_USE_SPICONTROLER, CONFIG_SPI_3_IRQ_PRI,
  605. spi_isr, &checkrb_sem, 0);
  606. irq_enable(IRQ_ID_SPI0+CONFIG_SPINAND_USE_SPICONTROLER);
  607. //LOG("NVIC_ISER0 = 0x%x \n", sys_read32(NVIC_ISER0));
  608. }
  609. set_spinand_gpiohighz();
  610. if (spinand_env_init(sni) != 0) {
  611. LOG("spinand env init err.\n");
  612. return -1;
  613. }
  614. #ifndef CONFIG_SPINAND_LIB
  615. ret = p_spinand_api->init(sni);
  616. #else
  617. //LOG("spinand version %s \n", spinand_get_version());
  618. ret = spinand_init(sni);
  619. #endif
  620. if (ret != 0) {
  621. LOG("SPINand rom driver init err.\n");
  622. return -1;
  623. }
  624. k_mutex_init(&mutex);
  625. #ifdef CONFIG_ACTS_DVFS_DYNAMIC_LEVEL
  626. dvfs_register_notifier(&spinand_dvfs_notifier);
  627. #endif
  628. #ifdef CONFIG_PM_DEVICE
  629. k_work_queue_start(&spinand_workq, spinand_workq_stack, K_THREAD_STACK_SIZEOF(spinand_workq_stack), 7, NULL);
  630. start_cycle = k_cycle_get_32();
  631. k_delayed_work_init(&power_control, spinand_workqueue_poweroff);
  632. k_delayed_work_submit_to_queue(&spinand_workq, &power_control, K_MSEC(1000));
  633. #endif
  634. spinand_initial = true;
  635. return 0;
  636. }
  637. #ifdef CONFIG_PM_DEVICE
  638. static u32_t bss_checksum;
  639. #define CHECKSUM_XOR_VALUE 0xaa55
  640. u32_t spinand_checksum(u32_t *buf, u32_t len)
  641. {
  642. u32_t i;
  643. u32_t sum = 0;
  644. for (i = 0; i < len; i++)
  645. {
  646. sum += buf[i];
  647. }
  648. sum ^= (uint16_t)CHECKSUM_XOR_VALUE;
  649. return sum;
  650. }
  651. void spinand_workqueue_poweroff(struct k_work *work)
  652. {
  653. if (CONFIG_SPINAND_POWER_CONTROL_SECONDS == 0) {
  654. LOG("spinand no need cycle power off ...\n");
  655. return;
  656. }
  657. spinand_lock();
  658. u32_t time_interval = k_cyc_to_ms_floor32(k_cycle_get_32() - start_cycle);
  659. //LOG("spinand check time_interval %u\n", time_interval);
  660. if (time_interval >= CONFIG_SPINAND_POWER_CONTROL_SECONDS * 1000 && !spinand_poweroff) {
  661. LOG("spinand power off ...\n");
  662. set_spinand_gpiohighz();
  663. spinand_poweroff = true;
  664. //set resume flag for later poweron.
  665. spinand_resume = true;
  666. spinand_initial = false;
  667. bss_checksum = spinand_checksum(api_bss, sizeof(api_bss)/4);
  668. spinand_unlock();
  669. return ;
  670. }
  671. k_delayed_work_submit_to_queue(&spinand_workq, &power_control, K_MSEC(1000));
  672. spinand_unlock();
  673. }
  674. int spinand_resume_init(struct spinand_info *sni)
  675. {
  676. int ret = 0;
  677. u32_t start = k_cycle_get_32();
  678. if (spinand_poweroff) {
  679. LOG("spinand power on ...\n");
  680. u32_t tmp_cksum = spinand_checksum(api_bss, sizeof(api_bss)/4);
  681. if (bss_checksum != tmp_cksum) {
  682. LOG("SPINand resume err! api_bss is changed! suspend_checksum = 0x%x; resume_checksum = 0x%x \n", bss_checksum, tmp_cksum);
  683. return -1;
  684. }
  685. spinand_poweroff = false;
  686. k_delayed_work_submit_to_queue(&spinand_workq, &power_control, K_MSEC(1000));
  687. }
  688. if (spinand_env_init(sni) != 0) {
  689. LOG("spinand env init err.\n");
  690. return -1;
  691. }
  692. #ifndef CONFIG_SPINAND_LIB
  693. ret = p_spinand_api->init(sni);
  694. #else
  695. ret = spinand_pdl_init(sni);
  696. #endif
  697. if (ret != 0) {
  698. LOG("SPINand rom driver init err.\n");
  699. return -1;
  700. }
  701. if (spinand_resume)
  702. spinand_resume = false;
  703. spinand_initial = true;
  704. LOG("spinand power on time cost (us)=%u\n", k_cyc_to_us_floor32(k_cycle_get_32() - start));
  705. return ret;
  706. }
  707. int spinand_pm_control(const struct device *device, enum pm_device_action action)
  708. {
  709. int ret;
  710. u32_t tmp_cksum;
  711. //struct spinand_info *sni = &spinand_acts_data;
  712. switch (action) {
  713. case PM_DEVICE_ACTION_RESUME:
  714. LOG("spinand resume ...\n");
  715. tmp_cksum = spinand_checksum(api_bss, sizeof(api_bss)/4);
  716. if (bss_checksum != tmp_cksum) {
  717. LOG("SPINand resume err! api_bss is changed! suspend_checksum = 0x%x; resume_checksum = 0x%x \n", bss_checksum, tmp_cksum);
  718. return -1;
  719. }
  720. //LOG("resume_checksum = 0x%x; sizeof(api_bss) = 0x%x \n", tmp_cksum, sizeof(api_bss));
  721. spinand_resume = true;
  722. break;
  723. case PM_DEVICE_ACTION_SUSPEND:
  724. if (mutex.lock_count != 0U) {
  725. LOG("spinand is using, can't suspend ...\n");
  726. return -1;
  727. }
  728. LOG("spinand suspend ...\n");
  729. set_spinand_gpiohighz();
  730. bss_checksum = spinand_checksum(api_bss, sizeof(api_bss)/4);
  731. //LOG("suspend_checksum = 0x%x; sizeof(api_bss) = 0x%x \n", bss_checksum, sizeof(api_bss));
  732. break;
  733. case PM_DEVICE_ACTION_EARLY_SUSPEND:
  734. break;
  735. case PM_DEVICE_ACTION_LATE_RESUME:
  736. break;
  737. case PM_DEVICE_ACTION_TURN_OFF:
  738. //flush all data to spinand.
  739. spinand_acts_flush(device, 0);
  740. break;
  741. default:
  742. ret = -EINVAL;
  743. }
  744. return 0;
  745. }
  746. #else
  747. #define adc_pm_control NULL
  748. #endif
  749. static struct flash_driver_api spinand_api = {
  750. .read = spinand_acts_read,
  751. .write = spinand_acts_write,
  752. .erase = spinand_acts_erase,
  753. .write_protection = NULL,
  754. .flush = spinand_acts_flush,
  755. };
  756. #define SPINAND_ACTS_DEVICE_INIT(n) \
  757. DEVICE_DEFINE(spinand, CONFIG_SPINAND_FLASH_NAME, \
  758. &spinand_acts_init, spinand_pm_control, \
  759. &spinand_acts_data, NULL, POST_KERNEL, \
  760. CONFIG_KERNEL_INIT_PRIORITY_OBJECTS, &spinand_api);
  761. #if IS_ENABLED(CONFIG_SPINAND_3) || IS_ENABLED(CONFIG_SPINAND_0)
  762. SPINAND_ACTS_DEVICE_INIT(3)
  763. #endif