spi.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2021. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #include <spi.h>
  32. #include <malloc.h>
  33. #include <libfdt.h>
  34. #include <lk_builtin_dtb.h>
  35. static struct mtk_spi_bus *spi_bus[BUS_COUNT] = { NULL };
  36. static int spi_bus_num = -1;
  37. static struct mtk_spi_bus_config spi_default_config = {
  38. .spi_mode = 0,
  39. .tick_delay = 0,
  40. };
  41. static void mtk_spi_reset(int bus_num)
  42. {
  43. u32 reg_val;
  44. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  45. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  46. reg_val |= 1 << SPI_CMD_RST_SHIFT;
  47. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  48. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  49. reg_val &= ~(1 << SPI_CMD_RST_SHIFT);
  50. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  51. spi_bus[bus_num]->state = MTK_SPI_IDLE;
  52. }
  53. static void mtk_spi_set_cs(int bus_num, bool enable)
  54. {
  55. u32 reg_val;
  56. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  57. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  58. if (!enable) {
  59. reg_val |= 1 << SPI_CMD_PAUSE_EN_SHIFT;
  60. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  61. spi_bus[bus_num]->state = MTK_SPI_PAUSE_IDLE;
  62. } else {
  63. reg_val &= ~(1 << SPI_CMD_PAUSE_EN_SHIFT);
  64. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  65. mtk_spi_reset(bus_num);
  66. spi_bus[bus_num]->state = MTK_SPI_IDLE;
  67. }
  68. }
  69. static void mtk_spi_enable_transfer(int bus_num)
  70. {
  71. u32 reg_val;
  72. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  73. if (spi_bus[bus_num]->state == MTK_SPI_IDLE) {
  74. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  75. reg_val |= 1 << SPI_CMD_ACT_SHIFT;
  76. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  77. } else if (spi_bus[bus_num]->state == MTK_SPI_PAUSE_IDLE) {
  78. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  79. reg_val |= 1 << SPI_CMD_RESUME_SHIFT;
  80. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  81. }
  82. }
  83. static void mtk_spi_packet(int bus_num, u32 size)
  84. {
  85. u32 reg_val, packet_len, packet_loop;
  86. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  87. packet_len = size < MTK_PACKET_SIZE ? size : MTK_PACKET_SIZE;
  88. packet_loop = MTK_SPI_ROUNDUP_DIV(size, packet_len);
  89. reg_val = DRV_Reg32(&regs->spi_cfg1_reg);
  90. reg_val &= ~(SPI_CFG1_PACKET_LENGTH_MASK | SPI_CFG1_PACKET_LOOP_MASK);
  91. reg_val |= ((packet_len - 1) << SPI_CFG1_PACKET_LENGTH_SHIFT) |
  92. ((packet_loop - 1) << SPI_CFG1_PACKET_LOOP_SHIFT);
  93. mt_reg_sync_writel(reg_val, &regs->spi_cfg1_reg);
  94. }
  95. static int mtk_spi_polling(int bus_num)
  96. {
  97. int i;
  98. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  99. /*
  100. *spi sw should wait for status1 register to idle before polling
  101. * status0 register for rx/tx finish.
  102. */
  103. i = 0;
  104. while ((DRV_Reg32(&regs->spi_status1_reg) &
  105. MTK_SPI_BUSY_STATUS) == 0) {
  106. i++;
  107. udelay(1);
  108. if (i > MTK_TXRX_TIMEOUT_US) {
  109. dprintf(CRITICAL, "Timeout for spi status1 reg.\n");
  110. goto error;
  111. }
  112. }
  113. i = 0;
  114. while ((DRV_Reg32(&regs->spi_status0_reg) &
  115. MTK_SPI_PAUSE_FINISH_INT_STATUS) == 0) {
  116. i++;
  117. udelay(1);
  118. if (i > MTK_TXRX_TIMEOUT_US) {
  119. dprintf(CRITICAL, "Timeout for spi status0 reg.\n");
  120. goto error;
  121. }
  122. }
  123. return 0;
  124. error:
  125. return -1;
  126. }
  127. static void spi_prepare_transfer(int bus_num, struct spi_transfer *transfer)
  128. {
  129. uint32_t div, sck_ticks, cs_ticks, reg_val;
  130. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  131. u32 speed_hz = transfer->speed_hz;
  132. if (speed_hz < (SPI_HZ / 2))
  133. div = MTK_SPI_ROUNDUP_DIV(SPI_HZ, speed_hz);
  134. else
  135. div = 1;
  136. sck_ticks = MTK_SPI_ROUNDUP_DIV(div, 2);
  137. cs_ticks = sck_ticks * 2;
  138. /* set the timing */
  139. mt_reg_sync_writel(((cs_ticks - 1) << SPI_CFG0_CS_HOLD_OFFSET) |
  140. ((cs_ticks - 1) << SPI_CFG0_CS_SETUP_OFFSET),
  141. &regs->spi_cfg0_reg);
  142. mt_reg_sync_writel(((sck_ticks - 1) << SPI_CFG2_SCK_HIGH_OFFSET) |
  143. ((sck_ticks - 1) << SPI_CFG2_SCK_LOW_OFFSET),
  144. &regs->spi_cfg2_reg);
  145. reg_val = DRV_Reg32(&regs->spi_cfg1_reg);
  146. reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
  147. reg_val |= (cs_ticks - 1) << SPI_CFG1_CS_IDLE_SHIFT;
  148. mt_reg_sync_writel(reg_val, &regs->spi_cfg1_reg);
  149. /* tick delay */
  150. reg_val = DRV_Reg32(&regs->spi_cfg1_reg);
  151. reg_val &= 0x1FFFFFFF;
  152. reg_val |= (transfer->tick_delay << SPI_CFG1_GET_TICK_DLY_SHIFT);
  153. mt_reg_sync_writel(reg_val, &regs->spi_cfg1_reg);
  154. }
  155. static int mtk_spi_fifo_transfer(int bus_num, unsigned char *rx_buf,
  156. unsigned char *tx_buf, u32 size)
  157. {
  158. u32 i, reg_val = 0, word_count, remaind;
  159. int ret;
  160. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  161. if (!size || size > MTK_FIFO_DEPTH)
  162. return -1;
  163. mtk_spi_packet(bus_num, size);
  164. remaind = size & 0x03;
  165. if (rx_buf && !tx_buf) {
  166. word_count = size >> 2;
  167. if (remaind)
  168. word_count++;
  169. for (i = 0; i < word_count; i++)
  170. mt_reg_sync_writel(MTK_ARBITRARY_VALUE,
  171. &regs->spi_tx_data_reg);
  172. }
  173. if (tx_buf) {
  174. reg_val = 0;
  175. for (i = 0; i < size - remaind; i++) {
  176. reg_val |= *(tx_buf + i) << ((i & 0x03) << 3);
  177. if ((i & 0x03) == 3) {
  178. mt_reg_sync_writel(reg_val,
  179. &regs->spi_tx_data_reg);
  180. reg_val = 0;
  181. }
  182. }
  183. if (remaind) {
  184. reg_val = 0;
  185. for (i = 0; i < remaind; i++) {
  186. reg_val |= *(tx_buf + size - remaind + i)
  187. << ((i & 0x03) << 3);
  188. }
  189. mt_reg_sync_writel(reg_val, &regs->spi_tx_data_reg);
  190. }
  191. }
  192. mtk_spi_enable_transfer(bus_num);
  193. ret = mtk_spi_polling(bus_num);
  194. if (!ret && rx_buf) {
  195. for (i = 0; i < size; i++) {
  196. if ((i & 0x03) == 0)
  197. reg_val = DRV_Reg32(&regs->spi_rx_data_reg);
  198. *(rx_buf + i) = (reg_val >> ((i & 0x03) << 3)) & 0xff;
  199. }
  200. }
  201. return ret;
  202. }
  203. static int mtk_spi_dma_transfer(int bus_num, unsigned char *rx_buf,
  204. unsigned char *tx_buf, u32 size)
  205. {
  206. u32 reg_val;
  207. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  208. if (!rx_buf && tx_buf) {
  209. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  210. reg_val |= 1 << SPI_CMD_TX_DMA_SHIFT;
  211. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  212. } else {
  213. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  214. reg_val |= (1 << SPI_CMD_RX_DMA_SHIFT) |
  215. (1 << SPI_CMD_TX_DMA_SHIFT);
  216. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  217. }
  218. if (tx_buf) {
  219. arch_clean_cache_range((addr_t)tx_buf, size);
  220. mt_reg_sync_writel((u32)tx_buf, &regs->spi_tx_src_reg);
  221. }
  222. if (rx_buf) {
  223. arch_clean_cache_range((addr_t)rx_buf, size);
  224. mt_reg_sync_writel((u32)rx_buf, &regs->spi_rx_dst_reg);
  225. }
  226. mtk_spi_packet(bus_num, size);
  227. mtk_spi_enable_transfer(bus_num);
  228. if (mtk_spi_polling(bus_num))
  229. goto error;
  230. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  231. reg_val &= ~(1 << SPI_CMD_RX_DMA_SHIFT | 1 << SPI_CMD_TX_DMA_SHIFT);
  232. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  233. if (rx_buf)
  234. arch_clean_invalidate_cache_range((addr_t)rx_buf, size);
  235. return 0;
  236. error:
  237. return -1;
  238. }
  239. int spi_sync(int bus_num, struct spi_transfer *transfer)
  240. {
  241. int ret, min_size;
  242. u8 *tx_buf = (u8 *)transfer->tx_buf;
  243. u8 *rx_buf = (u8 *)transfer->rx_buf;
  244. u32 size = transfer->len;
  245. if(bus_num < 0) {
  246. dprintf(CRITICAL, "spi: bus_num is valid.\n");
  247. return -1;
  248. }
  249. spi_prepare_transfer(bus_num, transfer);
  250. while (size) {
  251. min_size = size < MTK_PACKET_SIZE ? size : MTK_PACKET_SIZE;
  252. if (size > MTK_FIFO_DEPTH)
  253. ret = mtk_spi_dma_transfer(bus_num, rx_buf, tx_buf,
  254. min_size);
  255. else
  256. ret = mtk_spi_fifo_transfer(bus_num, rx_buf, tx_buf,
  257. min_size);
  258. if (ret) {
  259. mtk_spi_reset(bus_num);
  260. return ret;
  261. }
  262. size -= min_size;
  263. if (rx_buf)
  264. rx_buf += min_size;
  265. if (tx_buf)
  266. tx_buf += min_size;
  267. }
  268. if (transfer->cs_change)
  269. mtk_spi_set_cs(bus_num, 1);
  270. else
  271. mtk_spi_set_cs(bus_num, 0);
  272. return ret;
  273. }
  274. static void spi_fdt_getprop_u32_array(int nodeoffset,
  275. const char *name, unsigned int *out_value)
  276. {
  277. int i;
  278. unsigned int *data = NULL;
  279. int len = 0;
  280. void *lk_drv_fdt = (void *)get_lk_overlayed_dtb();
  281. if (lk_drv_fdt == NULL)
  282. panic("lk driver fdt is NULL!\n");
  283. data = (unsigned int *)fdt_getprop(lk_drv_fdt, nodeoffset, name, &len);
  284. if (len > 0 && data) {
  285. len = len / sizeof(unsigned int);
  286. for (i = 0; i < len; i++)
  287. *(out_value+i) = fdt32_to_cpu(*(data+i));
  288. } else
  289. *out_value = 0;
  290. }
  291. void mtk_spi_init(int bus_num, struct mtk_spi_bus_config *spi_config)
  292. {
  293. uint32_t reg_val;
  294. uint16_t cpha, cpol;
  295. struct mtk_spi_bus_config *spi_bus_config = spi_config;
  296. struct mtk_spi_regs *regs = spi_bus[bus_num]->reg_addr;
  297. if (spi_bus_config == NULL)
  298. spi_bus_config = &spi_default_config;
  299. cpha = spi_bus_config->spi_mode & SPI_CPHA ? 1:0;
  300. cpol = spi_bus_config->spi_mode & SPI_CPOL ? 1:0;
  301. reg_val = DRV_Reg32(&regs->spi_cmd_reg);
  302. /* set spi mode */
  303. if (cpha)
  304. reg_val |= SPI_CMD_CPHA_EN;
  305. else
  306. reg_val &= ~SPI_CMD_CPHA_EN;
  307. if (cpol)
  308. reg_val |= SPI_CMD_CPOL_EN;
  309. else
  310. reg_val &= ~SPI_CMD_CPOL_EN;
  311. /* set the mlsbx and mlsbtx */
  312. reg_val &= ~SPI_CMD_TXMSBF_EN;
  313. reg_val &= ~SPI_CMD_RXMSBF_EN;
  314. /* set the tx/rx endian */
  315. reg_val &= ~SPI_CMD_TX_ENDIAN_EN;
  316. reg_val &= ~SPI_CMD_RX_ENDIAN_EN;
  317. /* clear pause mode */
  318. reg_val &= ~SPI_CMD_PAUSE_EN;
  319. /* set finish interrupt always disable */
  320. reg_val &= ~SPI_CMD_FINISH_IE_EN;
  321. /* set pause interrupt always disable */
  322. reg_val &= ~SPI_CMD_PAUSE_IE_EN;
  323. /* disable dma mode */
  324. reg_val &= ~(SPI_CMD_TX_DMA_EN | SPI_CMD_RX_DMA_EN);
  325. /* set deassert mode */
  326. reg_val &= ~SPI_CMD_DEASSERT_EN;
  327. mt_reg_sync_writel(reg_val, &regs->spi_cmd_reg);
  328. /* pad select */
  329. reg_val = spi_bus[bus_num]->pad_select;
  330. mt_reg_sync_writel(reg_val, &regs->spi_pad_sel_reg);
  331. /* tick delay */
  332. reg_val = DRV_Reg32(&regs->spi_cfg1_reg);
  333. reg_val |= (spi_bus_config->tick_delay << SPI_CFG1_GET_TICK_DLY_SHIFT);
  334. mt_reg_sync_writel(reg_val, &regs->spi_cfg1_reg);
  335. /* cs pull high && reset spi */
  336. mtk_spi_set_cs(bus_num, 1);
  337. mtk_spi_reset(bus_num);
  338. }
  339. int init_spi_bus_from_dt(const char *compatible,
  340. struct mtk_spi_bus_config *config)
  341. {
  342. int node, parent_node = 0;
  343. uint32_t temp_data[4] = { 0 };
  344. uint32_t pad_select = 0;
  345. struct mtk_spi_bus *bus = NULL;
  346. void *lk_drv_fdt = (void *)get_lk_overlayed_dtb();
  347. if (lk_drv_fdt == NULL)
  348. panic("lk driver fdt is NULL!\n");
  349. node = fdt_node_offset_by_compatible(lk_drv_fdt, -1, compatible);
  350. if (node <= 0) {
  351. dprintf(SPEW, "spi slave dts node is not set, just skip.\n");
  352. return -1;
  353. }
  354. parent_node = fdt_parent_offset(lk_drv_fdt, node);
  355. if (node <= 0) {
  356. dprintf(SPEW, "get spi slave parent node failed!\n");
  357. return -1;
  358. }
  359. bus = malloc(sizeof(struct mtk_spi_bus));
  360. if (!bus) {
  361. dprintf(CRITICAL, "faild to malloc mtk_spi_bus\n");
  362. return -1;
  363. }
  364. spi_bus_num++;
  365. spi_bus[spi_bus_num] = bus;
  366. spi_fdt_getprop_u32_array(parent_node,
  367. "reg", temp_data);
  368. spi_fdt_getprop_u32_array(parent_node,
  369. "mediatek,pad-select", &pad_select);
  370. spi_bus[spi_bus_num]->reg_addr = (struct mtk_spi_regs *)temp_data[1];
  371. spi_bus[spi_bus_num]->pad_select = pad_select;
  372. spi_bus[spi_bus_num]->spi_bus_fdt_offset = parent_node;
  373. dprintf(SPEW, "reg addr : %p, pad_select : %d\n",
  374. spi_bus[spi_bus_num]->reg_addr,
  375. spi_bus[spi_bus_num]->pad_select);
  376. mtk_spi_init(spi_bus_num, config);
  377. return spi_bus_num;
  378. }