dp_parser.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944
  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. #if defined(CONFIG_SECDP)
  11. #include "secdp.h"
  12. #endif
  13. static void dp_parser_unmap_io_resources(struct dp_parser *parser)
  14. {
  15. int i = 0;
  16. struct dp_io *io = &parser->io;
  17. for (i = 0; i < io->len; i++)
  18. msm_dss_iounmap(&io->data[i].io);
  19. }
  20. static int dp_parser_reg(struct dp_parser *parser)
  21. {
  22. int rc = 0, i = 0;
  23. u32 reg_count;
  24. struct platform_device *pdev = parser->pdev;
  25. struct dp_io *io = &parser->io;
  26. struct device *dev = &pdev->dev;
  27. reg_count = of_property_count_strings(dev->of_node, "reg-names");
  28. if (reg_count <= 0) {
  29. DP_ERR("no reg defined\n");
  30. return -EINVAL;
  31. }
  32. io->len = reg_count;
  33. io->data = devm_kzalloc(dev, sizeof(struct dp_io_data) * reg_count,
  34. GFP_KERNEL);
  35. if (!io->data)
  36. return -ENOMEM;
  37. for (i = 0; i < reg_count; i++) {
  38. of_property_read_string_index(dev->of_node,
  39. "reg-names", i, &io->data[i].name);
  40. rc = msm_dss_ioremap_byname(pdev, &io->data[i].io,
  41. io->data[i].name);
  42. if (rc) {
  43. DP_ERR("unable to remap %s resources\n",
  44. io->data[i].name);
  45. goto err;
  46. }
  47. }
  48. return 0;
  49. err:
  50. dp_parser_unmap_io_resources(parser);
  51. return rc;
  52. }
  53. static const char *dp_get_phy_aux_config_property(u32 cfg_type)
  54. {
  55. switch (cfg_type) {
  56. case PHY_AUX_CFG0:
  57. return "qcom,aux-cfg0-settings";
  58. case PHY_AUX_CFG1:
  59. return "qcom,aux-cfg1-settings";
  60. case PHY_AUX_CFG2:
  61. return "qcom,aux-cfg2-settings";
  62. case PHY_AUX_CFG3:
  63. return "qcom,aux-cfg3-settings";
  64. case PHY_AUX_CFG4:
  65. return "qcom,aux-cfg4-settings";
  66. case PHY_AUX_CFG5:
  67. return "qcom,aux-cfg5-settings";
  68. case PHY_AUX_CFG6:
  69. return "qcom,aux-cfg6-settings";
  70. case PHY_AUX_CFG7:
  71. return "qcom,aux-cfg7-settings";
  72. case PHY_AUX_CFG8:
  73. return "qcom,aux-cfg8-settings";
  74. case PHY_AUX_CFG9:
  75. return "qcom,aux-cfg9-settings";
  76. default:
  77. return "unknown";
  78. }
  79. }
  80. static void dp_parser_phy_aux_cfg_reset(struct dp_parser *parser)
  81. {
  82. int i = 0;
  83. for (i = 0; i < PHY_AUX_CFG_MAX; i++)
  84. parser->aux_cfg[i] = (const struct dp_aux_cfg){ 0 };
  85. }
  86. static int dp_parser_aux(struct dp_parser *parser)
  87. {
  88. struct device_node *of_node = parser->pdev->dev.of_node;
  89. int len = 0, i = 0, j = 0, config_count = 0;
  90. const char *data;
  91. int const minimum_config_count = 1;
  92. for (i = 0; i < PHY_AUX_CFG_MAX; i++) {
  93. const char *property = dp_get_phy_aux_config_property(i);
  94. data = of_get_property(of_node, property, &len);
  95. if (!data) {
  96. DP_ERR("Unable to read %s\n", property);
  97. goto error;
  98. }
  99. config_count = len - 1;
  100. if ((config_count < minimum_config_count) ||
  101. (config_count > DP_AUX_CFG_MAX_VALUE_CNT)) {
  102. DP_ERR("Invalid config count (%d) configs for %s\n",
  103. config_count, property);
  104. goto error;
  105. }
  106. parser->aux_cfg[i].offset = data[0];
  107. parser->aux_cfg[i].cfg_cnt = config_count;
  108. DP_DEBUG("%s offset=0x%x, cfg_cnt=%d\n",
  109. property,
  110. parser->aux_cfg[i].offset,
  111. parser->aux_cfg[i].cfg_cnt);
  112. for (j = 1; j < len; j++) {
  113. parser->aux_cfg[i].lut[j - 1] = data[j];
  114. DP_DEBUG("%s lut[%d]=0x%x\n",
  115. property,
  116. i,
  117. parser->aux_cfg[i].lut[j - 1]);
  118. }
  119. }
  120. return 0;
  121. error:
  122. dp_parser_phy_aux_cfg_reset(parser);
  123. return -EINVAL;
  124. }
  125. #if defined(CONFIG_SECDP_DBG)
  126. int secdp_aux_cfg_show(struct dp_parser *parser, char *buf)
  127. {
  128. struct dp_aux_cfg *cfg = parser->aux_cfg;
  129. int i, rc = 0;
  130. for (i = 0; i < PHY_AUX_CFG_MAX; i++) {
  131. rc += scnprintf(buf + rc, PAGE_SIZE - rc,
  132. "%s: offset=0x%x, value=0x%02x\n",
  133. dp_phy_aux_config_type_to_string(i),
  134. cfg[i].offset,
  135. cfg[i].lut[cfg[i].current_index]);
  136. }
  137. return rc;
  138. }
  139. int secdp_aux_cfg_store(struct dp_parser *parser, char *buf)
  140. {
  141. struct dp_aux_cfg *cfg = parser->aux_cfg;
  142. char *tok;
  143. u32 value;
  144. int i, rc = 0;
  145. for (i = 0; i < PHY_AUX_CFG_MAX; i++) {
  146. tok = strsep(&buf, ",");
  147. if (!tok)
  148. continue;
  149. rc = kstrtouint(tok, 16, &value);
  150. if (rc) {
  151. DP_ERR("error: %s rc:%d\n", tok, rc);
  152. break;
  153. }
  154. cfg[i].lut[cfg[i].current_index] = value;
  155. DP_DEBUG("offset=0x%x, value=0x%02x\n", cfg[i].offset,
  156. cfg[i].lut[cfg[i].current_index]);
  157. }
  158. return rc;
  159. }
  160. #endif
  161. static int dp_parser_misc(struct dp_parser *parser)
  162. {
  163. int rc = 0, len = 0, i = 0;
  164. const char *data = NULL;
  165. struct device_node *of_node = parser->pdev->dev.of_node;
  166. data = of_get_property(of_node, "qcom,logical2physical-lane-map", &len);
  167. if (data && (len == DP_MAX_PHY_LN)) {
  168. for (i = 0; i < len; i++)
  169. parser->l_map[i] = data[i];
  170. }
  171. data = of_get_property(of_node, "qcom,pn-swap-lane-map", &len);
  172. if (data && (len == DP_MAX_PHY_LN)) {
  173. for (i = 0; i < len; i++)
  174. parser->l_pnswap |= (data[i] & 0x01) << i;
  175. }
  176. rc = of_property_read_u32(of_node,
  177. "qcom,max-pclk-frequency-khz", &parser->max_pclk_khz);
  178. if (rc)
  179. parser->max_pclk_khz = DP_MAX_PIXEL_CLK_KHZ;
  180. rc = of_property_read_u32(of_node,
  181. "qcom,max-lclk-frequency-khz", &parser->max_lclk_khz);
  182. if (rc)
  183. parser->max_lclk_khz = DP_MAX_LINK_CLK_KHZ;
  184. return 0;
  185. }
  186. static int dp_parser_msm_hdcp_dev(struct dp_parser *parser)
  187. {
  188. struct device_node *node;
  189. struct platform_device *pdev;
  190. node = of_find_compatible_node(NULL, NULL, "qcom,msm-hdcp");
  191. if (!node) {
  192. // This is a non-fatal error, module initialization can proceed
  193. DP_WARN("couldn't find msm-hdcp node\n");
  194. return 0;
  195. }
  196. pdev = of_find_device_by_node(node);
  197. if (!pdev) {
  198. // This is a non-fatal error, module initialization can proceed
  199. DP_WARN("couldn't find msm-hdcp pdev\n");
  200. return 0;
  201. }
  202. parser->msm_hdcp_dev = &pdev->dev;
  203. return 0;
  204. }
  205. static int dp_parser_pinctrl(struct dp_parser *parser)
  206. {
  207. int rc = 0;
  208. struct dp_pinctrl *pinctrl = &parser->pinctrl;
  209. #if IS_ENABLED(CONFIG_SBU_SWITCH_CONTROL)
  210. DP_INFO("max77775: no need to parse dp_aux gpios\n");
  211. return 0;
  212. #endif
  213. pinctrl->pin = devm_pinctrl_get(&parser->pdev->dev);
  214. if (IS_ERR_OR_NULL(pinctrl->pin)) {
  215. DP_DEBUG("failed to get pinctrl, rc=%d\n", rc);
  216. goto error;
  217. }
  218. pinctrl->state_active = pinctrl_lookup_state(pinctrl->pin,
  219. "mdss_dp_active");
  220. if (IS_ERR_OR_NULL(pinctrl->state_active)) {
  221. rc = PTR_ERR(pinctrl->state_active);
  222. DP_ERR("failed to get pinctrl active state, rc=%d\n", rc);
  223. goto error;
  224. }
  225. pinctrl->state_suspend = pinctrl_lookup_state(pinctrl->pin,
  226. "mdss_dp_sleep");
  227. if (IS_ERR_OR_NULL(pinctrl->state_suspend)) {
  228. rc = PTR_ERR(pinctrl->state_suspend);
  229. DP_ERR("failed to get pinctrl suspend state, rc=%d\n", rc);
  230. goto error;
  231. }
  232. error:
  233. return rc;
  234. }
  235. static int dp_parser_gpio(struct dp_parser *parser)
  236. {
  237. int i = 0;
  238. struct device *dev = &parser->pdev->dev;
  239. struct device_node *of_node = dev->of_node;
  240. struct dss_module_power *mp = &parser->mp[DP_CORE_PM];
  241. static const char * const dp_gpios[] = {
  242. "qcom,aux-en-gpio",
  243. "qcom,aux-sel-gpio",
  244. "qcom,usbplug-cc-gpio",
  245. };
  246. if (of_find_property(of_node, "qcom,dp-gpio-aux-switch", NULL))
  247. parser->gpio_aux_switch = true;
  248. mp->gpio_config = devm_kzalloc(dev,
  249. sizeof(struct dss_gpio) * ARRAY_SIZE(dp_gpios), GFP_KERNEL);
  250. if (!mp->gpio_config)
  251. return -ENOMEM;
  252. mp->num_gpio = ARRAY_SIZE(dp_gpios);
  253. for (i = 0; i < ARRAY_SIZE(dp_gpios); i++) {
  254. mp->gpio_config[i].gpio = of_get_named_gpio(of_node,
  255. dp_gpios[i], 0);
  256. if (!gpio_is_valid(mp->gpio_config[i].gpio)) {
  257. DP_DEBUG("%s gpio not specified\n", dp_gpios[i]);
  258. /* In case any gpio was not specified, we think gpio
  259. * aux switch also was not specified.
  260. */
  261. parser->gpio_aux_switch = false;
  262. continue;
  263. }
  264. strlcpy(mp->gpio_config[i].gpio_name, dp_gpios[i],
  265. sizeof(mp->gpio_config[i].gpio_name));
  266. mp->gpio_config[i].value = 0;
  267. }
  268. #if defined(CONFIG_SECDP)
  269. for (i = 0; i < ARRAY_SIZE(dp_gpios); i++) {
  270. DP_INFO("name:%s gpio:%u value:%u\n",
  271. mp->gpio_config[i].gpio_name,
  272. mp->gpio_config[i].gpio, mp->gpio_config[i].value);
  273. }
  274. #endif
  275. return 0;
  276. }
  277. static const char *dp_parser_supply_node_name(enum dp_pm_type module)
  278. {
  279. switch (module) {
  280. case DP_CORE_PM: return "qcom,core-supply-entries";
  281. case DP_CTRL_PM: return "qcom,ctrl-supply-entries";
  282. case DP_PHY_PM: return "qcom,phy-supply-entries";
  283. case DP_PLL_PM: return "qcom,pll-supply-entries";
  284. default: return "???";
  285. }
  286. }
  287. static int dp_parser_get_vreg(struct dp_parser *parser,
  288. enum dp_pm_type module)
  289. {
  290. int i = 0, rc = 0;
  291. u32 tmp = 0;
  292. const char *pm_supply_name = NULL;
  293. struct device_node *supply_node = NULL;
  294. struct device_node *of_node = parser->pdev->dev.of_node;
  295. struct device_node *supply_root_node = NULL;
  296. struct dss_module_power *mp = &parser->mp[module];
  297. mp->num_vreg = 0;
  298. pm_supply_name = dp_parser_supply_node_name(module);
  299. #if defined(CONFIG_SECDP)
  300. DP_DEBUG("pm_supply_name: %s\n", pm_supply_name);
  301. #endif
  302. supply_root_node = of_get_child_by_name(of_node, pm_supply_name);
  303. if (!supply_root_node) {
  304. DP_DEBUG("no supply entry present: %s\n", pm_supply_name);
  305. goto novreg;
  306. }
  307. mp->num_vreg = of_get_available_child_count(supply_root_node);
  308. if (mp->num_vreg == 0) {
  309. DP_DEBUG("no vreg\n");
  310. goto novreg;
  311. } else {
  312. DP_DEBUG("vreg found. count=%d\n", mp->num_vreg);
  313. }
  314. mp->vreg_config = devm_kzalloc(&parser->pdev->dev,
  315. sizeof(struct dss_vreg) * mp->num_vreg, GFP_KERNEL);
  316. if (!mp->vreg_config) {
  317. rc = -ENOMEM;
  318. goto error;
  319. }
  320. for_each_child_of_node(supply_root_node, supply_node) {
  321. const char *st = NULL;
  322. /* vreg-name */
  323. rc = of_property_read_string(supply_node,
  324. "qcom,supply-name", &st);
  325. if (rc) {
  326. DP_ERR("error reading name. rc=%d\n",
  327. rc);
  328. goto error;
  329. }
  330. snprintf(mp->vreg_config[i].vreg_name,
  331. ARRAY_SIZE((mp->vreg_config[i].vreg_name)), "%s", st);
  332. /* vreg-min-voltage */
  333. rc = of_property_read_u32(supply_node,
  334. "qcom,supply-min-voltage", &tmp);
  335. if (rc) {
  336. DP_ERR("error reading min volt. rc=%d\n",
  337. rc);
  338. goto error;
  339. }
  340. mp->vreg_config[i].min_voltage = tmp;
  341. /* vreg-max-voltage */
  342. rc = of_property_read_u32(supply_node,
  343. "qcom,supply-max-voltage", &tmp);
  344. if (rc) {
  345. DP_ERR("error reading max volt. rc=%d\n",
  346. rc);
  347. goto error;
  348. }
  349. mp->vreg_config[i].max_voltage = tmp;
  350. /* enable-load */
  351. rc = of_property_read_u32(supply_node,
  352. "qcom,supply-enable-load", &tmp);
  353. if (rc) {
  354. DP_ERR("error reading enable load. rc=%d\n",
  355. rc);
  356. goto error;
  357. }
  358. mp->vreg_config[i].enable_load = tmp;
  359. /* disable-load */
  360. rc = of_property_read_u32(supply_node,
  361. "qcom,supply-disable-load", &tmp);
  362. if (rc) {
  363. DP_ERR("error reading disable load. rc=%d\n",
  364. rc);
  365. goto error;
  366. }
  367. mp->vreg_config[i].disable_load = tmp;
  368. DP_DEBUG("%s min=%d, max=%d, enable=%d, disable=%d\n",
  369. mp->vreg_config[i].vreg_name,
  370. mp->vreg_config[i].min_voltage,
  371. mp->vreg_config[i].max_voltage,
  372. mp->vreg_config[i].enable_load,
  373. mp->vreg_config[i].disable_load
  374. );
  375. ++i;
  376. }
  377. return rc;
  378. error:
  379. if (mp->vreg_config) {
  380. devm_kfree(&parser->pdev->dev, mp->vreg_config);
  381. mp->vreg_config = NULL;
  382. }
  383. novreg:
  384. mp->num_vreg = 0;
  385. return rc;
  386. }
  387. static void dp_parser_put_vreg_data(struct device *dev,
  388. struct dss_module_power *mp)
  389. {
  390. if (!mp) {
  391. DEV_ERR("invalid input\n");
  392. return;
  393. }
  394. if (mp->vreg_config) {
  395. devm_kfree(dev, mp->vreg_config);
  396. mp->vreg_config = NULL;
  397. }
  398. mp->num_vreg = 0;
  399. }
  400. #if defined(CONFIG_SECDP)
  401. static struct regulator *secdp_get_aux_pullup_vreg(struct device *dev)
  402. {
  403. struct regulator *vreg = NULL;
  404. vreg = devm_regulator_get(dev, "aux-pullup");
  405. if (IS_ERR(vreg)) {
  406. DP_ERR("unable to get aux-pullup vdd supply\n");
  407. return NULL;
  408. }
  409. DP_INFO("get aux-pullup vdd success\n");
  410. return vreg;
  411. }
  412. #endif
  413. static int dp_parser_regulator(struct dp_parser *parser)
  414. {
  415. int i, rc = 0;
  416. struct platform_device *pdev = parser->pdev;
  417. /* Parse the regulator information */
  418. for (i = DP_CORE_PM; i < DP_MAX_PM; i++) {
  419. rc = dp_parser_get_vreg(parser, i);
  420. if (rc) {
  421. DP_ERR("get_dt_vreg_data failed for %s. rc=%d\n",
  422. dp_parser_pm_name(i), rc);
  423. i--;
  424. for (; i >= DP_CORE_PM; i--)
  425. dp_parser_put_vreg_data(&pdev->dev,
  426. &parser->mp[i]);
  427. break;
  428. }
  429. }
  430. #if defined(CONFIG_SECDP)
  431. parser->aux_pullup_vreg = secdp_get_aux_pullup_vreg(&pdev->dev);
  432. #endif
  433. return rc;
  434. }
  435. static bool dp_parser_check_prefix(const char *clk_prefix, const char *clk_name)
  436. {
  437. return !!strnstr(clk_name, clk_prefix, strlen(clk_name));
  438. }
  439. static void dp_parser_put_clk_data(struct device *dev,
  440. struct dss_module_power *mp)
  441. {
  442. if (!mp) {
  443. DEV_ERR("%s: invalid input\n", __func__);
  444. return;
  445. }
  446. if (mp->clk_config) {
  447. devm_kfree(dev, mp->clk_config);
  448. mp->clk_config = NULL;
  449. }
  450. mp->num_clk = 0;
  451. }
  452. static void dp_parser_put_gpio_data(struct device *dev,
  453. struct dss_module_power *mp)
  454. {
  455. if (!mp) {
  456. DEV_ERR("%s: invalid input\n", __func__);
  457. return;
  458. }
  459. if (mp->gpio_config) {
  460. devm_kfree(dev, mp->gpio_config);
  461. mp->gpio_config = NULL;
  462. }
  463. mp->num_gpio = 0;
  464. }
  465. static int dp_parser_init_clk_data(struct dp_parser *parser)
  466. {
  467. int num_clk = 0, i = 0, rc = 0;
  468. int core_clk_count = 0, link_clk_count = 0;
  469. int strm0_clk_count = 0, strm1_clk_count = 0;
  470. const char *core_clk = "core";
  471. const char *strm0_clk = "strm0";
  472. const char *strm1_clk = "strm1";
  473. const char *link_clk = "link";
  474. const char *clk_name;
  475. struct device *dev = &parser->pdev->dev;
  476. struct dss_module_power *core_power = &parser->mp[DP_CORE_PM];
  477. struct dss_module_power *strm0_power = &parser->mp[DP_STREAM0_PM];
  478. struct dss_module_power *strm1_power = &parser->mp[DP_STREAM1_PM];
  479. struct dss_module_power *link_power = &parser->mp[DP_LINK_PM];
  480. num_clk = of_property_count_strings(dev->of_node, "clock-names");
  481. if (num_clk <= 0) {
  482. DP_ERR("no clocks are defined\n");
  483. rc = -EINVAL;
  484. goto exit;
  485. }
  486. for (i = 0; i < num_clk; i++) {
  487. of_property_read_string_index(dev->of_node,
  488. "clock-names", i, &clk_name);
  489. if (dp_parser_check_prefix(core_clk, clk_name))
  490. core_clk_count++;
  491. if (dp_parser_check_prefix(strm0_clk, clk_name))
  492. strm0_clk_count++;
  493. if (dp_parser_check_prefix(strm1_clk, clk_name))
  494. strm1_clk_count++;
  495. if (dp_parser_check_prefix(link_clk, clk_name))
  496. link_clk_count++;
  497. }
  498. /* Initialize the CORE power module */
  499. if (core_clk_count <= 0) {
  500. DP_ERR("no core clocks are defined\n");
  501. rc = -EINVAL;
  502. goto exit;
  503. }
  504. core_power->num_clk = core_clk_count;
  505. core_power->clk_config = devm_kzalloc(dev,
  506. sizeof(struct dss_clk) * core_power->num_clk,
  507. GFP_KERNEL);
  508. if (!core_power->clk_config) {
  509. rc = -EINVAL;
  510. goto exit;
  511. }
  512. /* Initialize the STREAM0 power module */
  513. if (strm0_clk_count <= 0) {
  514. DP_DEBUG("no strm0 clocks are defined\n");
  515. } else {
  516. strm0_power->num_clk = strm0_clk_count;
  517. strm0_power->clk_config = devm_kzalloc(dev,
  518. sizeof(struct dss_clk) * strm0_power->num_clk,
  519. GFP_KERNEL);
  520. if (!strm0_power->clk_config) {
  521. strm0_power->num_clk = 0;
  522. rc = -EINVAL;
  523. goto strm0_clock_error;
  524. }
  525. }
  526. /* Initialize the STREAM1 power module */
  527. if (strm1_clk_count <= 0) {
  528. DP_DEBUG("no strm1 clocks are defined\n");
  529. } else {
  530. strm1_power->num_clk = strm1_clk_count;
  531. strm1_power->clk_config = devm_kzalloc(dev,
  532. sizeof(struct dss_clk) * strm1_power->num_clk,
  533. GFP_KERNEL);
  534. if (!strm1_power->clk_config) {
  535. strm1_power->num_clk = 0;
  536. rc = -EINVAL;
  537. goto strm1_clock_error;
  538. }
  539. }
  540. /* Initialize the link power module */
  541. if (link_clk_count <= 0) {
  542. DP_ERR("no link clocks are defined\n");
  543. rc = -EINVAL;
  544. goto link_clock_error;
  545. }
  546. link_power->num_clk = link_clk_count;
  547. link_power->clk_config = devm_kzalloc(dev,
  548. sizeof(struct dss_clk) * link_power->num_clk,
  549. GFP_KERNEL);
  550. if (!link_power->clk_config) {
  551. link_power->num_clk = 0;
  552. rc = -EINVAL;
  553. goto link_clock_error;
  554. }
  555. return rc;
  556. link_clock_error:
  557. dp_parser_put_clk_data(dev, strm1_power);
  558. strm1_clock_error:
  559. dp_parser_put_clk_data(dev, strm0_power);
  560. strm0_clock_error:
  561. dp_parser_put_clk_data(dev, core_power);
  562. exit:
  563. return rc;
  564. }
  565. static int dp_parser_clock(struct dp_parser *parser)
  566. {
  567. int rc = 0, i = 0;
  568. int num_clk = 0;
  569. int core_clk_index = 0, link_clk_index = 0;
  570. int core_clk_count = 0, link_clk_count = 0;
  571. int strm0_clk_index = 0, strm1_clk_index = 0;
  572. int strm0_clk_count = 0, strm1_clk_count = 0;
  573. int clock_mmrm = 0;
  574. const char *clk_name;
  575. const char *core_clk = "core";
  576. const char *strm0_clk = "strm0";
  577. const char *strm1_clk = "strm1";
  578. const char *link_clk = "link";
  579. struct device *dev = &parser->pdev->dev;
  580. struct dss_module_power *core_power;
  581. struct dss_module_power *strm0_power;
  582. struct dss_module_power *strm1_power;
  583. struct dss_module_power *link_power;
  584. core_power = &parser->mp[DP_CORE_PM];
  585. strm0_power = &parser->mp[DP_STREAM0_PM];
  586. strm1_power = &parser->mp[DP_STREAM1_PM];
  587. link_power = &parser->mp[DP_LINK_PM];
  588. rc = dp_parser_init_clk_data(parser);
  589. if (rc) {
  590. DP_ERR("failed to initialize power data\n");
  591. rc = -EINVAL;
  592. goto exit;
  593. }
  594. core_clk_count = core_power->num_clk;
  595. link_clk_count = link_power->num_clk;
  596. strm0_clk_count = strm0_power->num_clk;
  597. strm1_clk_count = strm1_power->num_clk;
  598. num_clk = of_property_count_strings(dev->of_node, "clock-names");
  599. for (i = 0; i < num_clk; i++) {
  600. of_property_read_string_index(dev->of_node, "clock-names",
  601. i, &clk_name);
  602. if (dp_parser_check_prefix(core_clk, clk_name) &&
  603. core_clk_index < core_clk_count) {
  604. struct dss_clk *clk =
  605. &core_power->clk_config[core_clk_index];
  606. strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name));
  607. clk->type = DSS_CLK_AHB;
  608. core_clk_index++;
  609. } else if (dp_parser_check_prefix(link_clk, clk_name) &&
  610. link_clk_index < link_clk_count) {
  611. struct dss_clk *clk =
  612. &link_power->clk_config[link_clk_index];
  613. strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name));
  614. link_clk_index++;
  615. clock_mmrm = 0;
  616. of_property_read_u32_index(dev->of_node, "clock-mmrm", i, &clock_mmrm);
  617. if (clock_mmrm) {
  618. clk->type = DSS_CLK_MMRM;
  619. clk->mmrm.clk_id = clock_mmrm;
  620. } else if (!strcmp(clk_name, "link_clk_src")) {
  621. clk->type = DSS_CLK_PCLK;
  622. } else {
  623. clk->type = DSS_CLK_AHB;
  624. }
  625. } else if (dp_parser_check_prefix(strm0_clk, clk_name) &&
  626. strm0_clk_index < strm0_clk_count) {
  627. struct dss_clk *clk =
  628. &strm0_power->clk_config[strm0_clk_index];
  629. strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name));
  630. strm0_clk_index++;
  631. clk->type = DSS_CLK_PCLK;
  632. } else if (dp_parser_check_prefix(strm1_clk, clk_name) &&
  633. strm1_clk_index < strm1_clk_count) {
  634. struct dss_clk *clk =
  635. &strm1_power->clk_config[strm1_clk_index];
  636. strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name));
  637. strm1_clk_index++;
  638. clk->type = DSS_CLK_PCLK;
  639. }
  640. }
  641. DP_DEBUG("clock parsing successful\n");
  642. exit:
  643. return rc;
  644. }
  645. static int dp_parser_catalog(struct dp_parser *parser)
  646. {
  647. int rc;
  648. u32 version;
  649. struct device *dev = &parser->pdev->dev;
  650. rc = of_property_read_u32(dev->of_node, "qcom,phy-version", &version);
  651. if (!rc)
  652. parser->hw_cfg.phy_version = version;
  653. return 0;
  654. }
  655. static int dp_parser_mst(struct dp_parser *parser)
  656. {
  657. struct device *dev = &parser->pdev->dev;
  658. int i;
  659. parser->has_mst = of_property_read_bool(dev->of_node,
  660. "qcom,mst-enable");
  661. #if defined(CONFIG_SECDP)
  662. parser->mst_support = of_property_read_bool(dev->of_node,
  663. "secdp,mst-support");
  664. if (!parser->mst_support) {
  665. parser->has_mst = false;
  666. DP_INFO("[secdp] mst disable!\n");
  667. }
  668. #endif
  669. parser->has_mst_sideband = parser->has_mst;
  670. DP_DEBUG("mst parsing successful. mst:%d\n", parser->has_mst);
  671. for (i = 0; i < MAX_DP_MST_STREAMS; i++) {
  672. of_property_read_u32_index(dev->of_node,
  673. "qcom,mst-fixed-topology-ports", i,
  674. &parser->mst_fixed_port[i]);
  675. }
  676. return 0;
  677. }
  678. static void dp_parser_dsc(struct dp_parser *parser)
  679. {
  680. struct device *dev = &parser->pdev->dev;
  681. parser->dsc_feature_enable = of_property_read_bool(dev->of_node,
  682. "qcom,dsc-feature-enable");
  683. #if defined(SECDP_MAX_HBR2)
  684. parser->dsc_feature_enable = false;
  685. DP_INFO("[secdp] dsc disable!\n");
  686. #endif
  687. parser->dsc_continuous_pps = of_property_read_bool(dev->of_node,
  688. "qcom,dsc-continuous-pps");
  689. DP_DEBUG("dsc parsing successful. dsc:%d\n",
  690. parser->dsc_feature_enable);
  691. DP_DEBUG("cont_pps:%d\n",
  692. parser->dsc_continuous_pps);
  693. }
  694. static void dp_parser_qos(struct dp_parser *parser)
  695. {
  696. struct device *dev = &parser->pdev->dev;
  697. u32 mask, latency;
  698. int rc;
  699. rc = of_property_read_u32(dev->of_node, "qcom,qos-cpu-latency-us", &latency);
  700. if (rc)
  701. return;
  702. rc = of_property_read_u32(dev->of_node, "qcom,qos-cpu-mask", &mask);
  703. if (rc)
  704. return;
  705. parser->qos_cpu_mask = mask;
  706. parser->qos_cpu_latency = latency;
  707. DP_DEBUG("qos parsing successful. mask:%x latency:%ld\n", mask, latency);
  708. }
  709. static void dp_parser_fec(struct dp_parser *parser)
  710. {
  711. struct device *dev = &parser->pdev->dev;
  712. parser->fec_feature_enable = of_property_read_bool(dev->of_node,
  713. "qcom,fec-feature-enable");
  714. #if defined(SECDP_MAX_HBR2)
  715. parser->fec_feature_enable = false;
  716. DP_INFO("[secdp] fec disable!\n");
  717. #endif
  718. DP_DEBUG("fec parsing successful. fec:%d\n",
  719. parser->fec_feature_enable);
  720. }
  721. static void dp_parser_widebus(struct dp_parser *parser)
  722. {
  723. struct device *dev = &parser->pdev->dev;
  724. parser->has_widebus = of_property_read_bool(dev->of_node,
  725. "qcom,widebus-enable");
  726. DP_DEBUG("widebus parsing successful. widebus:%d\n",
  727. parser->has_widebus);
  728. }
  729. static int parse_lt_param(struct device *dev, u8 **ptr, char *property) {
  730. int ret = 0, i = 0, j = 0, index = 0;
  731. u32 out_val = 0;
  732. u32 expected_elems = MAX_SWING_LEVELS * MAX_PRE_EMP_LEVELS;
  733. u8 parsed_val = 0;
  734. ret = of_property_count_u32_elems(dev->of_node, property);
  735. if (ret != expected_elems) {
  736. return ret;
  737. }
  738. *ptr = devm_kzalloc(dev, sizeof(u8) * expected_elems, GFP_KERNEL);
  739. if (!*ptr)
  740. return -ENOMEM;
  741. for (i = 0; i < MAX_SWING_LEVELS; i++) {
  742. for (j = 0; j < MAX_PRE_EMP_LEVELS; j++) {
  743. index = i * MAX_SWING_LEVELS + j;
  744. ret = of_property_read_u32_index(dev->of_node, property, index, &out_val);
  745. if (ret)
  746. return ret;
  747. parsed_val = out_val & 0xFF;
  748. ((u8 *)*ptr)[index] = parsed_val;
  749. }
  750. }
  751. return ret;
  752. }
  753. static void dp_parser_clear_link_training_params(struct dp_parser *dp_parser)
  754. {
  755. devm_kfree(&dp_parser->pdev->dev, dp_parser->swing_hbr2_3);
  756. devm_kfree(&dp_parser->pdev->dev, dp_parser->pre_emp_hbr2_3);
  757. devm_kfree(&dp_parser->pdev->dev, dp_parser->swing_hbr_rbr);
  758. devm_kfree(&dp_parser->pdev->dev, dp_parser->pre_emp_hbr_rbr);
  759. dp_parser->swing_hbr2_3 = NULL;
  760. dp_parser->pre_emp_hbr2_3 = NULL;
  761. dp_parser->swing_hbr_rbr = NULL;
  762. dp_parser->pre_emp_hbr_rbr = NULL;
  763. dp_parser->valid_lt_params = false;
  764. }
  765. #if !defined(CONFIG_SECDP)
  766. #define HBR2_3_VOLTAGE_SWING "qcom,hbr2-3-voltage-swing"
  767. #define HBR2_3_PRE_EMPHASIS "qcom,hbr2-3-pre-emphasis"
  768. #define HBR_RBR_VOLTAGE_SWING "qcom,hbr-rbr-voltage-swing"
  769. #define HBR_RBR_PRE_EMPHASIS "qcom,hbr-rbr-pre-emphasis"
  770. #else
  771. #define HBR2_3_VOLTAGE_SWING "secdp,hbr2-3-voltage-swing"
  772. #define HBR2_3_PRE_EMPHASIS "secdp,hbr2-3-pre-emphasis"
  773. #define HBR_RBR_VOLTAGE_SWING "secdp,hbr-rbr-voltage-swing"
  774. #define HBR_RBR_PRE_EMPHASIS "secdp,hbr-rbr-pre-emphasis"
  775. #endif
  776. static void dp_parser_link_training_params(struct dp_parser *parser)
  777. {
  778. struct device *dev = &parser->pdev->dev;
  779. int ret = 0;
  780. ret = parse_lt_param(dev, &parser->swing_hbr2_3, "qcom,hbr2-3-voltage-swing");
  781. if (ret)
  782. goto early_exit;
  783. ret = parse_lt_param(dev, &parser->pre_emp_hbr2_3, "qcom,hbr2-3-pre-emphasis");
  784. if (ret)
  785. goto early_exit;
  786. ret = parse_lt_param(dev, &parser->swing_hbr_rbr, "qcom,hbr-rbr-voltage-swing");
  787. if (ret)
  788. goto early_exit;
  789. ret = parse_lt_param(dev, &parser->pre_emp_hbr_rbr, "qcom,hbr-rbr-pre-emphasis");
  790. if (ret)
  791. goto early_exit;
  792. parser->valid_lt_params = true;
  793. DP_DEBUG("link training parameters parsing success\n");
  794. goto end;
  795. early_exit:
  796. if(ret == -EINVAL)
  797. DP_WARN("link training parameters not found - using default values\n");
  798. else
  799. DP_ERR("link training parameters parsing failure ret: %d\n", ret);
  800. dp_parser_clear_link_training_params(parser);
  801. end:
  802. return;
  803. }
  804. #if defined(CONFIG_SECDP)
  805. #if IS_ENABLED(CONFIG_COMBO_REDRIVER_PS5169)
  806. static void secdp_parse_ps5169_param(struct dp_parser *parser);
  807. #endif
  808. static void secdp_parse_misc(struct dp_parser *parser)
  809. {
  810. struct device *dev = &parser->pdev->dev;
  811. struct device_node *of_node = dev->of_node;
  812. const char *data;
  813. int len = 0;
  814. #if IS_ENABLED(CONFIG_COMBO_REDRIVER_PS5169)
  815. secdp_parse_ps5169_param(parser);
  816. #endif
  817. parser->cc_dir_inv = of_property_read_bool(dev->of_node,
  818. "secdp,cc-dir-inv");
  819. DP_DEBUG("secdp,cc-dir-inv: %d\n", parser->cc_dir_inv);
  820. parser->aux_sel_inv = of_property_read_bool(dev->of_node,
  821. "secdp,aux-sel-inv");
  822. DP_DEBUG("secdp,aux-sel-inv: %d\n", parser->aux_sel_inv);
  823. data = of_get_property(of_node, "secdp,redrv", &len);
  824. if (data) {
  825. if (!strncmp(data, "ptn36502", len))
  826. parser->use_redrv = SECDP_REDRV_PTN36502;
  827. else if (!strncmp(data, "ps5169", len))
  828. parser->use_redrv = SECDP_REDRV_PS5169;
  829. else
  830. parser->use_redrv = SECDP_REDRV_NONE;
  831. }
  832. DP_DEBUG("secdp,redrv: %s, %s\n", data,
  833. secdp_redrv_to_string(parser->use_redrv));
  834. data = of_get_property(of_node, "secdp,dex-dft-res", &len);
  835. if (data) {
  836. if (!strncmp(data, "3440x1440", len))
  837. parser->dex_dft_res = DEX_RES_3440X1440;
  838. }
  839. DP_DEBUG("secdp,dex-dft-res: %s, %s\n", data,
  840. secdp_dex_res_to_string(parser->dex_dft_res));
  841. parser->prefer_support = of_property_read_bool(dev->of_node,
  842. "secdp,prefer-res");
  843. DP_DEBUG("secdp,prefer-res: %d\n", parser->prefer_support);
  844. parser->mrr_fps_nolimit = of_property_read_bool(dev->of_node,
  845. "secdp,mrr-fps-nolimit");
  846. DP_DEBUG("secdp,mrr-fps-nolimit: %d\n", parser->mrr_fps_nolimit);
  847. parser->rf_tx_backoff = of_property_read_bool(dev->of_node,
  848. "secdp,rf-tx-backoff");
  849. DP_DEBUG("secdp,rf-tx-backoff: %d\n", parser->rf_tx_backoff);
  850. }
  851. #endif
  852. #if defined(CONFIG_SECDP_DBG)
  853. /*********************************************
  854. *** default DP PHY params ***
  855. *** see pineapple-sde.dtsi ***
  856. *********************************************/
  857. static u8 const hbr_rbr_voltage_swing[MAX_VOLTAGE_LEVELS * MAX_PRE_EMP_LEVELS] = {
  858. 0x07, 0x0f, 0x16, 0x1f, /* sw0, 0.4v */
  859. 0x11, 0x1e, 0x1f, 0xff, /* sw1, 0.6v */
  860. 0x16, 0x1f, 0xff, 0xff, /* sw1, 0.8v */
  861. 0x1f, 0xff, 0xff, 0xff, /* sw1, 1.2v */
  862. };
  863. static u8 const hbr_rbr_pre_emphasis[MAX_VOLTAGE_LEVELS * MAX_PRE_EMP_LEVELS] = {
  864. 0x00, 0x0d, 0x14, 0x1a, /* pe0, 0 db */
  865. 0x00, 0x0e, 0x15, 0xff, /* pe1, 3.5 db */
  866. 0x00, 0x0e, 0xff, 0xff, /* pe2, 6.0 db */
  867. 0x02, 0xff, 0xff, 0xff, /* pe3, 9.5 db */
  868. };
  869. static u8 const hbr2_3_voltage_swing[MAX_VOLTAGE_LEVELS * MAX_PRE_EMP_LEVELS] = {
  870. 0x02, 0x12, 0x16, 0x1a, /* sw0, 0.4v */
  871. 0x09, 0x19, 0x1f, 0xff, /* sw1, 0.6v */
  872. 0x10, 0x1f, 0xff, 0xff, /* sw1, 0.8v */
  873. 0x1f, 0xff, 0xff, 0xff, /* sw1, 1.2v */
  874. };
  875. static u8 const hbr2_3_pre_emphasis[MAX_VOLTAGE_LEVELS * MAX_PRE_EMP_LEVELS] = {
  876. 0x00, 0x0c, 0x15, 0x1b, /* pe0, 0 db */
  877. 0x02, 0x0e, 0x16, 0xff, /* pe1, 3.5 db */
  878. 0x02, 0x11, 0xff, 0xff, /* pe2, 6.0 db */
  879. 0x04, 0xff, 0xff, 0xff, /* pe3, 9.5 db */
  880. };
  881. static void secdp_set_default_phy_param(struct dp_parser *parser,
  882. u8 lr, u8 vxpx)
  883. {
  884. int i, j, index;
  885. for (i = 0; i < MAX_VOLTAGE_LEVELS; i++) {
  886. for (j = 0; j < MAX_PRE_EMP_LEVELS; j++) {
  887. index = i * MAX_VOLTAGE_LEVELS + j;
  888. if (lr & DP_LR_HBR_RBR) {
  889. if (vxpx & DP_PARAM_VX)
  890. parser->swing_hbr_rbr[index] = hbr_rbr_voltage_swing[index];
  891. if (vxpx & DP_PARAM_PX)
  892. parser->pre_emp_hbr_rbr[index] = hbr_rbr_pre_emphasis[index];
  893. }
  894. if (lr & DP_LR_HBR2_3) {
  895. if (vxpx & DP_PARAM_VX)
  896. parser->swing_hbr2_3[index] = hbr2_3_voltage_swing[index];
  897. if (vxpx & DP_PARAM_PX)
  898. parser->pre_emp_hbr2_3[index] = hbr2_3_pre_emphasis[index];
  899. }
  900. }
  901. }
  902. }
  903. static u8 *_secdp_get_lr_target(struct dp_parser *parser,
  904. enum secdp_link_rate_t lr,
  905. enum secdp_phy_param_t vxpx, char *buf, int *len)
  906. {
  907. u8 *target = NULL;
  908. int rc = 0;
  909. if (buf && len)
  910. rc = *len;
  911. if (lr == DP_LR_HBR_RBR) {
  912. if (vxpx == DP_PARAM_VX) {
  913. target = parser->swing_hbr_rbr;
  914. if (buf) {
  915. rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n",
  916. HBR_RBR_VOLTAGE_SWING);
  917. }
  918. } else if (vxpx == DP_PARAM_PX) {
  919. target = parser->pre_emp_hbr_rbr;
  920. if (buf) {
  921. rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n",
  922. HBR_RBR_PRE_EMPHASIS);
  923. }
  924. } else {
  925. DP_ERR("%s: invalid vxpx %d\n",
  926. secdp_link_rate_to_string(lr), vxpx);
  927. }
  928. } else if (lr == DP_LR_HBR2_3) {
  929. if (vxpx == DP_PARAM_VX) {
  930. target = parser->swing_hbr2_3;
  931. if (buf) {
  932. rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n",
  933. HBR2_3_VOLTAGE_SWING);
  934. }
  935. } else if (vxpx == DP_PARAM_PX) {
  936. target = parser->pre_emp_hbr2_3;
  937. if (buf) {
  938. rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n",
  939. HBR2_3_PRE_EMPHASIS);
  940. }
  941. } else {
  942. DP_ERR("%s: invalid vxpx %d\n",
  943. secdp_link_rate_to_string(lr), vxpx);
  944. }
  945. } else {
  946. DP_ERR("invalid link rate %d\n", lr);
  947. }
  948. if (buf && len && (rc != *len))
  949. *len = rc;
  950. return target;
  951. }
  952. int secdp_parse_vxpx_show(struct dp_parser *parser, enum secdp_link_rate_t lr,
  953. enum secdp_phy_param_t vxpx, char *buf)
  954. {
  955. int i = 0, j = 0, index = 0;
  956. int rc = 0;
  957. u8 *target = NULL;
  958. target = _secdp_get_lr_target(parser, lr, vxpx, buf, &rc);
  959. rc += scnprintf(buf + rc, PAGE_SIZE - rc, "=====\n");
  960. for (i = 0; i < MAX_SWING_LEVELS; i++) {
  961. for (j = 0; j < MAX_PRE_EMP_LEVELS; j++) {
  962. index = i * MAX_SWING_LEVELS + j;
  963. rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%02x,", target[index]);
  964. }
  965. rc += scnprintf(buf + rc, PAGE_SIZE - rc, "\n");
  966. }
  967. return rc;
  968. }
  969. int secdp_parse_vxpx_store(struct dp_parser *parser, enum secdp_link_rate_t lr,
  970. enum secdp_phy_param_t vxpx, char *buf)
  971. {
  972. u8 *tok, *target = NULL;
  973. u32 value;
  974. int i, j, index = 0, rc = 0;
  975. if (!strncmp(buf, "reset_all", strlen("reset_all"))) {
  976. DP_DEBUG("[all] reset!\n");
  977. secdp_set_default_phy_param(parser, DP_LR_HBR_RBR | DP_LR_HBR2_3,
  978. DP_PARAM_VX | DP_PARAM_PX);
  979. goto end;
  980. }
  981. if (!strncmp(buf, "reset", strlen("reset"))) {
  982. DP_DEBUG("[%s,%s] reset!\n",
  983. secdp_link_rate_to_string(lr), secdp_phy_type_to_string(vxpx));
  984. secdp_set_default_phy_param(parser, lr, vxpx);
  985. goto end;
  986. }
  987. DP_DEBUG("[%s,%s] set new params!\n",
  988. secdp_link_rate_to_string(lr), secdp_phy_type_to_string(vxpx));
  989. target = _secdp_get_lr_target(parser, lr, vxpx, NULL, NULL);
  990. for (i = 0; i < MAX_SWING_LEVELS; i++) {
  991. for (j = 0; j < MAX_PRE_EMP_LEVELS; j++) {
  992. index = i * MAX_SWING_LEVELS + j;
  993. tok = strsep(&buf, ",");
  994. if (!tok)
  995. continue;
  996. rc = kstrtouint(tok, 16, &value);
  997. if (rc) {
  998. DP_ERR("error: %s rc:%d\n", tok, rc);
  999. goto end;
  1000. }
  1001. target[index] = value;
  1002. }
  1003. }
  1004. end:
  1005. return rc;
  1006. }
  1007. int secdp_show_phy_param(struct dp_parser *parser, char *buf)
  1008. {
  1009. char tmp[SZ_1K] = {0,};
  1010. int rc = 0;
  1011. secdp_parse_vxpx_show(parser, DP_LR_HBR_RBR, DP_PARAM_VX, tmp);
  1012. rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n", tmp);
  1013. memset(tmp, 0, SZ_1K);
  1014. secdp_parse_vxpx_show(parser, DP_LR_HBR_RBR, DP_PARAM_PX, tmp);
  1015. rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n", tmp);
  1016. memset(tmp, 0, SZ_1K);
  1017. secdp_parse_vxpx_show(parser, DP_LR_HBR2_3, DP_PARAM_VX, tmp);
  1018. rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n", tmp);
  1019. memset(tmp, 0, SZ_1K);
  1020. secdp_parse_vxpx_show(parser, DP_LR_HBR2_3, DP_PARAM_PX, tmp);
  1021. rc += scnprintf(buf + rc, PAGE_SIZE - rc, "%s\n", tmp);
  1022. return rc;
  1023. }
  1024. #endif
  1025. #if defined(CONFIG_SECDP) && IS_ENABLED(CONFIG_COMBO_REDRIVER_PS5169)
  1026. static const char *secdp_get_ps5169_rbr_eq0(u32 lvl)
  1027. {
  1028. switch (lvl) {
  1029. case PHY_PS5169_EMP0:
  1030. return "secdp,redrv-rbr-eq0-0";
  1031. case PHY_PS5169_EMP1:
  1032. return "secdp,redrv-rbr-eq0-1";
  1033. case PHY_PS5169_EMP2:
  1034. return "secdp,redrv-rbr-eq0-2";
  1035. case PHY_PS5169_EMP3:
  1036. return "secdp,redrv-rbr-eq0-3";
  1037. default:
  1038. return "secdp,redrv-rbr-eq0-unknown";
  1039. }
  1040. }
  1041. static const char *secdp_get_ps5169_rbr_eq1(u32 lvl)
  1042. {
  1043. switch (lvl) {
  1044. case PHY_PS5169_SWING0:
  1045. return "secdp,redrv-rbr-eq1-0";
  1046. case PHY_PS5169_SWING1:
  1047. return "secdp,redrv-rbr-eq1-1";
  1048. case PHY_PS5169_SWING2:
  1049. return "secdp,redrv-rbr-eq1-2";
  1050. case PHY_PS5169_SWING3:
  1051. return "secdp,redrv-rbr-eq1-3";
  1052. default:
  1053. return "secdp,redrv-rbr-eq1-unknown";
  1054. }
  1055. }
  1056. static int _secdp_parse_ps5169_rbr(struct dp_parser *parser)
  1057. {
  1058. struct device_node *of_node = parser->pdev->dev.of_node;
  1059. int len = 0, i = 0, j = 0;
  1060. const char *data;
  1061. DP_ENTER("\n");
  1062. for (i = 0; i < MAX_PS5169_SWING_LEVELS; i++) {
  1063. const char *property = secdp_get_ps5169_rbr_eq0(i);
  1064. data = of_get_property(of_node, property, &len);
  1065. if (!data || len != 4) {
  1066. DP_ERR("Unable to read %s, len:%d\n", property, len);
  1067. goto error;
  1068. }
  1069. for (j = 0; j < MAX_PS5169_EMP_LEVELS; j++)
  1070. parser->ps5169_rbr_eq0[i][j] = data[j];
  1071. }
  1072. for (i = 0; i < MAX_PS5169_SWING_LEVELS; i++) {
  1073. const char *property = secdp_get_ps5169_rbr_eq1(i);
  1074. data = of_get_property(of_node, property, &len);
  1075. if (!data || len != 4) {
  1076. DP_ERR("Unable to read %s, len:%d\n", property, len);
  1077. goto error;
  1078. }
  1079. for (j = 0; j < MAX_PS5169_EMP_LEVELS; j++)
  1080. parser->ps5169_rbr_eq1[i][j] = data[j];
  1081. }
  1082. return 0;
  1083. error:
  1084. return -EINVAL;
  1085. }
  1086. static const char *secdp_get_ps5169_hbr_eq0(u32 lvl)
  1087. {
  1088. switch (lvl) {
  1089. case PHY_PS5169_EMP0:
  1090. return "secdp,redrv-hbr-eq0-0";
  1091. case PHY_PS5169_EMP1:
  1092. return "secdp,redrv-hbr-eq0-1";
  1093. case PHY_PS5169_EMP2:
  1094. return "secdp,redrv-hbr-eq0-2";
  1095. case PHY_PS5169_EMP3:
  1096. return "secdp,redrv-hbr-eq0-3";
  1097. default:
  1098. return "secdp,redrv-hbr-eq0-unknown";
  1099. }
  1100. }
  1101. static const char *secdp_get_ps5169_hbr_eq1(u32 lvl)
  1102. {
  1103. switch (lvl) {
  1104. case PHY_PS5169_SWING0:
  1105. return "secdp,redrv-hbr-eq1-0";
  1106. case PHY_PS5169_SWING1:
  1107. return "secdp,redrv-hbr-eq1-1";
  1108. case PHY_PS5169_SWING2:
  1109. return "secdp,redrv-hbr-eq1-2";
  1110. case PHY_PS5169_SWING3:
  1111. return "secdp,redrv-hbr-eq1-3";
  1112. default:
  1113. return "secdp,redrv-hbr-eq1-unknown";
  1114. }
  1115. }
  1116. static int _secdp_parse_ps5169_hbr(struct dp_parser *parser)
  1117. {
  1118. struct device_node *of_node = parser->pdev->dev.of_node;
  1119. int len = 0, i = 0, j = 0;
  1120. const char *data;
  1121. DP_ENTER("\n");
  1122. for (i = 0; i < MAX_PS5169_SWING_LEVELS; i++) {
  1123. const char *property = secdp_get_ps5169_hbr_eq0(i);
  1124. data = of_get_property(of_node, property, &len);
  1125. if (!data || len != 4) {
  1126. DP_ERR("Unable to read %s, len:%d\n", property, len);
  1127. goto error;
  1128. }
  1129. for (j = 0; j < MAX_PS5169_EMP_LEVELS; j++)
  1130. parser->ps5169_hbr_eq0[i][j] = data[j];
  1131. }
  1132. for (i = 0; i < MAX_PS5169_SWING_LEVELS; i++) {
  1133. const char *property = secdp_get_ps5169_hbr_eq1(i);
  1134. data = of_get_property(of_node, property, &len);
  1135. if (!data || len != 4) {
  1136. DP_ERR("Unable to read %s, len:%d\n", property, len);
  1137. goto error;
  1138. }
  1139. for (j = 0; j < MAX_PS5169_EMP_LEVELS; j++)
  1140. parser->ps5169_hbr_eq1[i][j] = data[j];
  1141. }
  1142. return 0;
  1143. error:
  1144. return -EINVAL;
  1145. }
  1146. static const char *secdp_get_ps5169_hbr2_eq0(u32 lvl)
  1147. {
  1148. switch (lvl) {
  1149. case PHY_PS5169_EMP0:
  1150. return "secdp,redrv-hbr2-eq0-0";
  1151. case PHY_PS5169_EMP1:
  1152. return "secdp,redrv-hbr2-eq0-1";
  1153. case PHY_PS5169_EMP2:
  1154. return "secdp,redrv-hbr2-eq0-2";
  1155. case PHY_PS5169_EMP3:
  1156. return "secdp,redrv-hbr2-eq0-3";
  1157. default:
  1158. return "secdp,redrv-hbr2-eq0-unknown";
  1159. }
  1160. }
  1161. static const char *secdp_get_ps5169_hbr2_eq1(u32 lvl)
  1162. {
  1163. switch (lvl) {
  1164. case PHY_PS5169_SWING0:
  1165. return "secdp,redrv-hbr2-eq1-0";
  1166. case PHY_PS5169_SWING1:
  1167. return "secdp,redrv-hbr2-eq1-1";
  1168. case PHY_PS5169_SWING2:
  1169. return "secdp,redrv-hbr2-eq1-2";
  1170. case PHY_PS5169_SWING3:
  1171. return "secdp,redrv-hbr2-eq1-3";
  1172. default:
  1173. return "secdp,redrv-hbr2-eq1-unknown";
  1174. }
  1175. }
  1176. static int _secdp_parse_ps5169_hbr2(struct dp_parser *parser)
  1177. {
  1178. struct device_node *of_node = parser->pdev->dev.of_node;
  1179. int len = 0, i = 0, j = 0;
  1180. const char *data;
  1181. DP_ENTER("\n");
  1182. for (i = 0; i < MAX_PS5169_SWING_LEVELS; i++) {
  1183. const char *property = secdp_get_ps5169_hbr2_eq0(i);
  1184. data = of_get_property(of_node, property, &len);
  1185. if (!data || len != 4) {
  1186. DP_ERR("Unable to read %s, len:%d\n", property, len);
  1187. goto error;
  1188. }
  1189. for (j = 0; j < MAX_PS5169_EMP_LEVELS; j++)
  1190. parser->ps5169_hbr2_eq0[i][j] = data[j];
  1191. }
  1192. for (i = 0; i < MAX_PS5169_SWING_LEVELS; i++) {
  1193. const char *property = secdp_get_ps5169_hbr2_eq1(i);
  1194. data = of_get_property(of_node, property, &len);
  1195. if (!data || len != 4) {
  1196. DP_ERR("Unable to read %s, len:%d\n", property, len);
  1197. goto error;
  1198. }
  1199. for (j = 0; j < MAX_PS5169_EMP_LEVELS; j++)
  1200. parser->ps5169_hbr2_eq1[i][j] = data[j];
  1201. }
  1202. return 0;
  1203. error:
  1204. return -EINVAL;
  1205. }
  1206. static const char *secdp_get_ps5169_hbr3_eq0(u32 lvl)
  1207. {
  1208. switch (lvl) {
  1209. case PHY_PS5169_EMP0:
  1210. return "secdp,redrv-hbr3-eq0-0";
  1211. case PHY_PS5169_EMP1:
  1212. return "secdp,redrv-hbr3-eq0-1";
  1213. case PHY_PS5169_EMP2:
  1214. return "secdp,redrv-hbr3-eq0-2";
  1215. case PHY_PS5169_EMP3:
  1216. return "secdp,redrv-hbr3-eq0-3";
  1217. default:
  1218. return "secdp,redrv-hbr3-eq0-unknown";
  1219. }
  1220. }
  1221. static const char *secdp_get_ps5169_hbr3_eq1(u32 lvl)
  1222. {
  1223. switch (lvl) {
  1224. case PHY_PS5169_SWING0:
  1225. return "secdp,redrv-hbr3-eq1-0";
  1226. case PHY_PS5169_SWING1:
  1227. return "secdp,redrv-hbr3-eq1-1";
  1228. case PHY_PS5169_SWING2:
  1229. return "secdp,redrv-hbr3-eq1-2";
  1230. case PHY_PS5169_SWING3:
  1231. return "secdp,redrv-hbr3-eq1-3";
  1232. default:
  1233. return "secdp,redrv-hbr3-eq1-unknown";
  1234. }
  1235. }
  1236. static int _secdp_parse_ps5169_hbr3(struct dp_parser *parser)
  1237. {
  1238. struct device_node *of_node = parser->pdev->dev.of_node;
  1239. int len = 0, i = 0, j = 0;
  1240. const char *data;
  1241. DP_ENTER("\n");
  1242. for (i = 0; i < MAX_PS5169_SWING_LEVELS; i++) {
  1243. const char *property = secdp_get_ps5169_hbr3_eq0(i);
  1244. data = of_get_property(of_node, property, &len);
  1245. if (!data || len != 4) {
  1246. DP_ERR("Unable to read %s, len:%d\n", property, len);
  1247. goto error;
  1248. }
  1249. for (j = 0; j < MAX_PS5169_EMP_LEVELS; j++)
  1250. parser->ps5169_hbr3_eq0[i][j] = data[j];
  1251. }
  1252. for (i = 0; i < MAX_PS5169_SWING_LEVELS; i++) {
  1253. const char *property = secdp_get_ps5169_hbr3_eq1(i);
  1254. data = of_get_property(of_node, property, &len);
  1255. if (!data || len != 4) {
  1256. DP_ERR("Unable to read %s, len:%d\n", property, len);
  1257. goto error;
  1258. }
  1259. for (j = 0; j < MAX_PS5169_EMP_LEVELS; j++)
  1260. parser->ps5169_hbr3_eq1[i][j] = data[j];
  1261. }
  1262. return 0;
  1263. error:
  1264. return -EINVAL;
  1265. }
  1266. static void secdp_parse_ps5169_param(struct dp_parser *parser)
  1267. {
  1268. _secdp_parse_ps5169_rbr(parser);
  1269. _secdp_parse_ps5169_hbr(parser);
  1270. _secdp_parse_ps5169_hbr2(parser);
  1271. _secdp_parse_ps5169_hbr3(parser);
  1272. }
  1273. /*********************************************
  1274. *** default PS5169 DP EQ0/EQ1 params ***
  1275. *********************************************/
  1276. #define EQ0 0x20
  1277. #define EQ1 0x06
  1278. static u8 const ps5169_rbr_eq0[MAX_PS5169_SWING_LEVELS][MAX_PS5169_EMP_LEVELS] = {
  1279. {EQ0, EQ0, EQ0, EQ0},
  1280. {EQ0, EQ0, EQ0, EQ0},
  1281. {EQ0, EQ0, EQ0, EQ0},
  1282. {EQ0, EQ0, EQ0, EQ0}
  1283. };
  1284. /* voltage swing, 0.2v and 1.0v are not support */
  1285. static u8 const ps5169_rbr_eq1[MAX_PS5169_SWING_LEVELS][MAX_PS5169_EMP_LEVELS] = {
  1286. {EQ1, EQ1, EQ1, EQ1},
  1287. {EQ1, EQ1, EQ1, EQ1},
  1288. {EQ1, EQ1, EQ1, EQ1},
  1289. {EQ1, EQ1, EQ1, EQ1}
  1290. };
  1291. static u8 const ps5169_hbr_eq0[MAX_PS5169_SWING_LEVELS][MAX_PS5169_EMP_LEVELS] = {
  1292. {EQ0, EQ0, EQ0, EQ0},
  1293. {EQ0, EQ0, EQ0, EQ0},
  1294. {EQ0, EQ0, EQ0, EQ0},
  1295. {EQ0, EQ0, EQ0, EQ0}
  1296. };
  1297. static u8 const ps5169_hbr_eq1[MAX_PS5169_SWING_LEVELS][MAX_PS5169_EMP_LEVELS] = {
  1298. {EQ1, EQ1, EQ1, EQ1},
  1299. {EQ1, EQ1, EQ1, EQ1},
  1300. {EQ1, EQ1, EQ1, EQ1},
  1301. {EQ1, EQ1, EQ1, EQ1}
  1302. };
  1303. static u8 const ps5169_hbr2_eq0[MAX_PS5169_SWING_LEVELS][MAX_PS5169_EMP_LEVELS] = {
  1304. {EQ0, EQ0, EQ0, EQ0},
  1305. {EQ0, EQ0, EQ0, EQ0},
  1306. {EQ0, EQ0, EQ0, EQ0},
  1307. {EQ0, EQ0, EQ0, EQ0}
  1308. };
  1309. static u8 const ps5169_hbr2_eq1[MAX_PS5169_SWING_LEVELS][MAX_PS5169_EMP_LEVELS] = {
  1310. {EQ1, EQ1, EQ1, EQ1},
  1311. {EQ1, EQ1, EQ1, EQ1},
  1312. {EQ1, EQ1, EQ1, EQ1},
  1313. {EQ1, EQ1, EQ1, EQ1}
  1314. };
  1315. static u8 const ps5169_hbr3_eq0[MAX_PS5169_SWING_LEVELS][MAX_PS5169_EMP_LEVELS] = {
  1316. {EQ0, EQ0, EQ0, EQ0},
  1317. {EQ0, EQ0, EQ0, EQ0},
  1318. {EQ0, EQ0, EQ0, EQ0},
  1319. {EQ0, EQ0, EQ0, EQ0}
  1320. };
  1321. static u8 const ps5169_hbr3_eq1[MAX_PS5169_SWING_LEVELS][MAX_PS5169_EMP_LEVELS] = {
  1322. {EQ1, EQ1, EQ1, EQ1},
  1323. {EQ1, EQ1, EQ1, EQ1},
  1324. {EQ1, EQ1, EQ1, EQ1},
  1325. {EQ1, EQ1, EQ1, EQ1}
  1326. };
  1327. static void secdp_set_default_ps5169_param(struct dp_parser *parser,
  1328. enum secdp_ps5169_eq_t eq, enum secdp_ps5169_link_rate_t link_rate)
  1329. {
  1330. int i, j;
  1331. for (i = 0; i < MAX_PS5169_SWING_LEVELS; i++) {
  1332. for (j = 0; j < MAX_PS5169_EMP_LEVELS; j++) {
  1333. if (eq == DP_PS5169_EQ_MAX || eq == DP_PS5169_EQ0) {
  1334. if (link_rate == DP_PS5169_RATE_MAX ||
  1335. link_rate == DP_PS5169_RATE_RBR) {
  1336. parser->ps5169_rbr_eq0[i][j] = ps5169_rbr_eq0[i][j];
  1337. }
  1338. if (link_rate == DP_PS5169_RATE_MAX ||
  1339. link_rate == DP_PS5169_RATE_HBR) {
  1340. parser->ps5169_hbr_eq0[i][j] = ps5169_hbr_eq0[i][j];
  1341. }
  1342. if (link_rate == DP_PS5169_RATE_MAX ||
  1343. link_rate == DP_PS5169_RATE_HBR2) {
  1344. parser->ps5169_hbr2_eq0[i][j] = ps5169_hbr2_eq0[i][j];
  1345. }
  1346. if (link_rate == DP_PS5169_RATE_MAX ||
  1347. link_rate == DP_PS5169_RATE_HBR3) {
  1348. parser->ps5169_hbr3_eq0[i][j] = ps5169_hbr3_eq0[i][j];
  1349. }
  1350. }
  1351. if (eq == DP_PS5169_EQ_MAX || eq == DP_PS5169_EQ1) {
  1352. if (link_rate == DP_PS5169_RATE_MAX ||
  1353. link_rate == DP_PS5169_RATE_RBR) {
  1354. parser->ps5169_rbr_eq1[i][j] = ps5169_rbr_eq1[i][j];
  1355. }
  1356. if (link_rate == DP_PS5169_RATE_MAX ||
  1357. link_rate == DP_PS5169_RATE_HBR) {
  1358. parser->ps5169_hbr_eq1[i][j] = ps5169_hbr_eq1[i][j];
  1359. }
  1360. if (link_rate == DP_PS5169_RATE_MAX ||
  1361. link_rate == DP_PS5169_RATE_HBR2) {
  1362. parser->ps5169_hbr2_eq1[i][j] = ps5169_hbr2_eq1[i][j];
  1363. }
  1364. if (link_rate == DP_PS5169_RATE_MAX ||
  1365. link_rate == DP_PS5169_RATE_HBR3) {
  1366. parser->ps5169_hbr3_eq1[i][j] = ps5169_hbr3_eq1[i][j];
  1367. }
  1368. }
  1369. }
  1370. }
  1371. }
  1372. #if defined(CONFIG_SECDP_DBG)
  1373. static u8 *_secdp_get_ps5169_param(struct dp_parser *parser, enum secdp_ps5169_eq_t eq,
  1374. enum secdp_ps5169_link_rate_t link_rate, int idx)
  1375. {
  1376. u8 *val = NULL;
  1377. switch (eq) {
  1378. case DP_PS5169_EQ0:
  1379. switch (link_rate) {
  1380. case DP_PS5169_RATE_RBR:
  1381. val = parser->ps5169_rbr_eq0[idx];
  1382. break;
  1383. case DP_PS5169_RATE_HBR:
  1384. val = parser->ps5169_hbr_eq0[idx];
  1385. break;
  1386. case DP_PS5169_RATE_HBR2:
  1387. val = parser->ps5169_hbr2_eq0[idx];
  1388. break;
  1389. case DP_PS5169_RATE_HBR3:
  1390. val = parser->ps5169_hbr3_eq0[idx];
  1391. break;
  1392. default:
  1393. DP_ERR("unknown rate: %d\n", link_rate);
  1394. break;
  1395. }
  1396. break;
  1397. case DP_PS5169_EQ1:
  1398. switch (link_rate) {
  1399. case DP_PS5169_RATE_RBR:
  1400. val = parser->ps5169_rbr_eq1[idx];
  1401. break;
  1402. case DP_PS5169_RATE_HBR:
  1403. val = parser->ps5169_hbr_eq1[idx];
  1404. break;
  1405. case DP_PS5169_RATE_HBR2:
  1406. val = parser->ps5169_hbr2_eq1[idx];
  1407. break;
  1408. case DP_PS5169_RATE_HBR3:
  1409. val = parser->ps5169_hbr3_eq1[idx];
  1410. break;
  1411. default:
  1412. DP_ERR("unknown rate: %d\n", link_rate);
  1413. break;
  1414. }
  1415. break;
  1416. default:
  1417. DP_ERR("unknown eq:%d\n", eq);
  1418. break;
  1419. }
  1420. return val;
  1421. }
  1422. int secdp_parse_ps5169_show(struct dp_parser *parser, enum secdp_ps5169_eq_t eq,
  1423. enum secdp_ps5169_link_rate_t link_rate, char *buf)
  1424. {
  1425. u8 *val[MAX_PS5169_SWING_LEVELS];
  1426. int i, rc = 0;
  1427. rc += scnprintf(buf + rc, PAGE_SIZE - rc, "\n%s | %s\n=====\n",
  1428. secdp_ps5169_eq_to_string(eq),
  1429. secdp_ps5169_rate_to_string(link_rate));
  1430. for (i = 0; i < MAX_PS5169_SWING_LEVELS; i++) {
  1431. val[i] = _secdp_get_ps5169_param(parser, eq, link_rate, i);
  1432. if (!val[i])
  1433. break;
  1434. rc += scnprintf(buf + rc, PAGE_SIZE - rc,
  1435. "%02x,%02x,%02x,%02x",
  1436. val[i][0], val[i][1], val[i][2], val[i][3]);
  1437. if (i < MAX_PS5169_SWING_LEVELS - 1)
  1438. rc += scnprintf(buf + rc, PAGE_SIZE - rc, ",\n");
  1439. else
  1440. rc += scnprintf(buf + rc, PAGE_SIZE - rc, "\n");
  1441. }
  1442. return rc;
  1443. }
  1444. int secdp_parse_ps5169_store(struct dp_parser *parser,
  1445. enum secdp_ps5169_eq_t eq, enum secdp_ps5169_link_rate_t link_rate, char *buf)
  1446. {
  1447. u8 *val[MAX_PS5169_SWING_LEVELS];
  1448. char *tok;
  1449. u32 value;
  1450. int i, j, rc = 0;
  1451. if (!strncmp(buf, "reset_all", strlen("reset_all"))) {
  1452. DP_DEBUG("[all] reset!\n");
  1453. secdp_set_default_ps5169_param(parser, DP_PS5169_EQ_MAX, DP_PS5169_RATE_MAX);
  1454. goto end;
  1455. }
  1456. if (!strncmp(buf, "reset", strlen("reset"))) {
  1457. DP_DEBUG("[%s,%s] reset!\n", secdp_ps5169_eq_to_string(eq),
  1458. secdp_ps5169_rate_to_string(link_rate));
  1459. secdp_set_default_ps5169_param(parser, eq, link_rate);
  1460. goto end;
  1461. }
  1462. DP_DEBUG("[%s,%s] set new params!\n", secdp_ps5169_eq_to_string(eq),
  1463. secdp_ps5169_rate_to_string(link_rate));
  1464. for (i = 0; i < MAX_PS5169_SWING_LEVELS; i++) {
  1465. val[i] = _secdp_get_ps5169_param(parser, eq, link_rate, i);
  1466. if (!val[i]) {
  1467. rc = -EINVAL;
  1468. break;
  1469. }
  1470. for (j = 0; j < MAX_PS5169_EMP_LEVELS; j++) {
  1471. tok = strsep(&buf, ",");
  1472. if (!tok)
  1473. continue;
  1474. rc = kstrtouint(tok, 16, &value);
  1475. if (rc) {
  1476. DP_ERR("error: %s rc:%d\n", tok, rc);
  1477. goto end;
  1478. }
  1479. val[i][j] = value;
  1480. }
  1481. }
  1482. end:
  1483. return rc;
  1484. }
  1485. int secdp_show_ps5169_param(struct dp_parser *parser, char *buf)
  1486. {
  1487. int eq, rc = 0;
  1488. for (eq = 0; eq < DP_PS5169_EQ_MAX; eq++) {
  1489. rc += secdp_parse_ps5169_show(parser, eq, DP_PS5169_RATE_RBR, buf + rc);
  1490. rc += secdp_parse_ps5169_show(parser, eq, DP_PS5169_RATE_HBR, buf + rc);
  1491. rc += secdp_parse_ps5169_show(parser, eq, DP_PS5169_RATE_HBR2, buf + rc);
  1492. rc += secdp_parse_ps5169_show(parser, eq, DP_PS5169_RATE_HBR3, buf + rc);
  1493. }
  1494. return rc;
  1495. }
  1496. #endif/*CONFIG_SECDP_DBG*/
  1497. #endif/*CONFIG_COMBO_REDRIVER_PS5169*/
  1498. static int dp_parser_parse(struct dp_parser *parser)
  1499. {
  1500. int rc = 0;
  1501. if (!parser) {
  1502. DP_ERR("invalid input\n");
  1503. rc = -EINVAL;
  1504. goto err;
  1505. }
  1506. rc = dp_parser_reg(parser);
  1507. if (rc)
  1508. goto err;
  1509. rc = dp_parser_aux(parser);
  1510. if (rc)
  1511. goto err;
  1512. rc = dp_parser_misc(parser);
  1513. if (rc)
  1514. goto err;
  1515. rc = dp_parser_clock(parser);
  1516. if (rc)
  1517. goto err;
  1518. rc = dp_parser_regulator(parser);
  1519. if (rc)
  1520. goto err;
  1521. rc = dp_parser_gpio(parser);
  1522. if (rc)
  1523. goto err;
  1524. rc = dp_parser_catalog(parser);
  1525. if (rc)
  1526. goto err;
  1527. rc = dp_parser_pinctrl(parser);
  1528. if (rc)
  1529. goto err;
  1530. rc = dp_parser_msm_hdcp_dev(parser);
  1531. if (rc)
  1532. goto err;
  1533. rc = dp_parser_mst(parser);
  1534. if (rc)
  1535. goto err;
  1536. dp_parser_dsc(parser);
  1537. dp_parser_fec(parser);
  1538. dp_parser_widebus(parser);
  1539. dp_parser_qos(parser);
  1540. dp_parser_link_training_params(parser);
  1541. #if defined(CONFIG_SECDP)
  1542. secdp_parse_misc(parser);
  1543. #endif
  1544. err:
  1545. return rc;
  1546. }
  1547. static struct dp_io_data *dp_parser_get_io(struct dp_parser *dp_parser,
  1548. char *name)
  1549. {
  1550. int i = 0;
  1551. struct dp_io *io;
  1552. if (!dp_parser) {
  1553. DP_ERR("invalid input\n");
  1554. goto err;
  1555. }
  1556. io = &dp_parser->io;
  1557. for (i = 0; i < io->len; i++) {
  1558. struct dp_io_data *data = &io->data[i];
  1559. if (!strcmp(data->name, name))
  1560. return data;
  1561. }
  1562. err:
  1563. return NULL;
  1564. }
  1565. static void dp_parser_get_io_buf(struct dp_parser *dp_parser, char *name)
  1566. {
  1567. int i = 0;
  1568. struct dp_io *io;
  1569. if (!dp_parser) {
  1570. DP_ERR("invalid input\n");
  1571. return;
  1572. }
  1573. io = &dp_parser->io;
  1574. for (i = 0; i < io->len; i++) {
  1575. struct dp_io_data *data = &io->data[i];
  1576. if (!strcmp(data->name, name)) {
  1577. if (!data->buf)
  1578. data->buf = devm_kzalloc(&dp_parser->pdev->dev,
  1579. data->io.len, GFP_KERNEL);
  1580. }
  1581. }
  1582. }
  1583. static void dp_parser_clear_io_buf(struct dp_parser *dp_parser)
  1584. {
  1585. int i = 0;
  1586. struct dp_io *io;
  1587. if (!dp_parser) {
  1588. DP_ERR("invalid input\n");
  1589. return;
  1590. }
  1591. io = &dp_parser->io;
  1592. for (i = 0; i < io->len; i++) {
  1593. struct dp_io_data *data = &io->data[i];
  1594. if (data->buf)
  1595. devm_kfree(&dp_parser->pdev->dev, data->buf);
  1596. data->buf = NULL;
  1597. }
  1598. }
  1599. struct dp_parser *dp_parser_get(struct platform_device *pdev)
  1600. {
  1601. struct dp_parser *parser;
  1602. parser = devm_kzalloc(&pdev->dev, sizeof(*parser), GFP_KERNEL);
  1603. if (!parser)
  1604. return ERR_PTR(-ENOMEM);
  1605. parser->parse = dp_parser_parse;
  1606. parser->get_io = dp_parser_get_io;
  1607. parser->get_io_buf = dp_parser_get_io_buf;
  1608. parser->clear_io_buf = dp_parser_clear_io_buf;
  1609. parser->pdev = pdev;
  1610. #if defined(CONFIG_SECDP)
  1611. #if IS_ENABLED(CONFIG_COMBO_REDRIVER_PS5169)
  1612. secdp_set_default_ps5169_param(parser, DP_PS5169_EQ_MAX, DP_PS5169_RATE_MAX);
  1613. #endif
  1614. #endif
  1615. return parser;
  1616. }
  1617. void dp_parser_put(struct dp_parser *parser)
  1618. {
  1619. int i = 0;
  1620. struct dss_module_power *power = NULL;
  1621. if (!parser) {
  1622. DP_ERR("invalid parser module\n");
  1623. return;
  1624. }
  1625. power = parser->mp;
  1626. for (i = 0; i < DP_MAX_PM; i++) {
  1627. dp_parser_put_clk_data(&parser->pdev->dev, &power[i]);
  1628. dp_parser_put_vreg_data(&parser->pdev->dev, &power[i]);
  1629. dp_parser_put_gpio_data(&parser->pdev->dev, &power[i]);
  1630. }
  1631. dp_parser_clear_link_training_params(parser);
  1632. dp_parser_clear_io_buf(parser);
  1633. devm_kfree(&parser->pdev->dev, parser->io.data);
  1634. devm_kfree(&parser->pdev->dev, parser);
  1635. }