power.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include <linux/clk.h>
  7. #include <linux/delay.h>
  8. #if IS_ENABLED(CONFIG_MSM_QMP)
  9. #include <linux/mailbox/qmp.h>
  10. #endif
  11. #include <linux/of.h>
  12. #include <linux/of_gpio.h>
  13. #include <linux/pinctrl/consumer.h>
  14. #include <linux/regulator/consumer.h>
  15. #if IS_ENABLED(CONFIG_QCOM_COMMAND_DB)
  16. #include <soc/qcom/cmd-db.h>
  17. #endif
  18. #include "main.h"
  19. #include "debug.h"
  20. #include "bus.h"
  21. #if IS_ENABLED(CONFIG_ARCH_QCOM)
  22. static struct cnss_vreg_cfg cnss_vreg_list[] = {
  23. {"vdd-wlan-core", 1300000, 1300000, 0, 0, 0},
  24. {"vdd-wlan-io", 1800000, 1800000, 0, 0, 0},
  25. {"vdd-wlan-xtal-aon", 0, 0, 0, 0, 0},
  26. {"vdd-wlan-xtal", 1800000, 1800000, 0, 2, 0},
  27. {"vdd-wlan", 0, 0, 0, 0, 0},
  28. {"vdd-wlan-ctrl1", 0, 0, 0, 0, 0},
  29. {"vdd-wlan-ctrl2", 0, 0, 0, 0, 0},
  30. {"vdd-wlan-sp2t", 2700000, 2700000, 0, 0, 0},
  31. {"wlan-ant-switch", 1800000, 1800000, 0, 0, 0},
  32. {"wlan-soc-swreg", 1200000, 1200000, 0, 0, 0},
  33. {"vdd-wlan-aon", 950000, 950000, 0, 0, 0},
  34. {"vdd-wlan-dig", 950000, 952000, 0, 0, 0},
  35. {"vdd-wlan-rfa1", 1900000, 1900000, 0, 0, 0},
  36. {"vdd-wlan-rfa2", 1350000, 1350000, 0, 0, 0},
  37. {"vdd-wlan-rfa3", 1900000, 1900000, 450000, 0, 0},
  38. {"alt-sleep-clk", 0, 0, 0, 0, 0},
  39. {"vdd-wlan-en", 0, 0, 0, 10, 0},
  40. };
  41. static struct cnss_clk_cfg cnss_clk_list[] = {
  42. {"rf_clk", 0, 0},
  43. };
  44. #else
  45. static struct cnss_vreg_cfg cnss_vreg_list[] = {
  46. };
  47. static struct cnss_clk_cfg cnss_clk_list[] = {
  48. };
  49. #endif
  50. #define CNSS_VREG_INFO_SIZE ARRAY_SIZE(cnss_vreg_list)
  51. #define CNSS_CLK_INFO_SIZE ARRAY_SIZE(cnss_clk_list)
  52. #define MAX_PROP_SIZE 32
  53. #define BOOTSTRAP_GPIO "qcom,enable-bootstrap-gpio"
  54. #define BOOTSTRAP_ACTIVE "bootstrap_active"
  55. #define HOST_SOL_GPIO "wlan-host-sol-gpio"
  56. #define DEV_SOL_GPIO "wlan-dev-sol-gpio"
  57. #define SOL_DEFAULT "sol_default"
  58. #define WLAN_EN_GPIO "wlan-en-gpio"
  59. #define BT_EN_GPIO "qcom,bt-en-gpio"
  60. #define XO_CLK_GPIO "qcom,xo-clk-gpio"
  61. #define WLAN_EN_ACTIVE "wlan_en_active"
  62. #define WLAN_EN_SLEEP "wlan_en_sleep"
  63. #define BOOTSTRAP_DELAY 1000
  64. #define WLAN_ENABLE_DELAY 1000
  65. #define TCS_CMD_DATA_ADDR_OFFSET 0x4
  66. #define TCS_OFFSET 0xC8
  67. #define TCS_CMD_OFFSET 0x10
  68. #define MAX_TCS_NUM 8
  69. #define MAX_TCS_CMD_NUM 5
  70. #define BT_CXMX_VOLTAGE_MV 950
  71. #define CNSS_MBOX_MSG_MAX_LEN 64
  72. #define CNSS_MBOX_TIMEOUT_MS 1000
  73. /**
  74. * enum cnss_vreg_param: Voltage regulator TCS param
  75. * @CNSS_VREG_VOLTAGE: Provides voltage level to be configured in TCS
  76. * @CNSS_VREG_MODE: Regulator mode
  77. * @CNSS_VREG_TCS_ENABLE: Set Voltage regulator enable config in TCS
  78. */
  79. enum cnss_vreg_param {
  80. CNSS_VREG_VOLTAGE,
  81. CNSS_VREG_MODE,
  82. CNSS_VREG_ENABLE,
  83. };
  84. /**
  85. * enum cnss_tcs_seq: TCS sequence ID for trigger
  86. * CNSS_TCS_UP_SEQ: TCS Sequence based on up trigger / Wake TCS
  87. * CNSS_TCS_DOWN_SEQ: TCS Sequence based on down trigger / Sleep TCS
  88. * CNSS_TCS_ALL_SEQ: Update for both up and down triggers
  89. */
  90. enum cnss_tcs_seq {
  91. CNSS_TCS_UP_SEQ,
  92. CNSS_TCS_DOWN_SEQ,
  93. CNSS_TCS_ALL_SEQ,
  94. };
  95. static int cnss_get_vreg_single(struct cnss_plat_data *plat_priv,
  96. struct cnss_vreg_info *vreg)
  97. {
  98. int ret = 0;
  99. struct device *dev;
  100. struct regulator *reg;
  101. const __be32 *prop;
  102. char prop_name[MAX_PROP_SIZE] = {0};
  103. int len;
  104. dev = &plat_priv->plat_dev->dev;
  105. reg = devm_regulator_get_optional(dev, vreg->cfg.name);
  106. if (IS_ERR(reg)) {
  107. ret = PTR_ERR(reg);
  108. if (ret == -ENODEV)
  109. return ret;
  110. else if (ret == -EPROBE_DEFER)
  111. cnss_pr_info("EPROBE_DEFER for regulator: %s\n",
  112. vreg->cfg.name);
  113. else
  114. cnss_pr_err("Failed to get regulator %s, err = %d\n",
  115. vreg->cfg.name, ret);
  116. return ret;
  117. }
  118. vreg->reg = reg;
  119. snprintf(prop_name, MAX_PROP_SIZE, "qcom,%s-config",
  120. vreg->cfg.name);
  121. prop = of_get_property(dev->of_node, prop_name, &len);
  122. if (!prop || len != (5 * sizeof(__be32))) {
  123. cnss_pr_dbg("Property %s %s, use default\n", prop_name,
  124. prop ? "invalid format" : "doesn't exist");
  125. } else {
  126. vreg->cfg.min_uv = be32_to_cpup(&prop[0]);
  127. vreg->cfg.max_uv = be32_to_cpup(&prop[1]);
  128. vreg->cfg.load_ua = be32_to_cpup(&prop[2]);
  129. vreg->cfg.delay_us = be32_to_cpup(&prop[3]);
  130. vreg->cfg.need_unvote = be32_to_cpup(&prop[4]);
  131. }
  132. cnss_pr_dbg("Got regulator: %s, min_uv: %u, max_uv: %u, load_ua: %u, delay_us: %u, need_unvote: %u\n",
  133. vreg->cfg.name, vreg->cfg.min_uv,
  134. vreg->cfg.max_uv, vreg->cfg.load_ua,
  135. vreg->cfg.delay_us, vreg->cfg.need_unvote);
  136. return 0;
  137. }
  138. static void cnss_put_vreg_single(struct cnss_plat_data *plat_priv,
  139. struct cnss_vreg_info *vreg)
  140. {
  141. struct device *dev = &plat_priv->plat_dev->dev;
  142. cnss_pr_dbg("Put regulator: %s\n", vreg->cfg.name);
  143. devm_regulator_put(vreg->reg);
  144. devm_kfree(dev, vreg);
  145. }
  146. static int cnss_vreg_on_single(struct cnss_vreg_info *vreg)
  147. {
  148. int ret = 0;
  149. if (vreg->enabled) {
  150. cnss_pr_dbg("Regulator %s is already enabled\n",
  151. vreg->cfg.name);
  152. return 0;
  153. }
  154. cnss_pr_dbg("Regulator %s is being enabled\n", vreg->cfg.name);
  155. if (vreg->cfg.min_uv != 0 && vreg->cfg.max_uv != 0) {
  156. ret = regulator_set_voltage(vreg->reg,
  157. vreg->cfg.min_uv,
  158. vreg->cfg.max_uv);
  159. if (ret) {
  160. cnss_pr_err("Failed to set voltage for regulator %s, min_uv: %u, max_uv: %u, err = %d\n",
  161. vreg->cfg.name, vreg->cfg.min_uv,
  162. vreg->cfg.max_uv, ret);
  163. goto out;
  164. }
  165. }
  166. if (vreg->cfg.load_ua) {
  167. ret = regulator_set_load(vreg->reg,
  168. vreg->cfg.load_ua);
  169. if (ret < 0) {
  170. cnss_pr_err("Failed to set load for regulator %s, load: %u, err = %d\n",
  171. vreg->cfg.name, vreg->cfg.load_ua,
  172. ret);
  173. goto out;
  174. }
  175. }
  176. if (vreg->cfg.delay_us)
  177. udelay(vreg->cfg.delay_us);
  178. ret = regulator_enable(vreg->reg);
  179. if (ret) {
  180. cnss_pr_err("Failed to enable regulator %s, err = %d\n",
  181. vreg->cfg.name, ret);
  182. goto out;
  183. }
  184. vreg->enabled = true;
  185. out:
  186. return ret;
  187. }
  188. static int cnss_vreg_unvote_single(struct cnss_vreg_info *vreg)
  189. {
  190. int ret = 0;
  191. if (!vreg->enabled) {
  192. cnss_pr_dbg("Regulator %s is already disabled\n",
  193. vreg->cfg.name);
  194. return 0;
  195. }
  196. cnss_pr_dbg("Removing vote for Regulator %s\n", vreg->cfg.name);
  197. if (vreg->cfg.load_ua) {
  198. ret = regulator_set_load(vreg->reg, 0);
  199. if (ret < 0)
  200. cnss_pr_err("Failed to set load for regulator %s, err = %d\n",
  201. vreg->cfg.name, ret);
  202. }
  203. if (vreg->cfg.min_uv != 0 && vreg->cfg.max_uv != 0) {
  204. ret = regulator_set_voltage(vreg->reg, 0,
  205. vreg->cfg.max_uv);
  206. if (ret)
  207. cnss_pr_err("Failed to set voltage for regulator %s, err = %d\n",
  208. vreg->cfg.name, ret);
  209. }
  210. return ret;
  211. }
  212. static int cnss_vreg_off_single(struct cnss_vreg_info *vreg)
  213. {
  214. int ret = 0;
  215. if (!vreg->enabled) {
  216. cnss_pr_dbg("Regulator %s is already disabled\n",
  217. vreg->cfg.name);
  218. return 0;
  219. }
  220. cnss_pr_dbg("Regulator %s is being disabled\n",
  221. vreg->cfg.name);
  222. ret = regulator_disable(vreg->reg);
  223. if (ret)
  224. cnss_pr_err("Failed to disable regulator %s, err = %d\n",
  225. vreg->cfg.name, ret);
  226. if (vreg->cfg.load_ua) {
  227. ret = regulator_set_load(vreg->reg, 0);
  228. if (ret < 0)
  229. cnss_pr_err("Failed to set load for regulator %s, err = %d\n",
  230. vreg->cfg.name, ret);
  231. }
  232. if (vreg->cfg.min_uv != 0 && vreg->cfg.max_uv != 0) {
  233. ret = regulator_set_voltage(vreg->reg, 0,
  234. vreg->cfg.max_uv);
  235. if (ret)
  236. cnss_pr_err("Failed to set voltage for regulator %s, err = %d\n",
  237. vreg->cfg.name, ret);
  238. }
  239. vreg->enabled = false;
  240. return ret;
  241. }
  242. static struct cnss_vreg_cfg *get_vreg_list(u32 *vreg_list_size,
  243. enum cnss_vreg_type type)
  244. {
  245. switch (type) {
  246. case CNSS_VREG_PRIM:
  247. *vreg_list_size = CNSS_VREG_INFO_SIZE;
  248. return cnss_vreg_list;
  249. default:
  250. cnss_pr_err("Unsupported vreg type 0x%x\n", type);
  251. *vreg_list_size = 0;
  252. return NULL;
  253. }
  254. }
  255. static int cnss_get_vreg(struct cnss_plat_data *plat_priv,
  256. struct list_head *vreg_list,
  257. struct cnss_vreg_cfg *vreg_cfg,
  258. u32 vreg_list_size)
  259. {
  260. int ret = 0;
  261. int i;
  262. struct cnss_vreg_info *vreg;
  263. struct device *dev = &plat_priv->plat_dev->dev;
  264. if (!list_empty(vreg_list)) {
  265. cnss_pr_dbg("Vregs have already been updated\n");
  266. return 0;
  267. }
  268. for (i = 0; i < vreg_list_size; i++) {
  269. vreg = devm_kzalloc(dev, sizeof(*vreg), GFP_KERNEL);
  270. if (!vreg)
  271. return -ENOMEM;
  272. memcpy(&vreg->cfg, &vreg_cfg[i], sizeof(vreg->cfg));
  273. ret = cnss_get_vreg_single(plat_priv, vreg);
  274. if (ret != 0) {
  275. if (ret == -ENODEV) {
  276. devm_kfree(dev, vreg);
  277. continue;
  278. } else {
  279. devm_kfree(dev, vreg);
  280. return ret;
  281. }
  282. }
  283. list_add_tail(&vreg->list, vreg_list);
  284. }
  285. return 0;
  286. }
  287. static void cnss_put_vreg(struct cnss_plat_data *plat_priv,
  288. struct list_head *vreg_list)
  289. {
  290. struct cnss_vreg_info *vreg;
  291. while (!list_empty(vreg_list)) {
  292. vreg = list_first_entry(vreg_list,
  293. struct cnss_vreg_info, list);
  294. list_del(&vreg->list);
  295. if (IS_ERR_OR_NULL(vreg->reg))
  296. continue;
  297. cnss_put_vreg_single(plat_priv, vreg);
  298. }
  299. }
  300. static int cnss_vreg_on(struct cnss_plat_data *plat_priv,
  301. struct list_head *vreg_list)
  302. {
  303. struct cnss_vreg_info *vreg;
  304. int ret = 0;
  305. list_for_each_entry(vreg, vreg_list, list) {
  306. if (IS_ERR_OR_NULL(vreg->reg))
  307. continue;
  308. ret = cnss_vreg_on_single(vreg);
  309. if (ret)
  310. break;
  311. }
  312. if (!ret)
  313. return 0;
  314. list_for_each_entry_continue_reverse(vreg, vreg_list, list) {
  315. if (IS_ERR_OR_NULL(vreg->reg) || !vreg->enabled)
  316. continue;
  317. cnss_vreg_off_single(vreg);
  318. }
  319. return ret;
  320. }
  321. static int cnss_vreg_off(struct cnss_plat_data *plat_priv,
  322. struct list_head *vreg_list)
  323. {
  324. struct cnss_vreg_info *vreg;
  325. list_for_each_entry_reverse(vreg, vreg_list, list) {
  326. if (IS_ERR_OR_NULL(vreg->reg))
  327. continue;
  328. cnss_vreg_off_single(vreg);
  329. }
  330. return 0;
  331. }
  332. static int cnss_vreg_unvote(struct cnss_plat_data *plat_priv,
  333. struct list_head *vreg_list)
  334. {
  335. struct cnss_vreg_info *vreg;
  336. list_for_each_entry_reverse(vreg, vreg_list, list) {
  337. if (IS_ERR_OR_NULL(vreg->reg))
  338. continue;
  339. if (vreg->cfg.need_unvote)
  340. cnss_vreg_unvote_single(vreg);
  341. }
  342. return 0;
  343. }
  344. int cnss_get_vreg_type(struct cnss_plat_data *plat_priv,
  345. enum cnss_vreg_type type)
  346. {
  347. struct cnss_vreg_cfg *vreg_cfg;
  348. u32 vreg_list_size = 0;
  349. int ret = 0;
  350. vreg_cfg = get_vreg_list(&vreg_list_size, type);
  351. if (!vreg_cfg)
  352. return -EINVAL;
  353. switch (type) {
  354. case CNSS_VREG_PRIM:
  355. ret = cnss_get_vreg(plat_priv, &plat_priv->vreg_list,
  356. vreg_cfg, vreg_list_size);
  357. break;
  358. default:
  359. cnss_pr_err("Unsupported vreg type 0x%x\n", type);
  360. return -EINVAL;
  361. }
  362. return ret;
  363. }
  364. void cnss_put_vreg_type(struct cnss_plat_data *plat_priv,
  365. enum cnss_vreg_type type)
  366. {
  367. switch (type) {
  368. case CNSS_VREG_PRIM:
  369. cnss_put_vreg(plat_priv, &plat_priv->vreg_list);
  370. break;
  371. default:
  372. return;
  373. }
  374. }
  375. int cnss_vreg_on_type(struct cnss_plat_data *plat_priv,
  376. enum cnss_vreg_type type)
  377. {
  378. int ret = 0;
  379. switch (type) {
  380. case CNSS_VREG_PRIM:
  381. ret = cnss_vreg_on(plat_priv, &plat_priv->vreg_list);
  382. break;
  383. default:
  384. cnss_pr_err("Unsupported vreg type 0x%x\n", type);
  385. return -EINVAL;
  386. }
  387. return ret;
  388. }
  389. int cnss_vreg_off_type(struct cnss_plat_data *plat_priv,
  390. enum cnss_vreg_type type)
  391. {
  392. int ret = 0;
  393. switch (type) {
  394. case CNSS_VREG_PRIM:
  395. ret = cnss_vreg_off(plat_priv, &plat_priv->vreg_list);
  396. break;
  397. default:
  398. cnss_pr_err("Unsupported vreg type 0x%x\n", type);
  399. return -EINVAL;
  400. }
  401. return ret;
  402. }
  403. int cnss_vreg_unvote_type(struct cnss_plat_data *plat_priv,
  404. enum cnss_vreg_type type)
  405. {
  406. int ret = 0;
  407. switch (type) {
  408. case CNSS_VREG_PRIM:
  409. ret = cnss_vreg_unvote(plat_priv, &plat_priv->vreg_list);
  410. break;
  411. default:
  412. cnss_pr_err("Unsupported vreg type 0x%x\n", type);
  413. return -EINVAL;
  414. }
  415. return ret;
  416. }
  417. static int cnss_get_clk_single(struct cnss_plat_data *plat_priv,
  418. struct cnss_clk_info *clk_info)
  419. {
  420. struct device *dev = &plat_priv->plat_dev->dev;
  421. struct clk *clk;
  422. int ret;
  423. clk = devm_clk_get(dev, clk_info->cfg.name);
  424. if (IS_ERR(clk)) {
  425. ret = PTR_ERR(clk);
  426. if (clk_info->cfg.required)
  427. cnss_pr_err("Failed to get clock %s, err = %d\n",
  428. clk_info->cfg.name, ret);
  429. else
  430. cnss_pr_dbg("Failed to get optional clock %s, err = %d\n",
  431. clk_info->cfg.name, ret);
  432. return ret;
  433. }
  434. clk_info->clk = clk;
  435. cnss_pr_dbg("Got clock: %s, freq: %u\n",
  436. clk_info->cfg.name, clk_info->cfg.freq);
  437. return 0;
  438. }
  439. static void cnss_put_clk_single(struct cnss_plat_data *plat_priv,
  440. struct cnss_clk_info *clk_info)
  441. {
  442. struct device *dev = &plat_priv->plat_dev->dev;
  443. cnss_pr_dbg("Put clock: %s\n", clk_info->cfg.name);
  444. devm_clk_put(dev, clk_info->clk);
  445. }
  446. static int cnss_clk_on_single(struct cnss_clk_info *clk_info)
  447. {
  448. int ret;
  449. if (clk_info->enabled) {
  450. cnss_pr_dbg("Clock %s is already enabled\n",
  451. clk_info->cfg.name);
  452. return 0;
  453. }
  454. cnss_pr_dbg("Clock %s is being enabled\n", clk_info->cfg.name);
  455. if (clk_info->cfg.freq) {
  456. ret = clk_set_rate(clk_info->clk, clk_info->cfg.freq);
  457. if (ret) {
  458. cnss_pr_err("Failed to set frequency %u for clock %s, err = %d\n",
  459. clk_info->cfg.freq, clk_info->cfg.name,
  460. ret);
  461. return ret;
  462. }
  463. }
  464. ret = clk_prepare_enable(clk_info->clk);
  465. if (ret) {
  466. cnss_pr_err("Failed to enable clock %s, err = %d\n",
  467. clk_info->cfg.name, ret);
  468. return ret;
  469. }
  470. clk_info->enabled = true;
  471. return 0;
  472. }
  473. static int cnss_clk_off_single(struct cnss_clk_info *clk_info)
  474. {
  475. if (!clk_info->enabled) {
  476. cnss_pr_dbg("Clock %s is already disabled\n",
  477. clk_info->cfg.name);
  478. return 0;
  479. }
  480. cnss_pr_dbg("Clock %s is being disabled\n", clk_info->cfg.name);
  481. clk_disable_unprepare(clk_info->clk);
  482. clk_info->enabled = false;
  483. return 0;
  484. }
  485. int cnss_get_clk(struct cnss_plat_data *plat_priv)
  486. {
  487. struct device *dev;
  488. struct list_head *clk_list;
  489. struct cnss_clk_info *clk_info;
  490. int ret, i;
  491. if (!plat_priv)
  492. return -ENODEV;
  493. dev = &plat_priv->plat_dev->dev;
  494. clk_list = &plat_priv->clk_list;
  495. if (!list_empty(clk_list)) {
  496. cnss_pr_dbg("Clocks have already been updated\n");
  497. return 0;
  498. }
  499. for (i = 0; i < CNSS_CLK_INFO_SIZE; i++) {
  500. clk_info = devm_kzalloc(dev, sizeof(*clk_info), GFP_KERNEL);
  501. if (!clk_info) {
  502. ret = -ENOMEM;
  503. goto cleanup;
  504. }
  505. memcpy(&clk_info->cfg, &cnss_clk_list[i],
  506. sizeof(clk_info->cfg));
  507. ret = cnss_get_clk_single(plat_priv, clk_info);
  508. if (ret != 0) {
  509. if (clk_info->cfg.required) {
  510. devm_kfree(dev, clk_info);
  511. goto cleanup;
  512. } else {
  513. devm_kfree(dev, clk_info);
  514. continue;
  515. }
  516. }
  517. list_add_tail(&clk_info->list, clk_list);
  518. }
  519. return 0;
  520. cleanup:
  521. while (!list_empty(clk_list)) {
  522. clk_info = list_first_entry(clk_list, struct cnss_clk_info,
  523. list);
  524. list_del(&clk_info->list);
  525. if (IS_ERR_OR_NULL(clk_info->clk))
  526. continue;
  527. cnss_put_clk_single(plat_priv, clk_info);
  528. devm_kfree(dev, clk_info);
  529. }
  530. return ret;
  531. }
  532. void cnss_put_clk(struct cnss_plat_data *plat_priv)
  533. {
  534. struct device *dev;
  535. struct list_head *clk_list;
  536. struct cnss_clk_info *clk_info;
  537. if (!plat_priv)
  538. return;
  539. dev = &plat_priv->plat_dev->dev;
  540. clk_list = &plat_priv->clk_list;
  541. while (!list_empty(clk_list)) {
  542. clk_info = list_first_entry(clk_list, struct cnss_clk_info,
  543. list);
  544. list_del(&clk_info->list);
  545. if (IS_ERR_OR_NULL(clk_info->clk))
  546. continue;
  547. cnss_put_clk_single(plat_priv, clk_info);
  548. devm_kfree(dev, clk_info);
  549. }
  550. }
  551. static int cnss_clk_on(struct cnss_plat_data *plat_priv,
  552. struct list_head *clk_list)
  553. {
  554. struct cnss_clk_info *clk_info;
  555. int ret = 0;
  556. list_for_each_entry(clk_info, clk_list, list) {
  557. if (IS_ERR_OR_NULL(clk_info->clk))
  558. continue;
  559. ret = cnss_clk_on_single(clk_info);
  560. if (ret)
  561. break;
  562. }
  563. if (!ret)
  564. return 0;
  565. list_for_each_entry_continue_reverse(clk_info, clk_list, list) {
  566. if (IS_ERR_OR_NULL(clk_info->clk))
  567. continue;
  568. cnss_clk_off_single(clk_info);
  569. }
  570. return ret;
  571. }
  572. static int cnss_clk_off(struct cnss_plat_data *plat_priv,
  573. struct list_head *clk_list)
  574. {
  575. struct cnss_clk_info *clk_info;
  576. list_for_each_entry_reverse(clk_info, clk_list, list) {
  577. if (IS_ERR_OR_NULL(clk_info->clk))
  578. continue;
  579. cnss_clk_off_single(clk_info);
  580. }
  581. return 0;
  582. }
  583. int cnss_get_pinctrl(struct cnss_plat_data *plat_priv)
  584. {
  585. int ret = 0;
  586. struct device *dev;
  587. struct cnss_pinctrl_info *pinctrl_info;
  588. dev = &plat_priv->plat_dev->dev;
  589. pinctrl_info = &plat_priv->pinctrl_info;
  590. pinctrl_info->pinctrl = devm_pinctrl_get(dev);
  591. if (IS_ERR_OR_NULL(pinctrl_info->pinctrl)) {
  592. ret = PTR_ERR(pinctrl_info->pinctrl);
  593. cnss_pr_err("Failed to get pinctrl, err = %d\n", ret);
  594. goto out;
  595. }
  596. if (of_find_property(dev->of_node, BOOTSTRAP_GPIO, NULL)) {
  597. pinctrl_info->bootstrap_active =
  598. pinctrl_lookup_state(pinctrl_info->pinctrl,
  599. BOOTSTRAP_ACTIVE);
  600. if (IS_ERR_OR_NULL(pinctrl_info->bootstrap_active)) {
  601. ret = PTR_ERR(pinctrl_info->bootstrap_active);
  602. cnss_pr_err("Failed to get bootstrap active state, err = %d\n",
  603. ret);
  604. goto out;
  605. }
  606. }
  607. if (of_find_property(dev->of_node, HOST_SOL_GPIO, NULL) &&
  608. of_find_property(dev->of_node, DEV_SOL_GPIO, NULL)) {
  609. pinctrl_info->sol_default =
  610. pinctrl_lookup_state(pinctrl_info->pinctrl,
  611. SOL_DEFAULT);
  612. if (IS_ERR_OR_NULL(pinctrl_info->sol_default)) {
  613. ret = PTR_ERR(pinctrl_info->sol_default);
  614. cnss_pr_err("Failed to get sol default state, err = %d\n",
  615. ret);
  616. goto out;
  617. }
  618. cnss_pr_dbg("Got sol default state\n");
  619. }
  620. if (of_find_property(dev->of_node, WLAN_EN_GPIO, NULL)) {
  621. pinctrl_info->wlan_en_active =
  622. pinctrl_lookup_state(pinctrl_info->pinctrl,
  623. WLAN_EN_ACTIVE);
  624. if (IS_ERR_OR_NULL(pinctrl_info->wlan_en_active)) {
  625. ret = PTR_ERR(pinctrl_info->wlan_en_active);
  626. cnss_pr_err("Failed to get wlan_en active state, err = %d\n",
  627. ret);
  628. goto out;
  629. }
  630. pinctrl_info->wlan_en_sleep =
  631. pinctrl_lookup_state(pinctrl_info->pinctrl,
  632. WLAN_EN_SLEEP);
  633. if (IS_ERR_OR_NULL(pinctrl_info->wlan_en_sleep)) {
  634. ret = PTR_ERR(pinctrl_info->wlan_en_sleep);
  635. cnss_pr_err("Failed to get wlan_en sleep state, err = %d\n",
  636. ret);
  637. goto out;
  638. }
  639. }
  640. /* Added for QCA6490 PMU delayed WLAN_EN_GPIO */
  641. if (of_find_property(dev->of_node, BT_EN_GPIO, NULL)) {
  642. pinctrl_info->bt_en_gpio = of_get_named_gpio(dev->of_node,
  643. BT_EN_GPIO, 0);
  644. cnss_pr_dbg("BT GPIO: %d\n", pinctrl_info->bt_en_gpio);
  645. } else {
  646. pinctrl_info->bt_en_gpio = -EINVAL;
  647. }
  648. /* Added for QCA6490 to minimize XO CLK selection leakage prevention */
  649. if (of_find_property(dev->of_node, XO_CLK_GPIO, NULL)) {
  650. pinctrl_info->xo_clk_gpio = of_get_named_gpio(dev->of_node,
  651. XO_CLK_GPIO, 0);
  652. cnss_pr_dbg("QCA6490 XO_CLK GPIO: %d\n",
  653. pinctrl_info->xo_clk_gpio);
  654. cnss_set_feature_list(plat_priv, BOOTSTRAP_CLOCK_SELECT_V01);
  655. } else {
  656. pinctrl_info->xo_clk_gpio = -EINVAL;
  657. }
  658. return 0;
  659. out:
  660. return ret;
  661. }
  662. #define CNSS_XO_CLK_RETRY_COUNT_MAX 5
  663. static void cnss_set_xo_clk_gpio_state(struct cnss_plat_data *plat_priv,
  664. bool enable)
  665. {
  666. int xo_clk_gpio = plat_priv->pinctrl_info.xo_clk_gpio, retry = 0, ret;
  667. if (xo_clk_gpio < 0 || plat_priv->device_id != QCA6490_DEVICE_ID)
  668. return;
  669. retry_gpio_req:
  670. ret = gpio_request(xo_clk_gpio, "XO_CLK_GPIO");
  671. if (ret) {
  672. if (retry++ < CNSS_XO_CLK_RETRY_COUNT_MAX) {
  673. /* wait for ~(10 - 20) ms */
  674. usleep_range(10000, 20000);
  675. goto retry_gpio_req;
  676. }
  677. }
  678. if (ret) {
  679. cnss_pr_err("QCA6490 XO CLK Gpio request failed\n");
  680. return;
  681. }
  682. if (enable) {
  683. gpio_direction_output(xo_clk_gpio, 1);
  684. /*XO CLK must be asserted for some time before WLAN_EN */
  685. usleep_range(100, 200);
  686. } else {
  687. /* Assert XO CLK ~(2-5)ms before off for valid latch in HW */
  688. usleep_range(2000, 5000);
  689. gpio_direction_output(xo_clk_gpio, 0);
  690. }
  691. gpio_free(xo_clk_gpio);
  692. }
  693. static int cnss_select_pinctrl_state(struct cnss_plat_data *plat_priv,
  694. bool state)
  695. {
  696. int ret = 0;
  697. struct cnss_pinctrl_info *pinctrl_info;
  698. if (!plat_priv) {
  699. cnss_pr_err("plat_priv is NULL!\n");
  700. ret = -ENODEV;
  701. goto out;
  702. }
  703. pinctrl_info = &plat_priv->pinctrl_info;
  704. if (state) {
  705. if (!IS_ERR_OR_NULL(pinctrl_info->bootstrap_active)) {
  706. ret = pinctrl_select_state
  707. (pinctrl_info->pinctrl,
  708. pinctrl_info->bootstrap_active);
  709. if (ret) {
  710. cnss_pr_err("Failed to select bootstrap active state, err = %d\n",
  711. ret);
  712. goto out;
  713. }
  714. udelay(BOOTSTRAP_DELAY);
  715. }
  716. if (!IS_ERR_OR_NULL(pinctrl_info->sol_default)) {
  717. ret = pinctrl_select_state
  718. (pinctrl_info->pinctrl,
  719. pinctrl_info->sol_default);
  720. if (ret) {
  721. cnss_pr_err("Failed to select sol default state, err = %d\n",
  722. ret);
  723. goto out;
  724. }
  725. cnss_pr_dbg("Selected sol default state\n");
  726. }
  727. cnss_set_xo_clk_gpio_state(plat_priv, true);
  728. if (!IS_ERR_OR_NULL(pinctrl_info->wlan_en_active)) {
  729. ret = pinctrl_select_state
  730. (pinctrl_info->pinctrl,
  731. pinctrl_info->wlan_en_active);
  732. if (ret) {
  733. cnss_pr_err("Failed to select wlan_en active state, err = %d\n",
  734. ret);
  735. goto out;
  736. }
  737. udelay(WLAN_ENABLE_DELAY);
  738. }
  739. cnss_set_xo_clk_gpio_state(plat_priv, false);
  740. } else {
  741. if (!IS_ERR_OR_NULL(pinctrl_info->wlan_en_sleep)) {
  742. ret = pinctrl_select_state(pinctrl_info->pinctrl,
  743. pinctrl_info->wlan_en_sleep);
  744. if (ret) {
  745. cnss_pr_err("Failed to select wlan_en sleep state, err = %d\n",
  746. ret);
  747. goto out;
  748. }
  749. }
  750. }
  751. cnss_pr_dbg("%s WLAN_EN GPIO successfully\n",
  752. state ? "Assert" : "De-assert");
  753. return 0;
  754. out:
  755. return ret;
  756. }
  757. /**
  758. * cnss_select_pinctrl_enable - select WLAN_GPIO for Active pinctrl status
  759. * @plat_priv: Platform private data structure pointer
  760. *
  761. * For QCA6490, PMU requires minimum 100ms delay between BT_EN_GPIO off and
  762. * WLAN_EN_GPIO on. This is done to avoid power up issues.
  763. *
  764. * Return: Status of pinctrl select operation. 0 - Success.
  765. */
  766. static int cnss_select_pinctrl_enable(struct cnss_plat_data *plat_priv)
  767. {
  768. int ret = 0, bt_en_gpio = plat_priv->pinctrl_info.bt_en_gpio;
  769. u8 wlan_en_state = 0;
  770. if (bt_en_gpio < 0 || plat_priv->device_id != QCA6490_DEVICE_ID)
  771. goto set_wlan_en;
  772. if (gpio_get_value(bt_en_gpio)) {
  773. cnss_pr_dbg("BT_EN_GPIO State: On\n");
  774. ret = cnss_select_pinctrl_state(plat_priv, true);
  775. if (!ret)
  776. return ret;
  777. wlan_en_state = 1;
  778. }
  779. if (!gpio_get_value(bt_en_gpio)) {
  780. cnss_pr_dbg("BT_EN_GPIO State: Off. Delay WLAN_GPIO enable\n");
  781. /* check for BT_EN_GPIO down race during above operation */
  782. if (wlan_en_state) {
  783. cnss_pr_dbg("Reset WLAN_EN as BT got turned off during enable\n");
  784. cnss_select_pinctrl_state(plat_priv, false);
  785. wlan_en_state = 0;
  786. }
  787. /* 100 ms delay for BT_EN and WLAN_EN QCA6490 PMU sequencing */
  788. msleep(100);
  789. }
  790. set_wlan_en:
  791. if (!wlan_en_state)
  792. ret = cnss_select_pinctrl_state(plat_priv, true);
  793. return ret;
  794. }
  795. int cnss_power_on_device(struct cnss_plat_data *plat_priv)
  796. {
  797. int ret = 0;
  798. if (plat_priv->powered_on) {
  799. cnss_pr_dbg("Already powered up");
  800. return 0;
  801. }
  802. ret = cnss_vreg_on_type(plat_priv, CNSS_VREG_PRIM);
  803. if (ret) {
  804. cnss_pr_err("Failed to turn on vreg, err = %d\n", ret);
  805. goto out;
  806. }
  807. ret = cnss_clk_on(plat_priv, &plat_priv->clk_list);
  808. if (ret) {
  809. cnss_pr_err("Failed to turn on clocks, err = %d\n", ret);
  810. goto vreg_off;
  811. }
  812. ret = cnss_select_pinctrl_enable(plat_priv);
  813. if (ret) {
  814. cnss_pr_err("Failed to select pinctrl state, err = %d\n", ret);
  815. goto clk_off;
  816. }
  817. plat_priv->powered_on = true;
  818. cnss_enable_dev_sol_irq(plat_priv);
  819. cnss_set_host_sol_value(plat_priv, 0);
  820. return 0;
  821. clk_off:
  822. cnss_clk_off(plat_priv, &plat_priv->clk_list);
  823. vreg_off:
  824. cnss_vreg_off_type(plat_priv, CNSS_VREG_PRIM);
  825. out:
  826. return ret;
  827. }
  828. void cnss_power_off_device(struct cnss_plat_data *plat_priv)
  829. {
  830. if (!plat_priv->powered_on) {
  831. cnss_pr_dbg("Already powered down");
  832. return;
  833. }
  834. cnss_disable_dev_sol_irq(plat_priv);
  835. cnss_select_pinctrl_state(plat_priv, false);
  836. cnss_clk_off(plat_priv, &plat_priv->clk_list);
  837. cnss_vreg_off_type(plat_priv, CNSS_VREG_PRIM);
  838. plat_priv->powered_on = false;
  839. }
  840. bool cnss_is_device_powered_on(struct cnss_plat_data *plat_priv)
  841. {
  842. return plat_priv->powered_on;
  843. }
  844. void cnss_set_pin_connect_status(struct cnss_plat_data *plat_priv)
  845. {
  846. unsigned long pin_status = 0;
  847. set_bit(CNSS_WLAN_EN, &pin_status);
  848. set_bit(CNSS_PCIE_TXN, &pin_status);
  849. set_bit(CNSS_PCIE_TXP, &pin_status);
  850. set_bit(CNSS_PCIE_RXN, &pin_status);
  851. set_bit(CNSS_PCIE_RXP, &pin_status);
  852. set_bit(CNSS_PCIE_REFCLKN, &pin_status);
  853. set_bit(CNSS_PCIE_REFCLKP, &pin_status);
  854. set_bit(CNSS_PCIE_RST, &pin_status);
  855. plat_priv->pin_result.host_pin_result = pin_status;
  856. }
  857. #if IS_ENABLED(CONFIG_QCOM_COMMAND_DB)
  858. static int cnss_cmd_db_ready(struct cnss_plat_data *plat_priv)
  859. {
  860. return cmd_db_ready();
  861. }
  862. static u32 cnss_cmd_db_read_addr(struct cnss_plat_data *plat_priv,
  863. const char *res_id)
  864. {
  865. return cmd_db_read_addr(res_id);
  866. }
  867. #else
  868. static int cnss_cmd_db_ready(struct cnss_plat_data *plat_priv)
  869. {
  870. return -EOPNOTSUPP;
  871. }
  872. static u32 cnss_cmd_db_read_addr(struct cnss_plat_data *plat_priv,
  873. const char *res_id)
  874. {
  875. return 0;
  876. }
  877. #endif
  878. int cnss_get_tcs_info(struct cnss_plat_data *plat_priv)
  879. {
  880. struct platform_device *plat_dev = plat_priv->plat_dev;
  881. struct resource *res;
  882. resource_size_t addr_len;
  883. void __iomem *tcs_cmd_base_addr;
  884. int ret = 0;
  885. res = platform_get_resource_byname(plat_dev, IORESOURCE_MEM, "tcs_cmd");
  886. if (!res) {
  887. cnss_pr_dbg("TCS CMD address is not present for CPR\n");
  888. goto out;
  889. }
  890. plat_priv->tcs_info.cmd_base_addr = res->start;
  891. addr_len = resource_size(res);
  892. cnss_pr_dbg("TCS CMD base address is %pa with length %pa\n",
  893. &plat_priv->tcs_info.cmd_base_addr, &addr_len);
  894. tcs_cmd_base_addr = devm_ioremap(&plat_dev->dev, res->start, addr_len);
  895. if (!tcs_cmd_base_addr) {
  896. ret = -EINVAL;
  897. cnss_pr_err("Failed to map TCS CMD address, err = %d\n",
  898. ret);
  899. goto out;
  900. }
  901. plat_priv->tcs_info.cmd_base_addr_io = tcs_cmd_base_addr;
  902. return 0;
  903. out:
  904. return ret;
  905. }
  906. int cnss_get_cpr_info(struct cnss_plat_data *plat_priv)
  907. {
  908. struct platform_device *plat_dev = plat_priv->plat_dev;
  909. struct cnss_cpr_info *cpr_info = &plat_priv->cpr_info;
  910. const char *cmd_db_name;
  911. u32 cpr_pmic_addr = 0;
  912. int ret = 0;
  913. if (plat_priv->tcs_info.cmd_base_addr == 0) {
  914. cnss_pr_dbg("TCS CMD not configured\n");
  915. return 0;
  916. }
  917. ret = of_property_read_string(plat_dev->dev.of_node,
  918. "qcom,cmd_db_name", &cmd_db_name);
  919. if (ret) {
  920. cnss_pr_dbg("CommandDB name is not present for CPR\n");
  921. goto out;
  922. }
  923. ret = cnss_cmd_db_ready(plat_priv);
  924. if (ret) {
  925. cnss_pr_err("CommandDB is not ready, err = %d\n", ret);
  926. goto out;
  927. }
  928. cpr_pmic_addr = cnss_cmd_db_read_addr(plat_priv, cmd_db_name);
  929. if (cpr_pmic_addr > 0) {
  930. cpr_info->cpr_pmic_addr = cpr_pmic_addr;
  931. cnss_pr_dbg("Get CPR PMIC address 0x%x from %s\n",
  932. cpr_info->cpr_pmic_addr, cmd_db_name);
  933. } else {
  934. cnss_pr_err("CPR PMIC address is not available for %s\n",
  935. cmd_db_name);
  936. ret = -EINVAL;
  937. goto out;
  938. }
  939. return 0;
  940. out:
  941. return ret;
  942. }
  943. int cnss_aop_mbox_init(struct cnss_plat_data *plat_priv)
  944. {
  945. struct mbox_client *mbox = &plat_priv->mbox_client_data;
  946. struct mbox_chan *chan;
  947. int ret = 0;
  948. mbox->dev = &plat_priv->plat_dev->dev;
  949. mbox->tx_block = true;
  950. mbox->tx_tout = CNSS_MBOX_TIMEOUT_MS;
  951. mbox->knows_txdone = false;
  952. plat_priv->mbox_chan = NULL;
  953. ret = of_property_read_string(plat_priv->plat_dev->dev.of_node,
  954. "qcom,vreg_ol_cpr",
  955. &plat_priv->vreg_ol_cpr);
  956. if (ret)
  957. cnss_pr_dbg("Vreg for OL CPR not configured\n");
  958. ret = of_property_read_string(plat_priv->plat_dev->dev.of_node,
  959. "qcom,vreg_ipa",
  960. &plat_priv->vreg_ipa);
  961. if (ret)
  962. cnss_pr_dbg("Volt regulator for Int Power Amp not configured\n");
  963. if (!plat_priv->vreg_ol_cpr && !plat_priv->vreg_ipa)
  964. return 0;
  965. chan = mbox_request_channel(mbox, 0);
  966. if (IS_ERR(chan)) {
  967. cnss_pr_err("Failed to get mbox channel\n");
  968. return PTR_ERR(chan);
  969. }
  970. plat_priv->mbox_chan = chan;
  971. cnss_pr_dbg("Mbox channel initialized\n");
  972. return 0;
  973. }
  974. #if IS_ENABLED(CONFIG_MSM_QMP)
  975. static int cnss_aop_set_vreg_param(struct cnss_plat_data *plat_priv,
  976. const char *vreg_name,
  977. enum cnss_vreg_param param,
  978. enum cnss_tcs_seq seq, int val)
  979. {
  980. struct qmp_pkt pkt;
  981. char mbox_msg[CNSS_MBOX_MSG_MAX_LEN];
  982. static const char * const vreg_param_str[] = {"v", "m", "e"};
  983. static const char *const tcs_seq_str[] = {"upval", "dwnval", "enable"};
  984. int ret = 0;
  985. if (param > CNSS_VREG_ENABLE || seq > CNSS_TCS_ALL_SEQ || !vreg_name)
  986. return -EINVAL;
  987. snprintf(mbox_msg, CNSS_MBOX_MSG_MAX_LEN,
  988. "{class: wlan_pdc, res: %s.%s, %s: %d}", vreg_name,
  989. vreg_param_str[param], tcs_seq_str[seq], val);
  990. cnss_pr_dbg("Sending AOP Mbox msg: %s\n", mbox_msg);
  991. pkt.size = CNSS_MBOX_MSG_MAX_LEN;
  992. pkt.data = mbox_msg;
  993. ret = mbox_send_message(plat_priv->mbox_chan, &pkt);
  994. if (ret < 0)
  995. cnss_pr_err("Failed to send AOP mbox msg: %s\n", mbox_msg);
  996. else
  997. ret = 0;
  998. return ret;
  999. }
  1000. #else
  1001. static int cnss_aop_set_vreg_param(struct cnss_plat_data *plat_priv,
  1002. const char *vreg_name,
  1003. enum cnss_vreg_param param,
  1004. enum cnss_tcs_seq seq, int val)
  1005. {
  1006. return 0;
  1007. }
  1008. #endif
  1009. int cnss_update_cpr_info(struct cnss_plat_data *plat_priv)
  1010. {
  1011. struct cnss_cpr_info *cpr_info = &plat_priv->cpr_info;
  1012. u32 pmic_addr, voltage = 0, voltage_tmp, offset;
  1013. void __iomem *tcs_cmd_addr, *tcs_cmd_data_addr;
  1014. int i, j;
  1015. if (cpr_info->voltage == 0) {
  1016. cnss_pr_err("OL CPR Voltage %dm is not valid\n",
  1017. cpr_info->voltage);
  1018. return -EINVAL;
  1019. }
  1020. if (!plat_priv->vreg_ol_cpr || !plat_priv->mbox_chan) {
  1021. cnss_pr_dbg("Mbox channel / OL CPR Vreg not configured\n");
  1022. } else {
  1023. return cnss_aop_set_vreg_param(plat_priv,
  1024. plat_priv->vreg_ol_cpr,
  1025. CNSS_VREG_VOLTAGE,
  1026. CNSS_TCS_UP_SEQ,
  1027. cpr_info->voltage);
  1028. }
  1029. if (plat_priv->tcs_info.cmd_base_addr == 0) {
  1030. cnss_pr_dbg("TCS CMD not configured for OL CPR update\n");
  1031. return 0;
  1032. }
  1033. if (cpr_info->cpr_pmic_addr == 0) {
  1034. cnss_pr_err("PMIC address 0x%x is not valid\n",
  1035. cpr_info->cpr_pmic_addr);
  1036. return -EINVAL;
  1037. }
  1038. if (cpr_info->tcs_cmd_data_addr_io)
  1039. goto update_cpr;
  1040. for (i = 0; i < MAX_TCS_NUM; i++) {
  1041. for (j = 0; j < MAX_TCS_CMD_NUM; j++) {
  1042. offset = i * TCS_OFFSET + j * TCS_CMD_OFFSET;
  1043. tcs_cmd_addr = plat_priv->tcs_info.cmd_base_addr_io +
  1044. offset;
  1045. pmic_addr = readl_relaxed(tcs_cmd_addr);
  1046. if (pmic_addr == cpr_info->cpr_pmic_addr) {
  1047. tcs_cmd_data_addr = tcs_cmd_addr +
  1048. TCS_CMD_DATA_ADDR_OFFSET;
  1049. voltage_tmp = readl_relaxed(tcs_cmd_data_addr);
  1050. cnss_pr_dbg("Got voltage %dmV from i: %d, j: %d\n",
  1051. voltage_tmp, i, j);
  1052. if (voltage_tmp > voltage) {
  1053. voltage = voltage_tmp;
  1054. cpr_info->tcs_cmd_data_addr =
  1055. plat_priv->tcs_info.cmd_base_addr +
  1056. offset + TCS_CMD_DATA_ADDR_OFFSET;
  1057. cpr_info->tcs_cmd_data_addr_io =
  1058. tcs_cmd_data_addr;
  1059. }
  1060. }
  1061. }
  1062. }
  1063. if (!cpr_info->tcs_cmd_data_addr_io) {
  1064. cnss_pr_err("Failed to find proper TCS CMD data address\n");
  1065. return -EINVAL;
  1066. }
  1067. update_cpr:
  1068. cpr_info->voltage = cpr_info->voltage > BT_CXMX_VOLTAGE_MV ?
  1069. cpr_info->voltage : BT_CXMX_VOLTAGE_MV;
  1070. cnss_pr_dbg("Update TCS CMD data address %pa with voltage %dmV\n",
  1071. &cpr_info->tcs_cmd_data_addr, cpr_info->voltage);
  1072. writel_relaxed(cpr_info->voltage, cpr_info->tcs_cmd_data_addr_io);
  1073. return 0;
  1074. }
  1075. int cnss_enable_int_pow_amp_vreg(struct cnss_plat_data *plat_priv)
  1076. {
  1077. struct platform_device *plat_dev = plat_priv->plat_dev;
  1078. u32 offset, addr_val, data_val;
  1079. void __iomem *tcs_cmd;
  1080. int ret;
  1081. static bool config_done;
  1082. if (plat_priv->device_id != QCA6490_DEVICE_ID)
  1083. return -EINVAL;
  1084. if (config_done) {
  1085. cnss_pr_dbg("IPA Vreg already configured\n");
  1086. return 0;
  1087. }
  1088. if (!plat_priv->vreg_ipa || !plat_priv->mbox_chan) {
  1089. cnss_pr_dbg("Mbox channel / IPA Vreg not configured\n");
  1090. } else {
  1091. ret = cnss_aop_set_vreg_param(plat_priv,
  1092. plat_priv->vreg_ipa,
  1093. CNSS_VREG_ENABLE,
  1094. CNSS_TCS_UP_SEQ, 1);
  1095. if (ret == 0)
  1096. config_done = true;
  1097. return ret;
  1098. }
  1099. if (!plat_priv->tcs_info.cmd_base_addr_io) {
  1100. cnss_pr_err("TCS CMD not configured for IPA Vreg enable\n");
  1101. return -EINVAL;
  1102. }
  1103. ret = of_property_read_u32(plat_dev->dev.of_node,
  1104. "qcom,tcs_offset_int_pow_amp_vreg",
  1105. &offset);
  1106. if (ret) {
  1107. cnss_pr_dbg("Internal Power Amp Vreg not configured\n");
  1108. return -EINVAL;
  1109. }
  1110. tcs_cmd = plat_priv->tcs_info.cmd_base_addr_io + offset;
  1111. addr_val = readl_relaxed(tcs_cmd);
  1112. tcs_cmd += TCS_CMD_DATA_ADDR_OFFSET;
  1113. /* 1 = enable Vreg */
  1114. writel_relaxed(1, tcs_cmd);
  1115. data_val = readl_relaxed(tcs_cmd);
  1116. cnss_pr_dbg("Setup S3E TCS Addr: %x Data: %d\n", addr_val, data_val);
  1117. config_done = true;
  1118. return 0;
  1119. }