cldma_platform.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. #include <linux/platform_device.h>
  2. #include <linux/interrupt.h>
  3. #include <linux/irq.h>
  4. #include "ccci_config.h"
  5. #if defined(CONFIG_MTK_CLKMGR)
  6. #include <mach/mt_clkmgr.h>
  7. #else
  8. #include <linux/clk.h>
  9. #endif /*CONFIG_MTK_CLKMGR */
  10. #ifdef FEATURE_RF_CLK_BUF
  11. #include <mt_clkbuf_ctl.h>
  12. #endif
  13. #ifdef FEATURE_INFORM_NFC_VSIM_CHANGE
  14. #include <mach/mt6605.h>
  15. #endif
  16. #include <mt-plat/upmu_common.h>
  17. #include <mach/mt_pbm.h>
  18. #include <mt_spm_sleep.h>
  19. #include "ccci_core.h"
  20. #include "ccci_platform.h"
  21. #include "modem_cldma.h"
  22. #include "cldma_platform.h"
  23. #include "cldma_reg.h"
  24. #include "modem_reg_base.h"
  25. #ifdef CONFIG_OF
  26. #include <linux/of.h>
  27. #include <linux/of_fdt.h>
  28. #include <linux/of_irq.h>
  29. #include <linux/of_address.h>
  30. #endif
  31. #include "ccci_core.h"
  32. #if !defined(CONFIG_MTK_CLKMGR)
  33. static struct clk *clk_scp_sys_md1_main;
  34. #endif
  35. static struct pinctrl *mdcldma_pinctrl;
  36. #define TAG "mcd"
  37. void md_cldma_hw_reset(struct ccci_modem *md)
  38. {
  39. unsigned int reg_value;
  40. CCCI_DBG_MSG(md->index, TAG, "md_cldma_hw_reset:rst cldma\n");
  41. /* reset cldma hw */
  42. reg_value = ccci_read32(infra_ao_base, INFRA_RST0_REG);
  43. reg_value &= ~(CLDMA_AO_RST_MASK | CLDMA_PD_RST_MASK);
  44. reg_value |= (CLDMA_AO_RST_MASK | CLDMA_PD_RST_MASK);
  45. ccci_write32(infra_ao_base, INFRA_RST0_REG, reg_value);
  46. CCCI_DBG_MSG(md->index, TAG, "md_cldma_hw_reset:clear reset\n");
  47. /* reset cldma clr */
  48. reg_value = ccci_read32(infra_ao_base, INFRA_RST1_REG);
  49. reg_value &= ~(CLDMA_AO_RST_MASK | CLDMA_PD_RST_MASK);
  50. reg_value |= (CLDMA_AO_RST_MASK | CLDMA_PD_RST_MASK);
  51. ccci_write32(infra_ao_base, INFRA_RST1_REG, reg_value);
  52. CCCI_DBG_MSG(md->index, TAG, "md_cldma_hw_reset:done\n");
  53. }
  54. int md_cd_get_modem_hw_info(struct platform_device *dev_ptr, struct ccci_dev_cfg *dev_cfg, struct md_hw_info *hw_info)
  55. {
  56. memset(dev_cfg, 0, sizeof(struct ccci_dev_cfg));
  57. memset(hw_info, 0, sizeof(struct md_hw_info));
  58. if (dev_ptr->dev.of_node == NULL) {
  59. CCCI_ERR_MSG(dev_cfg->index, TAG, "modem OF node NULL\n");
  60. return -1;
  61. }
  62. of_property_read_u32(dev_ptr->dev.of_node, "mediatek,md_id", &dev_cfg->index);
  63. CCCI_DBG_MSG(dev_cfg->index, TAG, "modem hw info get idx:%d\n", dev_cfg->index);
  64. if (!get_modem_is_enabled(dev_cfg->index)) {
  65. CCCI_ERR_MSG(dev_cfg->index, TAG, "modem %d not enable, exit\n", dev_cfg->index + 1);
  66. return -1;
  67. }
  68. switch (dev_cfg->index) {
  69. case 0: /* MD_SYS1 */
  70. dev_cfg->major = 0;
  71. dev_cfg->minor_base = 0;
  72. of_property_read_u32(dev_ptr->dev.of_node, "mediatek,cldma_capability", &dev_cfg->capability);
  73. hw_info->cldma_ap_ao_base = (unsigned long)of_iomap(dev_ptr->dev.of_node, 0);
  74. hw_info->cldma_md_ao_base = (unsigned long)of_iomap(dev_ptr->dev.of_node, 1);
  75. hw_info->cldma_ap_pdn_base = (unsigned long)of_iomap(dev_ptr->dev.of_node, 2);
  76. hw_info->cldma_md_pdn_base = (unsigned long)of_iomap(dev_ptr->dev.of_node, 3);
  77. hw_info->ap_ccif_base = (unsigned long)of_iomap(dev_ptr->dev.of_node, 4);
  78. hw_info->md_ccif_base = (unsigned long)of_iomap(dev_ptr->dev.of_node, 5);
  79. hw_info->cldma_irq_id = irq_of_parse_and_map(dev_ptr->dev.of_node, 0);
  80. hw_info->ap_ccif_irq_id = irq_of_parse_and_map(dev_ptr->dev.of_node, 1);
  81. hw_info->md_wdt_irq_id = irq_of_parse_and_map(dev_ptr->dev.of_node, 2);
  82. /* Device tree using none flag to register irq, sensitivity has set at "irq_of_parse_and_map" */
  83. hw_info->cldma_irq_flags = IRQF_TRIGGER_NONE;
  84. hw_info->ap_ccif_irq_flags = IRQF_TRIGGER_NONE;
  85. hw_info->md_wdt_irq_flags = IRQF_TRIGGER_NONE;
  86. hw_info->ap2md_bus_timeout_irq_flags = IRQF_TRIGGER_NONE;
  87. hw_info->sram_size = CCIF_SRAM_SIZE;
  88. hw_info->md_rgu_base = MD_RGU_BASE;
  89. hw_info->md_boot_slave_Vector = MD_BOOT_VECTOR;
  90. hw_info->md_boot_slave_Key = MD_BOOT_VECTOR_KEY;
  91. hw_info->md_boot_slave_En = MD_BOOT_VECTOR_EN;
  92. mdcldma_pinctrl = devm_pinctrl_get(&dev_ptr->dev);
  93. if (IS_ERR(mdcldma_pinctrl)) {
  94. CCCI_ERR_MSG(dev_cfg->index, TAG, "modem %d get mdcldma_pinctrl failed\n", dev_cfg->index + 1);
  95. return -1;
  96. }
  97. #if !defined(CONFIG_MTK_CLKMGR)
  98. clk_scp_sys_md1_main = devm_clk_get(&dev_ptr->dev, "scp-sys-md1-main");
  99. if (IS_ERR(clk_scp_sys_md1_main)) {
  100. CCCI_ERR_MSG(dev_cfg->index, TAG, "modem %d get scp-sys-md1-main failed\n", dev_cfg->index + 1);
  101. return -1;
  102. }
  103. #endif
  104. break;
  105. default:
  106. return -1;
  107. }
  108. CCCI_DBG_MSG(dev_cfg->index, TAG, "dev_major:%d,minor_base:%d,capability:%d\n",
  109. dev_cfg->major, dev_cfg->minor_base, dev_cfg->capability);
  110. CCCI_DBG_MSG(dev_cfg->index, TAG,
  111. "ap_cldma: ao_base=0x%p, pdn_base=0x%p,md_cldma: ao_base=0x%p, pdn_base=0x%p\n",
  112. (void *)hw_info->cldma_ap_ao_base, (void *)hw_info->cldma_ap_pdn_base,
  113. (void *)hw_info->cldma_md_ao_base, (void *)hw_info->cldma_md_pdn_base);
  114. CCCI_DBG_MSG(dev_cfg->index, TAG, "ap_ccif_base:0x%p, md_ccif_base:0x%p\n", (void *)hw_info->ap_ccif_base,
  115. (void *)hw_info->md_ccif_base);
  116. CCCI_DBG_MSG(dev_cfg->index, TAG, "cldma_irq:%d,ccif_irq:%d,md_wdt_irq:%d\n", hw_info->cldma_irq_id,
  117. hw_info->ap_ccif_irq_id, hw_info->md_wdt_irq_id);
  118. return 0;
  119. }
  120. int md_cd_io_remap_md_side_register(struct ccci_modem *md)
  121. {
  122. struct md_cd_ctrl *md_ctrl = (struct md_cd_ctrl *)md->private_data;
  123. md_ctrl->cldma_ap_pdn_base = (void __iomem *)(md_ctrl->hw_info->cldma_ap_pdn_base);
  124. md_ctrl->cldma_ap_ao_base = (void __iomem *)(md_ctrl->hw_info->cldma_ap_ao_base);
  125. md_ctrl->cldma_md_pdn_base = (void __iomem *)(md_ctrl->hw_info->cldma_md_pdn_base);
  126. md_ctrl->cldma_md_ao_base = (void __iomem *)(md_ctrl->hw_info->cldma_md_ao_base);
  127. md_ctrl->md_boot_slave_Vector = ioremap_nocache(md_ctrl->hw_info->md_boot_slave_Vector, 0x4);
  128. md_ctrl->md_boot_slave_Key = ioremap_nocache(md_ctrl->hw_info->md_boot_slave_Key, 0x4);
  129. md_ctrl->md_boot_slave_En = ioremap_nocache(md_ctrl->hw_info->md_boot_slave_En, 0x4);
  130. md_ctrl->md_rgu_base = ioremap_nocache(md_ctrl->hw_info->md_rgu_base, 0x40);
  131. md_ctrl->md_global_con0 = ioremap_nocache(MD_GLOBAL_CON0, 0x4);
  132. md_ctrl->md_bus_status = ioremap_nocache(MD_BUS_STATUS_BASE, MD_BUS_STATUS_LENGTH);
  133. md_ctrl->md_pc_monitor = ioremap_nocache(MD_PC_MONITOR_BASE, MD_PC_MONITOR_LENGTH);
  134. md_ctrl->md_topsm_status = ioremap_nocache(MD_TOPSM_STATUS_BASE, MD_TOPSM_STATUS_LENGTH);
  135. md_ctrl->md_ost_status = ioremap_nocache(MD_OST_STATUS_BASE, MD_OST_STATUS_LENGTH);
  136. md_ctrl->md_pll = ioremap_nocache(MD_PLL_BASE, MD_PLL_LENGTH);
  137. #ifdef MD_PEER_WAKEUP
  138. md_ctrl->md_peer_wakeup = ioremap_nocache(MD_PEER_WAKEUP, 0x4);
  139. #endif
  140. return 0;
  141. }
  142. void md_cd_lock_cldma_clock_src(int locked)
  143. {
  144. /* spm_ap_mdsrc_req(locked); */
  145. }
  146. void md_cd_lock_modem_clock_src(int locked)
  147. {
  148. spm_ap_mdsrc_req(locked);
  149. }
  150. void md_cd_dump_debug_register(struct ccci_modem *md)
  151. {
  152. struct md_cd_ctrl *md_ctrl = (struct md_cd_ctrl *)md->private_data;
  153. unsigned int reg_value;
  154. md_cd_lock_modem_clock_src(1);
  155. CCCI_INF_MSG(md->index, TAG, "Dump MD Bus status %x\n", MD_BUS_STATUS_BASE);
  156. ccci_mem_dump(md->index, md_ctrl->md_bus_status, MD_BUS_STATUS_LENGTH);
  157. CCCI_INF_MSG(md->index, TAG, "Dump MD PC monitor %x\n", MD_PC_MONITOR_BASE);
  158. /* stop MD PCMon */
  159. reg_value = ccci_read32(md_ctrl->md_pc_monitor, 0);
  160. reg_value &= ~(0x1 << 21);
  161. ccci_write32(md_ctrl->md_pc_monitor, 0, reg_value); /* clear bit[21] */
  162. ccci_write32((md_ctrl->md_pc_monitor + 4), 0, 0x80000000); /* stop MD PCMon */
  163. ccci_mem_dump(md->index, md_ctrl->md_pc_monitor, MD_PC_MONITOR_LENGTH);
  164. ccci_write32(md_ctrl->md_pc_monitor + 4, 0, 0x1); /* restart MD PCMon */
  165. CCCI_INF_MSG(md->index, TAG, "Dump MD TOPSM status %x\n", MD_TOPSM_STATUS_BASE);
  166. ccci_mem_dump(md->index, md_ctrl->md_topsm_status, MD_TOPSM_STATUS_LENGTH);
  167. CCCI_INF_MSG(md->index, TAG, "Dump MD OST status %x\n", MD_OST_STATUS_BASE);
  168. ccci_mem_dump(md->index, md_ctrl->md_ost_status, MD_OST_STATUS_LENGTH);
  169. CCCI_INF_MSG(md->index, TAG, "Dump MD PLL %x\n", MD_PLL_BASE);
  170. ccci_mem_dump(md->index, md_ctrl->md_pll, MD_PLL_LENGTH);
  171. md_cd_lock_modem_clock_src(0);
  172. }
  173. void md_cd_check_md_DCM(struct ccci_modem *md)
  174. {
  175. struct md_cd_ctrl *md_ctrl = (struct md_cd_ctrl *)md->private_data;
  176. md_cd_lock_modem_clock_src(1);
  177. CCCI_INF_MSG(md->index, TAG, "MD DCM: 0x%X\n", *(unsigned int *)(md_ctrl->md_bus_status + 0x45C));
  178. md_cd_lock_modem_clock_src(0);
  179. }
  180. void md_cd_check_emi_state(struct ccci_modem *md, int polling)
  181. {
  182. }
  183. /* callback for system power off*/
  184. void ccci_power_off(void)
  185. {
  186. /*ALPS02057700 workaround:
  187. * Power on VLTE for system power off backlight work normal
  188. */
  189. CCCI_INF_MSG(-1, CORE, "ccci_power_off:set VLTE on,bit0,1\n");
  190. pmic_config_interface(0x04D6, 0x1, 0x1, 0); /* bit[0] =>1'b1 */
  191. udelay(200);
  192. }
  193. int md_cd_power_on(struct ccci_modem *md)
  194. {
  195. int ret = 0;
  196. unsigned int reg_value;
  197. struct md_cd_ctrl *md_ctrl = (struct md_cd_ctrl *)md->private_data;
  198. #if defined(FEATURE_RF_CLK_BUF)
  199. struct pinctrl_state *RFIC0_01_mode;
  200. #endif
  201. /* turn on VLTE */
  202. #ifdef FEATURE_VLTE_SUPPORT
  203. struct pinctrl_state *vsram_output_high;
  204. if (NULL != mdcldma_pinctrl) {
  205. vsram_output_high = pinctrl_lookup_state(mdcldma_pinctrl, "vsram_output_high");
  206. if (IS_ERR(vsram_output_high)) {
  207. CCCI_INF_MSG(md->index, CORE, "cannot find vsram_output_high pintrl. ret=%ld\n",
  208. PTR_ERR(vsram_output_high));
  209. }
  210. pinctrl_select_state(mdcldma_pinctrl, vsram_output_high);
  211. } else {
  212. CCCI_INF_MSG(md->index, CORE, "mdcldma_pinctrl is NULL, some error happend.\n");
  213. }
  214. CCCI_INF_MSG(md->index, CORE, "md_cd_power_on:mt_set_gpio_out(GPIO_LTE_VSRAM_EXT_POWER_EN_PIN,1)\n");
  215. /* if(!(mt6325_upmu_get_swcid()==PMIC6325_E1_CID_CODE || */
  216. /* mt6325_upmu_get_swcid()==PMIC6325_E2_CID_CODE)) */
  217. {
  218. CCCI_INF_MSG(md->index, CORE, "md_cd_power_on:set VLTE on,bit0,1\n");
  219. pmic_config_interface(0x04D6, 0x1, 0x1, 0); /* bit[0] =>1'b1 */
  220. udelay(200);
  221. /*
  222. *[Notes] move into md cmos flow, for hardwareissue, so disable on denlai.
  223. * bring up need confirm with MD DE & SPM
  224. */
  225. /* reg_value = ccci_read32(infra_ao_base,0x338); */
  226. /* reg_value &= ~(0x40); //bit[6] =>1'b0 */
  227. /* ccci_write32(infra_ao_base,0x338,reg_value); */
  228. /* CCCI_INF_MSG(md->index, CORE, "md_cd_power_on: set infra_misc VLTE bit(0x1000_0338)=0x%x,
  229. bit[6]=0x%x\n",ccci_read32(infra_ao_base,0x338),(ccci_read32(infra_ao_base,0x338)&0x40)); */
  230. }
  231. #endif
  232. reg_value = ccci_read32(infra_ao_base, 0x338);
  233. reg_value &= ~(0x3 << 2); /* md1_srcclkena */
  234. reg_value |= (0x1 << 2);
  235. ccci_write32(infra_ao_base, 0x338, reg_value);
  236. CCCI_INF_MSG(md->index, CORE, "md_cd_power_on: set md1_srcclkena bit(0x1000_0338)=0x%x\n",
  237. ccci_read32(infra_ao_base, 0x338));
  238. #ifdef FEATURE_RF_CLK_BUF
  239. /* config RFICx as BSI */
  240. mutex_lock(&clk_buf_ctrl_lock); /* fixme,clkbuf, ->down(&clk_buf_ctrl_lock_2); */
  241. CCCI_INF_MSG(md->index, TAG, "clock buffer, BSI ignore mode\n");
  242. if (NULL != mdcldma_pinctrl) {
  243. RFIC0_01_mode = pinctrl_lookup_state(mdcldma_pinctrl, "RFIC0_01_mode");
  244. pinctrl_select_state(mdcldma_pinctrl, RFIC0_01_mode);
  245. }
  246. #endif
  247. /* power on MD_INFRA and MODEM_TOP */
  248. switch (md->index) {
  249. case MD_SYS1:
  250. #if defined(CONFIG_MTK_CLKMGR)
  251. CCCI_INF_MSG(md->index, TAG, "Call start md_power_on()\n");
  252. ret = md_power_on(SYS_MD1);
  253. CCCI_INF_MSG(md->index, TAG, "Call end md_power_on() ret=%d\n", ret);
  254. #else
  255. CCCI_INF_MSG(md->index, TAG, "Call start clk_prepare_enable()\n");
  256. ret = clk_prepare_enable(clk_scp_sys_md1_main);
  257. CCCI_INF_MSG(md->index, TAG, "Call end clk_prepare_enable()ret=%d\n", ret);
  258. #endif
  259. kicker_pbm_by_md(MD1, true);
  260. CCCI_INF_MSG(md->index, TAG, "Call end kicker_pbm_by_md(0,true)\n");
  261. break;
  262. }
  263. #ifdef FEATURE_RF_CLK_BUF
  264. mutex_unlock(&clk_buf_ctrl_lock); /* fixme,clkbuf, ->delete */
  265. #endif
  266. #ifdef FEATURE_INFORM_NFC_VSIM_CHANGE
  267. /* notify NFC */
  268. inform_nfc_vsim_change(md->index, 1, 0);
  269. #endif
  270. /* disable MD WDT */
  271. cldma_write32(md_ctrl->md_rgu_base, WDT_MD_MODE, WDT_MD_MODE_KEY);
  272. return ret;
  273. }
  274. int md_cd_bootup_cleanup(struct ccci_modem *md, int success)
  275. {
  276. return 0;
  277. }
  278. int md_cd_let_md_go(struct ccci_modem *md)
  279. {
  280. struct md_cd_ctrl *md_ctrl = (struct md_cd_ctrl *)md->private_data;
  281. if (MD_IN_DEBUG(md))
  282. return -1;
  283. CCCI_INF_MSG(md->index, TAG, "set MD boot slave\n");
  284. /* set the start address to let modem to run */
  285. cldma_write32(md_ctrl->md_boot_slave_Key, 0, 0x3567C766); /* make boot vector programmable */
  286. cldma_write32(md_ctrl->md_boot_slave_Vector, 0, 0x00000000);
  287. /* after remap, MD ROM address is 0 from MD's view */
  288. cldma_write32(md_ctrl->md_boot_slave_En, 0, 0xA3B66175); /* make boot vector take effect */
  289. return 0;
  290. }
  291. int md_cd_power_off(struct ccci_modem *md, unsigned int timeout)
  292. {
  293. int ret = 0;
  294. unsigned int reg_value;
  295. #if defined(FEATURE_RF_CLK_BUF)
  296. struct pinctrl_state *RFIC0_04_mode;
  297. #endif
  298. #if defined(FEATURE_VLTE_SUPPORT)
  299. struct pinctrl_state *vsram_output_low;
  300. #endif
  301. #ifdef FEATURE_INFORM_NFC_VSIM_CHANGE
  302. /* notify NFC */
  303. inform_nfc_vsim_change(md->index, 0, 0);
  304. #endif
  305. #ifdef FEATURE_RF_CLK_BUF
  306. mutex_lock(&clk_buf_ctrl_lock);
  307. #endif
  308. /* power off MD_INFRA and MODEM_TOP */
  309. switch (md->index) {
  310. case MD_SYS1:
  311. #if defined(CONFIG_MTK_CLKMGR)
  312. ret = md_power_off(SYS_MD1, timeout);
  313. #else
  314. clk_disable(clk_scp_sys_md1_main);
  315. #ifdef FEATURE_RF_CLK_BUF
  316. mutex_unlock(&clk_buf_ctrl_lock);
  317. #endif
  318. clk_unprepare(clk_scp_sys_md1_main); /* cannot be called in mutex context */
  319. #ifdef FEATURE_RF_CLK_BUF
  320. mutex_lock(&clk_buf_ctrl_lock);
  321. #endif
  322. #endif
  323. kicker_pbm_by_md(MD1, false);
  324. CCCI_INF_MSG(md->index, TAG, "Call end kicker_pbm_by_md(0,false)\n");
  325. break;
  326. }
  327. #ifdef FEATURE_RF_CLK_BUF
  328. /* config RFICx as AP SPM control */
  329. CCCI_INF_MSG(md->index, TAG, "clock buffer, AP SPM control mode\n");
  330. RFIC0_04_mode = pinctrl_lookup_state(mdcldma_pinctrl, "RFIC0_04_mode");
  331. pinctrl_select_state(mdcldma_pinctrl, RFIC0_04_mode);
  332. mutex_unlock(&clk_buf_ctrl_lock);
  333. #endif
  334. reg_value = ccci_read32(infra_ao_base, 0x338);
  335. reg_value &= ~(0x3 << 2); /* md1_srcclkena */
  336. ccci_write32(infra_ao_base, 0x338, reg_value);
  337. CCCI_INF_MSG(md->index, CORE, "md_cd_power_off: set md1_srcclkena bit(0x1000_0338)=0x%x\n",
  338. ccci_read32(infra_ao_base, 0x338));
  339. #ifdef FEATURE_VLTE_SUPPORT
  340. /* Turn off VLTE */
  341. /* if(!(mt6325_upmu_get_swcid()==PMIC6325_E1_CID_CODE || */
  342. /* mt6325_upmu_get_swcid()==PMIC6325_E2_CID_CODE)) */
  343. {
  344. /*
  345. *[Notes] move into md cmos flow, for hardwareissue, so disable on denlai.
  346. * bring up need confirm with MD DE & SPM
  347. */
  348. /* reg_value = ccci_read32(infra_ao_base,0x338); */
  349. /* reg_value &= ~(0x40); //bit[6] =>1'b0 */
  350. /* reg_value |= 0x40;//bit[6] =>1'b1 */
  351. /* ccci_write32(infra_ao_base,0x338,reg_value); */
  352. /* CCCI_INF_MSG(md->index, CORE, "md_cd_power_off: set SRCLKEN infra_misc(0x1000_0338)=0x%x,
  353. bit[6]=0x%x\n", ccci_read32(infra_ao_base, 0x338), (ccci_read32(infra_ao_base,0x338)&0x40)); */
  354. CCCI_INF_MSG(md->index, CORE, "md_cd_power_off:set VLTE on,bit0=0\n");
  355. pmic_config_interface(0x04D6, 0x0, 0x1, 0); /* bit[0] =>1'b0 */
  356. }
  357. if (NULL != mdcldma_pinctrl) {
  358. vsram_output_low = pinctrl_lookup_state(mdcldma_pinctrl, "vsram_output_low");
  359. if (IS_ERR(vsram_output_low)) {
  360. CCCI_INF_MSG(md->index, CORE, "cannot find vsram_output_low pintrl. ret=%ld\n",
  361. PTR_ERR(vsram_output_low));
  362. }
  363. pinctrl_select_state(mdcldma_pinctrl, vsram_output_low);
  364. } else {
  365. CCCI_INF_MSG(md->index, CORE, "mdcldma_pinctrl is NULL, some error happend.\n");
  366. }
  367. CCCI_INF_MSG(md->index, CORE, "md_cd_power_off:mt_set_gpio_out(GPIO_LTE_VSRAM_EXT_POWER_EN_PIN,0)\n");
  368. #endif
  369. return ret;
  370. }
  371. void cldma_dump_register(struct ccci_modem *md)
  372. {
  373. struct md_cd_ctrl *md_ctrl = (struct md_cd_ctrl *)md->private_data;
  374. CCCI_INF_MSG(md->index, TAG, "dump AP CLDMA Tx pdn register, active=%x\n", md_ctrl->txq_active);
  375. ccci_mem_dump(md->index, md_ctrl->cldma_ap_pdn_base + CLDMA_AP_UL_START_ADDR_0,
  376. CLDMA_AP_UL_CHECKSUM_CHANNEL_ENABLE - CLDMA_AP_UL_START_ADDR_0 + 4);
  377. CCCI_INF_MSG(md->index, TAG, "dump AP CLDMA Tx ao register, active=%x\n", md_ctrl->txq_active);
  378. ccci_mem_dump(md->index, md_ctrl->cldma_ap_ao_base + CLDMA_AP_UL_START_ADDR_BK_0,
  379. CLDMA_AP_UL_CURRENT_ADDR_BK_7 - CLDMA_AP_UL_START_ADDR_BK_0 + 4);
  380. CCCI_INF_MSG(md->index, TAG, "dump AP CLDMA Rx pdn register, active=%x\n", md_ctrl->rxq_active);
  381. ccci_mem_dump(md->index, md_ctrl->cldma_ap_pdn_base + CLDMA_AP_SO_ERROR,
  382. CLDMA_AP_SO_STOP_CMD - CLDMA_AP_SO_ERROR + 4);
  383. CCCI_INF_MSG(md->index, TAG, "dump AP CLDMA Rx ao register, active=%x\n", md_ctrl->rxq_active);
  384. ccci_mem_dump(md->index, md_ctrl->cldma_ap_ao_base + CLDMA_AP_SO_CFG,
  385. CLDMA_AP_DEBUG_ID_EN - CLDMA_AP_SO_CFG + 4);
  386. CCCI_INF_MSG(md->index, TAG, "dump AP CLDMA MISC pdn register\n");
  387. ccci_mem_dump(md->index, md_ctrl->cldma_ap_pdn_base + CLDMA_AP_L2TISAR0,
  388. CLDMA_AP_CLDMA_IP_BUSY - CLDMA_AP_L2TISAR0 + 4);
  389. CCCI_INF_MSG(md->index, TAG, "dump AP CLDMA MISC ao register\n");
  390. ccci_mem_dump(md->index, md_ctrl->cldma_ap_ao_base + CLDMA_AP_L2RIMR0, CLDMA_AP_DUMMY - CLDMA_AP_L2RIMR0 + 4);
  391. CCCI_INF_MSG(md->index, TAG, "dump MD CLDMA Tx pdn register, active=%x\n", md_ctrl->txq_active);
  392. ccci_mem_dump(md->index, md_ctrl->cldma_md_pdn_base + CLDMA_AP_UL_START_ADDR_0,
  393. CLDMA_AP_UL_CHECKSUM_CHANNEL_ENABLE - CLDMA_AP_UL_START_ADDR_0 + 4);
  394. CCCI_INF_MSG(md->index, TAG, "dump MD CLDMA Tx ao register, active=%x\n", md_ctrl->txq_active);
  395. ccci_mem_dump(md->index, md_ctrl->cldma_md_ao_base + CLDMA_AP_UL_START_ADDR_BK_0,
  396. CLDMA_AP_UL_CURRENT_ADDR_BK_7 - CLDMA_AP_UL_START_ADDR_BK_0 + 4);
  397. CCCI_INF_MSG(md->index, TAG, "dump MD CLDMA Rx pdn register, active=%x\n", md_ctrl->rxq_active);
  398. ccci_mem_dump(md->index, md_ctrl->cldma_md_pdn_base + CLDMA_AP_SO_ERROR,
  399. CLDMA_AP_SO_STOP_CMD - CLDMA_AP_SO_ERROR + 4);
  400. CCCI_INF_MSG(md->index, TAG, "dump MD CLDMA Rx ao register, active=%x\n", md_ctrl->rxq_active);
  401. ccci_mem_dump(md->index, md_ctrl->cldma_md_ao_base + CLDMA_AP_SO_CFG,
  402. CLDMA_AP_DEBUG_ID_EN - CLDMA_AP_SO_CFG + 4);
  403. CCCI_INF_MSG(md->index, TAG, "dump MD CLDMA MISC pdn register\n");
  404. ccci_mem_dump(md->index, md_ctrl->cldma_md_pdn_base + CLDMA_AP_L2TISAR0,
  405. CLDMA_AP_CLDMA_IP_BUSY - CLDMA_AP_L2TISAR0 + 4);
  406. CCCI_INF_MSG(md->index, TAG, "dump MD CLDMA MISC ao register\n");
  407. ccci_mem_dump(md->index, md_ctrl->cldma_md_ao_base + CLDMA_AP_L2RIMR0, CLDMA_AP_DUMMY - CLDMA_AP_L2RIMR0 + 4);
  408. }
  409. int ccci_modem_remove(struct platform_device *dev)
  410. {
  411. return 0;
  412. }
  413. void ccci_modem_shutdown(struct platform_device *dev)
  414. {
  415. }
  416. int ccci_modem_suspend(struct platform_device *dev, pm_message_t state)
  417. {
  418. struct ccci_modem *md = (struct ccci_modem *)dev->dev.platform_data;
  419. CCCI_DBG_MSG(md->index, TAG, "ccci_modem_suspend\n");
  420. return 0;
  421. }
  422. int ccci_modem_resume(struct platform_device *dev)
  423. {
  424. struct ccci_modem *md = (struct ccci_modem *)dev->dev.platform_data;
  425. CCCI_DBG_MSG(md->index, TAG, "ccci_modem_resume\n");
  426. return 0;
  427. }
  428. int ccci_modem_pm_suspend(struct device *device)
  429. {
  430. struct platform_device *pdev = to_platform_device(device);
  431. BUG_ON(pdev == NULL);
  432. return ccci_modem_suspend(pdev, PMSG_SUSPEND);
  433. }
  434. int ccci_modem_pm_resume(struct device *device)
  435. {
  436. struct platform_device *pdev = to_platform_device(device);
  437. BUG_ON(pdev == NULL);
  438. return ccci_modem_resume(pdev);
  439. }
  440. int ccci_modem_pm_restore_noirq(struct device *device)
  441. {
  442. struct ccci_modem *md = (struct ccci_modem *)device->platform_data;
  443. struct md_cd_ctrl *md_ctrl = (struct md_cd_ctrl *)md->private_data;
  444. /* set flag for next md_start */
  445. md->config.setting |= MD_SETTING_RELOAD;
  446. md->config.setting |= MD_SETTING_FIRST_BOOT;
  447. /* restore IRQ */
  448. #ifdef FEATURE_PM_IPO_H
  449. irq_set_irq_type(md_ctrl->cldma_irq_id, IRQF_TRIGGER_HIGH);
  450. irq_set_irq_type(md_ctrl->md_wdt_irq_id, IRQF_TRIGGER_FALLING);
  451. #endif
  452. return 0;
  453. }
  454. void ccci_modem_restore_reg(struct ccci_modem *md)
  455. {
  456. struct md_cd_ctrl *md_ctrl = (struct md_cd_ctrl *)md->private_data;
  457. int i;
  458. unsigned long flags;
  459. if (md->md_state == GATED || md->md_state == RESET || md->md_state == INVALID) {
  460. CCCI_DBG_MSG(md->index, TAG, "Resume no need reset cldma for md_state=%d\n", md->md_state);
  461. return;
  462. }
  463. cldma_write32(md_ctrl->ap_ccif_base, APCCIF_CON, 0x01); /* arbitration */
  464. if (cldma_read32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_TQSAR(0))) {
  465. CCCI_DBG_MSG(md->index, TAG, "Resume cldma pdn register: No need ...\n");
  466. } else {
  467. CCCI_DBG_MSG(md->index, TAG, "Resume cldma pdn register ...11\n");
  468. spin_lock_irqsave(&md_ctrl->cldma_timeout_lock, flags);
  469. cldma_write32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_HPQR, 0x00);
  470. /* set checksum */
  471. switch (CHECKSUM_SIZE) {
  472. case 0:
  473. cldma_write32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_UL_CHECKSUM_CHANNEL_ENABLE, 0);
  474. break;
  475. case 12:
  476. cldma_write32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_UL_CHECKSUM_CHANNEL_ENABLE,
  477. CLDMA_BM_ALL_QUEUE);
  478. cldma_write32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_UL_CFG,
  479. cldma_read32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_UL_CFG) & ~0x10);
  480. break;
  481. case 16:
  482. cldma_write32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_UL_CHECKSUM_CHANNEL_ENABLE,
  483. CLDMA_BM_ALL_QUEUE);
  484. cldma_write32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_UL_CFG,
  485. cldma_read32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_UL_CFG) | 0x10);
  486. break;
  487. }
  488. /* set start address */
  489. for (i = 0; i < QUEUE_LEN(md_ctrl->txq); i++) {
  490. if (cldma_read32(md_ctrl->cldma_ap_ao_base, CLDMA_AP_TQCPBAK(md_ctrl->txq[i].index)) == 0) {
  491. CCCI_DBG_MSG(md->index, TAG, "Resume CH(%d) current bak:== 0\n", i);
  492. cldma_write32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_TQSAR(md_ctrl->txq[i].index),
  493. md_ctrl->txq[i].tr_done->gpd_addr);
  494. cldma_write32(md_ctrl->cldma_ap_ao_base, CLDMA_AP_TQSABAK(md_ctrl->txq[i].index),
  495. md_ctrl->txq[i].tr_done->gpd_addr);
  496. } else {
  497. cldma_write32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_TQSAR(md_ctrl->txq[i].index),
  498. cldma_read32(md_ctrl->cldma_ap_ao_base,
  499. CLDMA_AP_TQCPBAK(md_ctrl->txq[i].index)));
  500. cldma_write32(md_ctrl->cldma_ap_ao_base, CLDMA_AP_TQSABAK(md_ctrl->txq[i].index),
  501. cldma_read32(md_ctrl->cldma_ap_ao_base,
  502. CLDMA_AP_TQCPBAK(md_ctrl->txq[i].index)));
  503. }
  504. }
  505. /* wait write done*/
  506. wmb();
  507. /* start all Tx and Rx queues */
  508. cldma_write32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_UL_START_CMD, CLDMA_BM_ALL_QUEUE);
  509. cldma_read32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_UL_START_CMD); /* dummy read */
  510. md_ctrl->txq_active |= CLDMA_BM_ALL_QUEUE;
  511. /* cldma_write32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_SO_START_CMD, CLDMA_BM_ALL_QUEUE); */
  512. /* cldma_read32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_SO_START_CMD); // dummy read */
  513. /* md_ctrl->rxq_active |= CLDMA_BM_ALL_QUEUE; */
  514. /* enable L2 DONE and ERROR interrupts */
  515. cldma_write32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_L2TIMCR0, CLDMA_BM_INT_DONE | CLDMA_BM_INT_ERROR);
  516. /* enable all L3 interrupts */
  517. cldma_write32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_L3TIMCR0, CLDMA_BM_INT_ALL);
  518. cldma_write32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_L3TIMCR1, CLDMA_BM_INT_ALL);
  519. cldma_write32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_L3RIMCR0, CLDMA_BM_INT_ALL);
  520. cldma_write32(md_ctrl->cldma_ap_pdn_base, CLDMA_AP_L3RIMCR1, CLDMA_BM_INT_ALL);
  521. spin_unlock_irqrestore(&md_ctrl->cldma_timeout_lock, flags);
  522. CCCI_DBG_MSG(md->index, TAG, "Resume cldma pdn register done\n");
  523. }
  524. }
  525. int ccci_modem_syssuspend(void)
  526. {
  527. CCCI_DBG_MSG(0, TAG, "ccci_modem_syssuspend\n");
  528. return 0;
  529. }
  530. void ccci_modem_sysresume(void)
  531. {
  532. struct ccci_modem *md;
  533. CCCI_DBG_MSG(0, TAG, "ccci_modem_sysresume\n");
  534. md = ccci_get_modem_by_id(0);
  535. if (md != NULL)
  536. ccci_modem_restore_reg(md);
  537. }