dp_parser.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2021-2023, Qualcomm Innovation Center, Inc. All rights reserved.
  4. * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
  5. */
  6. #include <linux/of_gpio.h>
  7. #include <linux/of_platform.h>
  8. #include "dp_parser.h"
  9. #include "dp_debug.h"
  10. static void dp_parser_unmap_io_resources(struct dp_parser *parser)
  11. {
  12. int i = 0;
  13. struct dp_io *io = &parser->io;
  14. for (i = 0; i < io->len; i++)
  15. msm_dss_iounmap(&io->data[i].io);
  16. }
  17. static int dp_parser_reg(struct dp_parser *parser)
  18. {
  19. int rc = 0, i = 0;
  20. u32 reg_count;
  21. struct platform_device *pdev = parser->pdev;
  22. struct dp_io *io = &parser->io;
  23. struct device *dev = &pdev->dev;
  24. reg_count = of_property_count_strings(dev->of_node, "reg-names");
  25. if (reg_count <= 0) {
  26. DP_ERR("no reg defined\n");
  27. return -EINVAL;
  28. }
  29. io->len = reg_count;
  30. io->data = devm_kzalloc(dev, sizeof(struct dp_io_data) * reg_count,
  31. GFP_KERNEL);
  32. if (!io->data)
  33. return -ENOMEM;
  34. for (i = 0; i < reg_count; i++) {
  35. of_property_read_string_index(dev->of_node,
  36. "reg-names", i, &io->data[i].name);
  37. rc = msm_dss_ioremap_byname(pdev, &io->data[i].io,
  38. io->data[i].name);
  39. if (rc) {
  40. DP_ERR("unable to remap %s resources\n",
  41. io->data[i].name);
  42. goto err;
  43. }
  44. }
  45. return 0;
  46. err:
  47. dp_parser_unmap_io_resources(parser);
  48. return rc;
  49. }
  50. static const char *dp_get_phy_aux_config_property(u32 cfg_type)
  51. {
  52. switch (cfg_type) {
  53. case PHY_AUX_CFG0:
  54. return "qcom,aux-cfg0-settings";
  55. case PHY_AUX_CFG1:
  56. return "qcom,aux-cfg1-settings";
  57. case PHY_AUX_CFG2:
  58. return "qcom,aux-cfg2-settings";
  59. case PHY_AUX_CFG3:
  60. return "qcom,aux-cfg3-settings";
  61. case PHY_AUX_CFG4:
  62. return "qcom,aux-cfg4-settings";
  63. case PHY_AUX_CFG5:
  64. return "qcom,aux-cfg5-settings";
  65. case PHY_AUX_CFG6:
  66. return "qcom,aux-cfg6-settings";
  67. case PHY_AUX_CFG7:
  68. return "qcom,aux-cfg7-settings";
  69. case PHY_AUX_CFG8:
  70. return "qcom,aux-cfg8-settings";
  71. case PHY_AUX_CFG9:
  72. return "qcom,aux-cfg9-settings";
  73. default:
  74. return "unknown";
  75. }
  76. }
  77. static void dp_parser_phy_aux_cfg_reset(struct dp_parser *parser)
  78. {
  79. int i = 0;
  80. for (i = 0; i < PHY_AUX_CFG_MAX; i++)
  81. parser->aux_cfg[i] = (const struct dp_aux_cfg){ 0 };
  82. }
  83. static int dp_parser_aux(struct dp_parser *parser)
  84. {
  85. struct device_node *of_node = parser->pdev->dev.of_node;
  86. int len = 0, i = 0, j = 0, config_count = 0;
  87. const char *data;
  88. int const minimum_config_count = 1;
  89. for (i = 0; i < PHY_AUX_CFG_MAX; i++) {
  90. const char *property = dp_get_phy_aux_config_property(i);
  91. data = of_get_property(of_node, property, &len);
  92. if (!data) {
  93. DP_ERR("Unable to read %s\n", property);
  94. goto error;
  95. }
  96. config_count = len - 1;
  97. if ((config_count < minimum_config_count) ||
  98. (config_count > DP_AUX_CFG_MAX_VALUE_CNT)) {
  99. DP_ERR("Invalid config count (%d) configs for %s\n",
  100. config_count, property);
  101. goto error;
  102. }
  103. parser->aux_cfg[i].offset = data[0];
  104. parser->aux_cfg[i].cfg_cnt = config_count;
  105. DP_DEBUG("%s offset=0x%x, cfg_cnt=%d\n",
  106. property,
  107. parser->aux_cfg[i].offset,
  108. parser->aux_cfg[i].cfg_cnt);
  109. for (j = 1; j < len; j++) {
  110. parser->aux_cfg[i].lut[j - 1] = data[j];
  111. DP_DEBUG("%s lut[%d]=0x%x\n",
  112. property,
  113. i,
  114. parser->aux_cfg[i].lut[j - 1]);
  115. }
  116. }
  117. return 0;
  118. error:
  119. dp_parser_phy_aux_cfg_reset(parser);
  120. return -EINVAL;
  121. }
  122. static int dp_parser_misc(struct dp_parser *parser)
  123. {
  124. int rc = 0, len = 0, i = 0;
  125. const char *data = NULL;
  126. struct device_node *of_node = parser->pdev->dev.of_node;
  127. data = of_get_property(of_node, "qcom,logical2physical-lane-map", &len);
  128. if (data && (len == DP_MAX_PHY_LN)) {
  129. for (i = 0; i < len; i++)
  130. parser->l_map[i] = data[i];
  131. }
  132. data = of_get_property(of_node, "qcom,pn-swap-lane-map", &len);
  133. if (data && (len == DP_MAX_PHY_LN)) {
  134. for (i = 0; i < len; i++)
  135. parser->l_pnswap |= (data[i] & 0x01) << i;
  136. }
  137. rc = of_property_read_u32(of_node,
  138. "qcom,max-pclk-frequency-khz", &parser->max_pclk_khz);
  139. if (rc)
  140. parser->max_pclk_khz = DP_MAX_PIXEL_CLK_KHZ;
  141. rc = of_property_read_u32(of_node,
  142. "qcom,max-lclk-frequency-khz", &parser->max_lclk_khz);
  143. if (rc)
  144. parser->max_lclk_khz = DP_MAX_LINK_CLK_KHZ;
  145. return 0;
  146. }
  147. static int dp_parser_msm_hdcp_dev(struct dp_parser *parser)
  148. {
  149. struct device_node *node;
  150. struct platform_device *pdev;
  151. node = of_find_compatible_node(NULL, NULL, "qcom,msm-hdcp");
  152. if (!node) {
  153. // This is a non-fatal error, module initialization can proceed
  154. DP_WARN("couldn't find msm-hdcp node\n");
  155. return 0;
  156. }
  157. pdev = of_find_device_by_node(node);
  158. if (!pdev) {
  159. // This is a non-fatal error, module initialization can proceed
  160. DP_WARN("couldn't find msm-hdcp pdev\n");
  161. return 0;
  162. }
  163. parser->msm_hdcp_dev = &pdev->dev;
  164. return 0;
  165. }
  166. static int dp_parser_pinctrl(struct dp_parser *parser)
  167. {
  168. int rc = 0;
  169. struct dp_pinctrl *pinctrl = &parser->pinctrl;
  170. pinctrl->pin = devm_pinctrl_get(&parser->pdev->dev);
  171. if (IS_ERR_OR_NULL(pinctrl->pin)) {
  172. DP_DEBUG("failed to get pinctrl, rc=%d\n", rc);
  173. goto error;
  174. }
  175. pinctrl->state_active = pinctrl_lookup_state(pinctrl->pin,
  176. "mdss_dp_active");
  177. if (IS_ERR_OR_NULL(pinctrl->state_active)) {
  178. rc = PTR_ERR(pinctrl->state_active);
  179. DP_ERR("failed to get pinctrl active state, rc=%d\n", rc);
  180. goto error;
  181. }
  182. pinctrl->state_suspend = pinctrl_lookup_state(pinctrl->pin,
  183. "mdss_dp_sleep");
  184. if (IS_ERR_OR_NULL(pinctrl->state_suspend)) {
  185. rc = PTR_ERR(pinctrl->state_suspend);
  186. DP_ERR("failed to get pinctrl suspend state, rc=%d\n", rc);
  187. goto error;
  188. }
  189. error:
  190. return rc;
  191. }
  192. static int dp_parser_gpio(struct dp_parser *parser)
  193. {
  194. int i = 0;
  195. struct device *dev = &parser->pdev->dev;
  196. struct device_node *of_node = dev->of_node;
  197. struct dss_module_power *mp = &parser->mp[DP_CORE_PM];
  198. static const char * const dp_gpios[] = {
  199. "qcom,aux-en-gpio",
  200. "qcom,aux-sel-gpio",
  201. "qcom,usbplug-cc-gpio",
  202. };
  203. if (of_find_property(of_node, "qcom,dp-gpio-aux-switch", NULL))
  204. parser->gpio_aux_switch = true;
  205. mp->gpio_config = devm_kzalloc(dev,
  206. sizeof(struct dss_gpio) * ARRAY_SIZE(dp_gpios), GFP_KERNEL);
  207. if (!mp->gpio_config)
  208. return -ENOMEM;
  209. mp->num_gpio = ARRAY_SIZE(dp_gpios);
  210. for (i = 0; i < ARRAY_SIZE(dp_gpios); i++) {
  211. mp->gpio_config[i].gpio = of_get_named_gpio(of_node,
  212. dp_gpios[i], 0);
  213. if (!gpio_is_valid(mp->gpio_config[i].gpio)) {
  214. DP_DEBUG("%s gpio not specified\n", dp_gpios[i]);
  215. /* In case any gpio was not specified, we think gpio
  216. * aux switch also was not specified.
  217. */
  218. parser->gpio_aux_switch = false;
  219. continue;
  220. }
  221. strlcpy(mp->gpio_config[i].gpio_name, dp_gpios[i],
  222. sizeof(mp->gpio_config[i].gpio_name));
  223. mp->gpio_config[i].value = 0;
  224. }
  225. return 0;
  226. }
  227. static const char *dp_parser_supply_node_name(enum dp_pm_type module)
  228. {
  229. switch (module) {
  230. case DP_CORE_PM: return "qcom,core-supply-entries";
  231. case DP_CTRL_PM: return "qcom,ctrl-supply-entries";
  232. case DP_PHY_PM: return "qcom,phy-supply-entries";
  233. case DP_PLL_PM: return "qcom,pll-supply-entries";
  234. default: return "???";
  235. }
  236. }
  237. static int dp_parser_get_vreg(struct dp_parser *parser,
  238. enum dp_pm_type module)
  239. {
  240. int i = 0, rc = 0;
  241. u32 tmp = 0;
  242. const char *pm_supply_name = NULL;
  243. struct device_node *supply_node = NULL;
  244. struct device_node *of_node = parser->pdev->dev.of_node;
  245. struct device_node *supply_root_node = NULL;
  246. struct dss_module_power *mp = &parser->mp[module];
  247. mp->num_vreg = 0;
  248. pm_supply_name = dp_parser_supply_node_name(module);
  249. supply_root_node = of_get_child_by_name(of_node, pm_supply_name);
  250. if (!supply_root_node) {
  251. DP_DEBUG("no supply entry present: %s\n", pm_supply_name);
  252. goto novreg;
  253. }
  254. mp->num_vreg = of_get_available_child_count(supply_root_node);
  255. if (mp->num_vreg == 0) {
  256. DP_DEBUG("no vreg\n");
  257. goto novreg;
  258. } else {
  259. DP_DEBUG("vreg found. count=%d\n", mp->num_vreg);
  260. }
  261. mp->vreg_config = devm_kzalloc(&parser->pdev->dev,
  262. sizeof(struct dss_vreg) * mp->num_vreg, GFP_KERNEL);
  263. if (!mp->vreg_config) {
  264. rc = -ENOMEM;
  265. goto error;
  266. }
  267. for_each_child_of_node(supply_root_node, supply_node) {
  268. const char *st = NULL;
  269. /* vreg-name */
  270. rc = of_property_read_string(supply_node,
  271. "qcom,supply-name", &st);
  272. if (rc) {
  273. DP_ERR("error reading name. rc=%d\n",
  274. rc);
  275. goto error;
  276. }
  277. snprintf(mp->vreg_config[i].vreg_name,
  278. ARRAY_SIZE((mp->vreg_config[i].vreg_name)), "%s", st);
  279. /* vreg-min-voltage */
  280. rc = of_property_read_u32(supply_node,
  281. "qcom,supply-min-voltage", &tmp);
  282. if (rc) {
  283. DP_ERR("error reading min volt. rc=%d\n",
  284. rc);
  285. goto error;
  286. }
  287. mp->vreg_config[i].min_voltage = tmp;
  288. /* vreg-max-voltage */
  289. rc = of_property_read_u32(supply_node,
  290. "qcom,supply-max-voltage", &tmp);
  291. if (rc) {
  292. DP_ERR("error reading max volt. rc=%d\n",
  293. rc);
  294. goto error;
  295. }
  296. mp->vreg_config[i].max_voltage = tmp;
  297. /* enable-load */
  298. rc = of_property_read_u32(supply_node,
  299. "qcom,supply-enable-load", &tmp);
  300. if (rc) {
  301. DP_ERR("error reading enable load. rc=%d\n",
  302. rc);
  303. goto error;
  304. }
  305. mp->vreg_config[i].enable_load = tmp;
  306. /* disable-load */
  307. rc = of_property_read_u32(supply_node,
  308. "qcom,supply-disable-load", &tmp);
  309. if (rc) {
  310. DP_ERR("error reading disable load. rc=%d\n",
  311. rc);
  312. goto error;
  313. }
  314. mp->vreg_config[i].disable_load = tmp;
  315. DP_DEBUG("%s min=%d, max=%d, enable=%d, disable=%d\n",
  316. mp->vreg_config[i].vreg_name,
  317. mp->vreg_config[i].min_voltage,
  318. mp->vreg_config[i].max_voltage,
  319. mp->vreg_config[i].enable_load,
  320. mp->vreg_config[i].disable_load
  321. );
  322. ++i;
  323. }
  324. return rc;
  325. error:
  326. if (mp->vreg_config) {
  327. devm_kfree(&parser->pdev->dev, mp->vreg_config);
  328. mp->vreg_config = NULL;
  329. }
  330. novreg:
  331. mp->num_vreg = 0;
  332. return rc;
  333. }
  334. static void dp_parser_put_vreg_data(struct device *dev,
  335. struct dss_module_power *mp)
  336. {
  337. if (!mp) {
  338. DEV_ERR("invalid input\n");
  339. return;
  340. }
  341. if (mp->vreg_config) {
  342. devm_kfree(dev, mp->vreg_config);
  343. mp->vreg_config = NULL;
  344. }
  345. mp->num_vreg = 0;
  346. }
  347. static int dp_parser_regulator(struct dp_parser *parser)
  348. {
  349. int i, rc = 0;
  350. struct platform_device *pdev = parser->pdev;
  351. /* Parse the regulator information */
  352. for (i = DP_CORE_PM; i < DP_MAX_PM; i++) {
  353. rc = dp_parser_get_vreg(parser, i);
  354. if (rc) {
  355. DP_ERR("get_dt_vreg_data failed for %s. rc=%d\n",
  356. dp_parser_pm_name(i), rc);
  357. i--;
  358. for (; i >= DP_CORE_PM; i--)
  359. dp_parser_put_vreg_data(&pdev->dev,
  360. &parser->mp[i]);
  361. break;
  362. }
  363. }
  364. return rc;
  365. }
  366. static bool dp_parser_check_prefix(const char *clk_prefix, const char *clk_name)
  367. {
  368. return !!strnstr(clk_name, clk_prefix, strlen(clk_name));
  369. }
  370. static void dp_parser_put_clk_data(struct device *dev,
  371. struct dss_module_power *mp)
  372. {
  373. if (!mp) {
  374. DEV_ERR("%s: invalid input\n", __func__);
  375. return;
  376. }
  377. if (mp->clk_config) {
  378. devm_kfree(dev, mp->clk_config);
  379. mp->clk_config = NULL;
  380. }
  381. mp->num_clk = 0;
  382. }
  383. static void dp_parser_put_gpio_data(struct device *dev,
  384. struct dss_module_power *mp)
  385. {
  386. if (!mp) {
  387. DEV_ERR("%s: invalid input\n", __func__);
  388. return;
  389. }
  390. if (mp->gpio_config) {
  391. devm_kfree(dev, mp->gpio_config);
  392. mp->gpio_config = NULL;
  393. }
  394. mp->num_gpio = 0;
  395. }
  396. static int dp_parser_init_clk_data(struct dp_parser *parser)
  397. {
  398. int num_clk = 0, i = 0, rc = 0;
  399. int core_clk_count = 0, link_clk_count = 0;
  400. int strm0_clk_count = 0, strm1_clk_count = 0;
  401. const char *core_clk = "core";
  402. const char *strm0_clk = "strm0";
  403. const char *strm1_clk = "strm1";
  404. const char *link_clk = "link";
  405. const char *clk_name;
  406. struct device *dev = &parser->pdev->dev;
  407. struct dss_module_power *core_power = &parser->mp[DP_CORE_PM];
  408. struct dss_module_power *strm0_power = &parser->mp[DP_STREAM0_PM];
  409. struct dss_module_power *strm1_power = &parser->mp[DP_STREAM1_PM];
  410. struct dss_module_power *link_power = &parser->mp[DP_LINK_PM];
  411. num_clk = of_property_count_strings(dev->of_node, "clock-names");
  412. if (num_clk <= 0) {
  413. DP_ERR("no clocks are defined\n");
  414. rc = -EINVAL;
  415. goto exit;
  416. }
  417. for (i = 0; i < num_clk; i++) {
  418. of_property_read_string_index(dev->of_node,
  419. "clock-names", i, &clk_name);
  420. if (dp_parser_check_prefix(core_clk, clk_name))
  421. core_clk_count++;
  422. if (dp_parser_check_prefix(strm0_clk, clk_name))
  423. strm0_clk_count++;
  424. if (dp_parser_check_prefix(strm1_clk, clk_name))
  425. strm1_clk_count++;
  426. if (dp_parser_check_prefix(link_clk, clk_name))
  427. link_clk_count++;
  428. }
  429. /* Initialize the CORE power module */
  430. if (core_clk_count <= 0) {
  431. DP_ERR("no core clocks are defined\n");
  432. rc = -EINVAL;
  433. goto exit;
  434. }
  435. core_power->num_clk = core_clk_count;
  436. core_power->clk_config = devm_kzalloc(dev,
  437. sizeof(struct dss_clk) * core_power->num_clk,
  438. GFP_KERNEL);
  439. if (!core_power->clk_config) {
  440. rc = -EINVAL;
  441. goto exit;
  442. }
  443. /* Initialize the STREAM0 power module */
  444. if (strm0_clk_count <= 0) {
  445. DP_DEBUG("no strm0 clocks are defined\n");
  446. } else {
  447. strm0_power->num_clk = strm0_clk_count;
  448. strm0_power->clk_config = devm_kzalloc(dev,
  449. sizeof(struct dss_clk) * strm0_power->num_clk,
  450. GFP_KERNEL);
  451. if (!strm0_power->clk_config) {
  452. strm0_power->num_clk = 0;
  453. rc = -EINVAL;
  454. goto strm0_clock_error;
  455. }
  456. }
  457. /* Initialize the STREAM1 power module */
  458. if (strm1_clk_count <= 0) {
  459. DP_DEBUG("no strm1 clocks are defined\n");
  460. } else {
  461. strm1_power->num_clk = strm1_clk_count;
  462. strm1_power->clk_config = devm_kzalloc(dev,
  463. sizeof(struct dss_clk) * strm1_power->num_clk,
  464. GFP_KERNEL);
  465. if (!strm1_power->clk_config) {
  466. strm1_power->num_clk = 0;
  467. rc = -EINVAL;
  468. goto strm1_clock_error;
  469. }
  470. }
  471. /* Initialize the link power module */
  472. if (link_clk_count <= 0) {
  473. DP_ERR("no link clocks are defined\n");
  474. rc = -EINVAL;
  475. goto link_clock_error;
  476. }
  477. link_power->num_clk = link_clk_count;
  478. link_power->clk_config = devm_kzalloc(dev,
  479. sizeof(struct dss_clk) * link_power->num_clk,
  480. GFP_KERNEL);
  481. if (!link_power->clk_config) {
  482. link_power->num_clk = 0;
  483. rc = -EINVAL;
  484. goto link_clock_error;
  485. }
  486. return rc;
  487. link_clock_error:
  488. dp_parser_put_clk_data(dev, strm1_power);
  489. strm1_clock_error:
  490. dp_parser_put_clk_data(dev, strm0_power);
  491. strm0_clock_error:
  492. dp_parser_put_clk_data(dev, core_power);
  493. exit:
  494. return rc;
  495. }
  496. static int dp_parser_clock(struct dp_parser *parser)
  497. {
  498. int rc = 0, i = 0;
  499. int num_clk = 0;
  500. int core_clk_index = 0, link_clk_index = 0;
  501. int core_clk_count = 0, link_clk_count = 0;
  502. int strm0_clk_index = 0, strm1_clk_index = 0;
  503. int strm0_clk_count = 0, strm1_clk_count = 0;
  504. int clock_mmrm = 0;
  505. const char *clk_name;
  506. const char *core_clk = "core";
  507. const char *strm0_clk = "strm0";
  508. const char *strm1_clk = "strm1";
  509. const char *link_clk = "link";
  510. struct device *dev = &parser->pdev->dev;
  511. struct dss_module_power *core_power;
  512. struct dss_module_power *strm0_power;
  513. struct dss_module_power *strm1_power;
  514. struct dss_module_power *link_power;
  515. core_power = &parser->mp[DP_CORE_PM];
  516. strm0_power = &parser->mp[DP_STREAM0_PM];
  517. strm1_power = &parser->mp[DP_STREAM1_PM];
  518. link_power = &parser->mp[DP_LINK_PM];
  519. rc = dp_parser_init_clk_data(parser);
  520. if (rc) {
  521. DP_ERR("failed to initialize power data\n");
  522. rc = -EINVAL;
  523. goto exit;
  524. }
  525. core_clk_count = core_power->num_clk;
  526. link_clk_count = link_power->num_clk;
  527. strm0_clk_count = strm0_power->num_clk;
  528. strm1_clk_count = strm1_power->num_clk;
  529. num_clk = of_property_count_strings(dev->of_node, "clock-names");
  530. for (i = 0; i < num_clk; i++) {
  531. of_property_read_string_index(dev->of_node, "clock-names",
  532. i, &clk_name);
  533. if (dp_parser_check_prefix(core_clk, clk_name) &&
  534. core_clk_index < core_clk_count) {
  535. struct dss_clk *clk =
  536. &core_power->clk_config[core_clk_index];
  537. strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name));
  538. clk->type = DSS_CLK_AHB;
  539. core_clk_index++;
  540. } else if (dp_parser_check_prefix(link_clk, clk_name) &&
  541. link_clk_index < link_clk_count) {
  542. struct dss_clk *clk =
  543. &link_power->clk_config[link_clk_index];
  544. strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name));
  545. link_clk_index++;
  546. clock_mmrm = 0;
  547. of_property_read_u32_index(dev->of_node, "clock-mmrm", i, &clock_mmrm);
  548. if (clock_mmrm) {
  549. clk->type = DSS_CLK_MMRM;
  550. clk->mmrm.clk_id = clock_mmrm;
  551. } else if (!strcmp(clk_name, "link_clk_src")) {
  552. clk->type = DSS_CLK_PCLK;
  553. } else {
  554. clk->type = DSS_CLK_AHB;
  555. }
  556. } else if (dp_parser_check_prefix(strm0_clk, clk_name) &&
  557. strm0_clk_index < strm0_clk_count) {
  558. struct dss_clk *clk =
  559. &strm0_power->clk_config[strm0_clk_index];
  560. strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name));
  561. strm0_clk_index++;
  562. clk->type = DSS_CLK_PCLK;
  563. } else if (dp_parser_check_prefix(strm1_clk, clk_name) &&
  564. strm1_clk_index < strm1_clk_count) {
  565. struct dss_clk *clk =
  566. &strm1_power->clk_config[strm1_clk_index];
  567. strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name));
  568. strm1_clk_index++;
  569. clk->type = DSS_CLK_PCLK;
  570. }
  571. }
  572. DP_DEBUG("clock parsing successful\n");
  573. exit:
  574. return rc;
  575. }
  576. static int dp_parser_catalog(struct dp_parser *parser)
  577. {
  578. int rc;
  579. u32 version;
  580. struct device *dev = &parser->pdev->dev;
  581. rc = of_property_read_u32(dev->of_node, "qcom,phy-version", &version);
  582. if (!rc)
  583. parser->hw_cfg.phy_version = version;
  584. return 0;
  585. }
  586. static int dp_parser_mst(struct dp_parser *parser)
  587. {
  588. struct device *dev = &parser->pdev->dev;
  589. int i;
  590. parser->has_mst = of_property_read_bool(dev->of_node,
  591. "qcom,mst-enable");
  592. parser->has_mst_sideband = parser->has_mst;
  593. DP_DEBUG("mst parsing successful. mst:%d\n", parser->has_mst);
  594. for (i = 0; i < MAX_DP_MST_STREAMS; i++) {
  595. of_property_read_u32_index(dev->of_node,
  596. "qcom,mst-fixed-topology-ports", i,
  597. &parser->mst_fixed_port[i]);
  598. }
  599. return 0;
  600. }
  601. static void dp_parser_dsc(struct dp_parser *parser)
  602. {
  603. struct device *dev = &parser->pdev->dev;
  604. parser->dsc_feature_enable = of_property_read_bool(dev->of_node,
  605. "qcom,dsc-feature-enable");
  606. parser->dsc_continuous_pps = of_property_read_bool(dev->of_node,
  607. "qcom,dsc-continuous-pps");
  608. DP_DEBUG("dsc parsing successful. dsc:%d\n",
  609. parser->dsc_feature_enable);
  610. DP_DEBUG("cont_pps:%d\n",
  611. parser->dsc_continuous_pps);
  612. }
  613. static void dp_parser_qos(struct dp_parser *parser)
  614. {
  615. struct device *dev = &parser->pdev->dev;
  616. u32 mask, latency;
  617. int rc;
  618. rc = of_property_read_u32(dev->of_node, "qcom,qos-cpu-latency-us", &latency);
  619. if (rc)
  620. return;
  621. rc = of_property_read_u32(dev->of_node, "qcom,qos-cpu-mask", &mask);
  622. if (rc)
  623. return;
  624. parser->qos_cpu_mask = mask;
  625. parser->qos_cpu_latency = latency;
  626. DP_DEBUG("qos parsing successful. mask:%x latency:%ld\n", mask, latency);
  627. }
  628. static void dp_parser_fec(struct dp_parser *parser)
  629. {
  630. struct device *dev = &parser->pdev->dev;
  631. parser->fec_feature_enable = of_property_read_bool(dev->of_node,
  632. "qcom,fec-feature-enable");
  633. DP_DEBUG("fec parsing successful. fec:%d\n",
  634. parser->fec_feature_enable);
  635. }
  636. static void dp_parser_widebus(struct dp_parser *parser)
  637. {
  638. struct device *dev = &parser->pdev->dev;
  639. parser->has_widebus = of_property_read_bool(dev->of_node,
  640. "qcom,widebus-enable");
  641. DP_DEBUG("widebus parsing successful. widebus:%d\n",
  642. parser->has_widebus);
  643. }
  644. static int parse_lt_param(struct device *dev, u8 **ptr, char *property) {
  645. int ret = 0, i = 0, j = 0, index = 0;
  646. u32 out_val = 0;
  647. u32 expected_elems = MAX_SWING_LEVELS * MAX_PRE_EMP_LEVELS;
  648. u8 parsed_val = 0;
  649. ret = of_property_count_u32_elems(dev->of_node, property);
  650. if (ret != expected_elems) {
  651. return ret;
  652. }
  653. *ptr = devm_kzalloc(dev, sizeof(u8) * expected_elems, GFP_KERNEL);
  654. if (!*ptr)
  655. return -ENOMEM;
  656. for (i = 0; i < MAX_SWING_LEVELS; i++) {
  657. for (j = 0; j < MAX_PRE_EMP_LEVELS; j++) {
  658. index = i * MAX_SWING_LEVELS + j;
  659. ret = of_property_read_u32_index(dev->of_node, property, index, &out_val);
  660. if (ret)
  661. return ret;
  662. parsed_val = out_val & 0xFF;
  663. ((u8 *)*ptr)[index] = parsed_val;
  664. }
  665. }
  666. return ret;
  667. }
  668. static void dp_parser_clear_link_training_params(struct dp_parser *dp_parser)
  669. {
  670. devm_kfree(&dp_parser->pdev->dev, dp_parser->swing_hbr2_3);
  671. devm_kfree(&dp_parser->pdev->dev, dp_parser->pre_emp_hbr2_3);
  672. devm_kfree(&dp_parser->pdev->dev, dp_parser->swing_hbr_rbr);
  673. devm_kfree(&dp_parser->pdev->dev, dp_parser->pre_emp_hbr_rbr);
  674. dp_parser->swing_hbr2_3 = NULL;
  675. dp_parser->pre_emp_hbr2_3 = NULL;
  676. dp_parser->swing_hbr_rbr = NULL;
  677. dp_parser->pre_emp_hbr_rbr = NULL;
  678. dp_parser->valid_lt_params = false;
  679. }
  680. static void dp_parser_link_training_params(struct dp_parser *parser)
  681. {
  682. struct device *dev = &parser->pdev->dev;
  683. int ret = 0;
  684. ret = parse_lt_param(dev, &parser->swing_hbr2_3, "qcom,hbr2-3-voltage-swing");
  685. if (ret)
  686. goto early_exit;
  687. ret = parse_lt_param(dev, &parser->pre_emp_hbr2_3, "qcom,hbr2-3-pre-emphasis");
  688. if (ret)
  689. goto early_exit;
  690. ret = parse_lt_param(dev, &parser->swing_hbr_rbr, "qcom,hbr-rbr-voltage-swing");
  691. if (ret)
  692. goto early_exit;
  693. ret = parse_lt_param(dev, &parser->pre_emp_hbr_rbr, "qcom,hbr-rbr-pre-emphasis");
  694. if (ret)
  695. goto early_exit;
  696. parser->valid_lt_params = true;
  697. DP_DEBUG("link training parameters parsing success\n");
  698. goto end;
  699. early_exit:
  700. if(ret == -EINVAL)
  701. DP_WARN("link training parameters not found - using default values\n");
  702. else
  703. DP_ERR("link training parameters parsing failure ret: %d\n", ret);
  704. dp_parser_clear_link_training_params(parser);
  705. end:
  706. return;
  707. }
  708. static int dp_parser_parse(struct dp_parser *parser)
  709. {
  710. int rc = 0;
  711. if (!parser) {
  712. DP_ERR("invalid input\n");
  713. rc = -EINVAL;
  714. goto err;
  715. }
  716. rc = dp_parser_reg(parser);
  717. if (rc)
  718. goto err;
  719. rc = dp_parser_aux(parser);
  720. if (rc)
  721. goto err;
  722. rc = dp_parser_misc(parser);
  723. if (rc)
  724. goto err;
  725. rc = dp_parser_clock(parser);
  726. if (rc)
  727. goto err;
  728. rc = dp_parser_regulator(parser);
  729. if (rc)
  730. goto err;
  731. rc = dp_parser_gpio(parser);
  732. if (rc)
  733. goto err;
  734. rc = dp_parser_catalog(parser);
  735. if (rc)
  736. goto err;
  737. rc = dp_parser_pinctrl(parser);
  738. if (rc)
  739. goto err;
  740. rc = dp_parser_msm_hdcp_dev(parser);
  741. if (rc)
  742. goto err;
  743. rc = dp_parser_mst(parser);
  744. if (rc)
  745. goto err;
  746. dp_parser_dsc(parser);
  747. dp_parser_fec(parser);
  748. dp_parser_widebus(parser);
  749. dp_parser_qos(parser);
  750. dp_parser_link_training_params(parser);
  751. err:
  752. return rc;
  753. }
  754. static struct dp_io_data *dp_parser_get_io(struct dp_parser *dp_parser,
  755. char *name)
  756. {
  757. int i = 0;
  758. struct dp_io *io;
  759. if (!dp_parser) {
  760. DP_ERR("invalid input\n");
  761. goto err;
  762. }
  763. io = &dp_parser->io;
  764. for (i = 0; i < io->len; i++) {
  765. struct dp_io_data *data = &io->data[i];
  766. if (!strcmp(data->name, name))
  767. return data;
  768. }
  769. err:
  770. return NULL;
  771. }
  772. static void dp_parser_get_io_buf(struct dp_parser *dp_parser, char *name)
  773. {
  774. int i = 0;
  775. struct dp_io *io;
  776. if (!dp_parser) {
  777. DP_ERR("invalid input\n");
  778. return;
  779. }
  780. io = &dp_parser->io;
  781. for (i = 0; i < io->len; i++) {
  782. struct dp_io_data *data = &io->data[i];
  783. if (!strcmp(data->name, name)) {
  784. if (!data->buf)
  785. data->buf = devm_kzalloc(&dp_parser->pdev->dev,
  786. data->io.len, GFP_KERNEL);
  787. }
  788. }
  789. }
  790. static void dp_parser_clear_io_buf(struct dp_parser *dp_parser)
  791. {
  792. int i = 0;
  793. struct dp_io *io;
  794. if (!dp_parser) {
  795. DP_ERR("invalid input\n");
  796. return;
  797. }
  798. io = &dp_parser->io;
  799. for (i = 0; i < io->len; i++) {
  800. struct dp_io_data *data = &io->data[i];
  801. if (data->buf)
  802. devm_kfree(&dp_parser->pdev->dev, data->buf);
  803. data->buf = NULL;
  804. }
  805. }
  806. struct dp_parser *dp_parser_get(struct platform_device *pdev)
  807. {
  808. struct dp_parser *parser;
  809. parser = devm_kzalloc(&pdev->dev, sizeof(*parser), GFP_KERNEL);
  810. if (!parser)
  811. return ERR_PTR(-ENOMEM);
  812. parser->parse = dp_parser_parse;
  813. parser->get_io = dp_parser_get_io;
  814. parser->get_io_buf = dp_parser_get_io_buf;
  815. parser->clear_io_buf = dp_parser_clear_io_buf;
  816. parser->pdev = pdev;
  817. return parser;
  818. }
  819. void dp_parser_put(struct dp_parser *parser)
  820. {
  821. int i = 0;
  822. struct dss_module_power *power = NULL;
  823. if (!parser) {
  824. DP_ERR("invalid parser module\n");
  825. return;
  826. }
  827. power = parser->mp;
  828. for (i = 0; i < DP_MAX_PM; i++) {
  829. dp_parser_put_clk_data(&parser->pdev->dev, &power[i]);
  830. dp_parser_put_vreg_data(&parser->pdev->dev, &power[i]);
  831. dp_parser_put_gpio_data(&parser->pdev->dev, &power[i]);
  832. }
  833. dp_parser_clear_link_training_params(parser);
  834. dp_parser_clear_io_buf(parser);
  835. devm_kfree(&parser->pdev->dev, parser->io.data);
  836. devm_kfree(&parser->pdev->dev, parser);
  837. }