dpi.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2009 Nokia Corporation
  4. * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
  5. *
  6. * Some code and ideas taken from drivers/video/omap/ driver
  7. * by Imre Deak.
  8. */
  9. #define DSS_SUBSYS_NAME "DPI"
  10. #include <linux/clk.h>
  11. #include <linux/delay.h>
  12. #include <linux/err.h>
  13. #include <linux/errno.h>
  14. #include <linux/export.h>
  15. #include <linux/kernel.h>
  16. #include <linux/of.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/regulator/consumer.h>
  19. #include <linux/string.h>
  20. #include <linux/sys_soc.h>
  21. #include <drm/drm_bridge.h>
  22. #include "dss.h"
  23. #include "omapdss.h"
  24. struct dpi_data {
  25. struct platform_device *pdev;
  26. enum dss_model dss_model;
  27. struct dss_device *dss;
  28. unsigned int id;
  29. struct regulator *vdds_dsi_reg;
  30. enum dss_clk_source clk_src;
  31. struct dss_pll *pll;
  32. struct dss_lcd_mgr_config mgr_config;
  33. unsigned long pixelclock;
  34. int data_lines;
  35. struct omap_dss_device output;
  36. struct drm_bridge bridge;
  37. };
  38. #define drm_bridge_to_dpi(bridge) container_of(bridge, struct dpi_data, bridge)
  39. /* -----------------------------------------------------------------------------
  40. * Clock Handling and PLL
  41. */
  42. static enum dss_clk_source dpi_get_clk_src_dra7xx(struct dpi_data *dpi,
  43. enum omap_channel channel)
  44. {
  45. /*
  46. * Possible clock sources:
  47. * LCD1: FCK/PLL1_1/HDMI_PLL
  48. * LCD2: FCK/PLL1_3/HDMI_PLL (DRA74x: PLL2_3)
  49. * LCD3: FCK/PLL1_3/HDMI_PLL (DRA74x: PLL2_1)
  50. */
  51. switch (channel) {
  52. case OMAP_DSS_CHANNEL_LCD:
  53. {
  54. if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_1))
  55. return DSS_CLK_SRC_PLL1_1;
  56. break;
  57. }
  58. case OMAP_DSS_CHANNEL_LCD2:
  59. {
  60. if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_3))
  61. return DSS_CLK_SRC_PLL1_3;
  62. if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL2_3))
  63. return DSS_CLK_SRC_PLL2_3;
  64. break;
  65. }
  66. case OMAP_DSS_CHANNEL_LCD3:
  67. {
  68. if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL2_1))
  69. return DSS_CLK_SRC_PLL2_1;
  70. if (dss_pll_find_by_src(dpi->dss, DSS_CLK_SRC_PLL1_3))
  71. return DSS_CLK_SRC_PLL1_3;
  72. break;
  73. }
  74. default:
  75. break;
  76. }
  77. return DSS_CLK_SRC_FCK;
  78. }
  79. static enum dss_clk_source dpi_get_clk_src(struct dpi_data *dpi)
  80. {
  81. enum omap_channel channel = dpi->output.dispc_channel;
  82. /*
  83. * XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL
  84. * would also be used for DISPC fclk. Meaning, when the DPI output is
  85. * disabled, DISPC clock will be disabled, and TV out will stop.
  86. */
  87. switch (dpi->dss_model) {
  88. case DSS_MODEL_OMAP2:
  89. case DSS_MODEL_OMAP3:
  90. return DSS_CLK_SRC_FCK;
  91. case DSS_MODEL_OMAP4:
  92. switch (channel) {
  93. case OMAP_DSS_CHANNEL_LCD:
  94. return DSS_CLK_SRC_PLL1_1;
  95. case OMAP_DSS_CHANNEL_LCD2:
  96. return DSS_CLK_SRC_PLL2_1;
  97. default:
  98. return DSS_CLK_SRC_FCK;
  99. }
  100. case DSS_MODEL_OMAP5:
  101. switch (channel) {
  102. case OMAP_DSS_CHANNEL_LCD:
  103. return DSS_CLK_SRC_PLL1_1;
  104. case OMAP_DSS_CHANNEL_LCD3:
  105. return DSS_CLK_SRC_PLL2_1;
  106. case OMAP_DSS_CHANNEL_LCD2:
  107. default:
  108. return DSS_CLK_SRC_FCK;
  109. }
  110. case DSS_MODEL_DRA7:
  111. return dpi_get_clk_src_dra7xx(dpi, channel);
  112. default:
  113. return DSS_CLK_SRC_FCK;
  114. }
  115. }
  116. struct dpi_clk_calc_ctx {
  117. struct dpi_data *dpi;
  118. unsigned int clkout_idx;
  119. /* inputs */
  120. unsigned long pck_min, pck_max;
  121. /* outputs */
  122. struct dss_pll_clock_info pll_cinfo;
  123. unsigned long fck;
  124. struct dispc_clock_info dispc_cinfo;
  125. };
  126. static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
  127. unsigned long pck, void *data)
  128. {
  129. struct dpi_clk_calc_ctx *ctx = data;
  130. /*
  131. * Odd dividers give us uneven duty cycle, causing problem when level
  132. * shifted. So skip all odd dividers when the pixel clock is on the
  133. * higher side.
  134. */
  135. if (ctx->pck_min >= 100000000) {
  136. if (lckd > 1 && lckd % 2 != 0)
  137. return false;
  138. if (pckd > 1 && pckd % 2 != 0)
  139. return false;
  140. }
  141. ctx->dispc_cinfo.lck_div = lckd;
  142. ctx->dispc_cinfo.pck_div = pckd;
  143. ctx->dispc_cinfo.lck = lck;
  144. ctx->dispc_cinfo.pck = pck;
  145. return true;
  146. }
  147. static bool dpi_calc_hsdiv_cb(int m_dispc, unsigned long dispc,
  148. void *data)
  149. {
  150. struct dpi_clk_calc_ctx *ctx = data;
  151. ctx->pll_cinfo.mX[ctx->clkout_idx] = m_dispc;
  152. ctx->pll_cinfo.clkout[ctx->clkout_idx] = dispc;
  153. return dispc_div_calc(ctx->dpi->dss->dispc, dispc,
  154. ctx->pck_min, ctx->pck_max,
  155. dpi_calc_dispc_cb, ctx);
  156. }
  157. static bool dpi_calc_pll_cb(int n, int m, unsigned long fint,
  158. unsigned long clkdco,
  159. void *data)
  160. {
  161. struct dpi_clk_calc_ctx *ctx = data;
  162. ctx->pll_cinfo.n = n;
  163. ctx->pll_cinfo.m = m;
  164. ctx->pll_cinfo.fint = fint;
  165. ctx->pll_cinfo.clkdco = clkdco;
  166. return dss_pll_hsdiv_calc_a(ctx->dpi->pll, clkdco,
  167. ctx->pck_min, dss_get_max_fck_rate(ctx->dpi->dss),
  168. dpi_calc_hsdiv_cb, ctx);
  169. }
  170. static bool dpi_calc_dss_cb(unsigned long fck, void *data)
  171. {
  172. struct dpi_clk_calc_ctx *ctx = data;
  173. ctx->fck = fck;
  174. return dispc_div_calc(ctx->dpi->dss->dispc, fck,
  175. ctx->pck_min, ctx->pck_max,
  176. dpi_calc_dispc_cb, ctx);
  177. }
  178. static bool dpi_pll_clk_calc(struct dpi_data *dpi, unsigned long pck,
  179. struct dpi_clk_calc_ctx *ctx)
  180. {
  181. unsigned long clkin;
  182. memset(ctx, 0, sizeof(*ctx));
  183. ctx->dpi = dpi;
  184. ctx->clkout_idx = dss_pll_get_clkout_idx_for_src(dpi->clk_src);
  185. clkin = clk_get_rate(dpi->pll->clkin);
  186. if (dpi->pll->hw->type == DSS_PLL_TYPE_A) {
  187. unsigned long pll_min, pll_max;
  188. ctx->pck_min = pck - 1000;
  189. ctx->pck_max = pck + 1000;
  190. pll_min = 0;
  191. pll_max = 0;
  192. return dss_pll_calc_a(ctx->dpi->pll, clkin,
  193. pll_min, pll_max,
  194. dpi_calc_pll_cb, ctx);
  195. } else { /* DSS_PLL_TYPE_B */
  196. dss_pll_calc_b(dpi->pll, clkin, pck, &ctx->pll_cinfo);
  197. ctx->dispc_cinfo.lck_div = 1;
  198. ctx->dispc_cinfo.pck_div = 1;
  199. ctx->dispc_cinfo.lck = ctx->pll_cinfo.clkout[0];
  200. ctx->dispc_cinfo.pck = ctx->dispc_cinfo.lck;
  201. return true;
  202. }
  203. }
  204. static bool dpi_dss_clk_calc(struct dpi_data *dpi, unsigned long pck,
  205. struct dpi_clk_calc_ctx *ctx)
  206. {
  207. int i;
  208. /*
  209. * DSS fck gives us very few possibilities, so finding a good pixel
  210. * clock may not be possible. We try multiple times to find the clock,
  211. * each time widening the pixel clock range we look for, up to
  212. * +/- ~15MHz.
  213. */
  214. for (i = 0; i < 25; ++i) {
  215. bool ok;
  216. memset(ctx, 0, sizeof(*ctx));
  217. ctx->dpi = dpi;
  218. if (pck > 1000 * i * i * i)
  219. ctx->pck_min = max(pck - 1000 * i * i * i, 0lu);
  220. else
  221. ctx->pck_min = 0;
  222. ctx->pck_max = pck + 1000 * i * i * i;
  223. ok = dss_div_calc(dpi->dss, pck, ctx->pck_min,
  224. dpi_calc_dss_cb, ctx);
  225. if (ok)
  226. return ok;
  227. }
  228. return false;
  229. }
  230. static int dpi_set_pll_clk(struct dpi_data *dpi, unsigned long pck_req)
  231. {
  232. struct dpi_clk_calc_ctx ctx;
  233. int r;
  234. bool ok;
  235. ok = dpi_pll_clk_calc(dpi, pck_req, &ctx);
  236. if (!ok)
  237. return -EINVAL;
  238. r = dss_pll_set_config(dpi->pll, &ctx.pll_cinfo);
  239. if (r)
  240. return r;
  241. dss_select_lcd_clk_source(dpi->dss, dpi->output.dispc_channel,
  242. dpi->clk_src);
  243. dpi->mgr_config.clock_info = ctx.dispc_cinfo;
  244. return 0;
  245. }
  246. static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req)
  247. {
  248. struct dpi_clk_calc_ctx ctx;
  249. int r;
  250. bool ok;
  251. ok = dpi_dss_clk_calc(dpi, pck_req, &ctx);
  252. if (!ok)
  253. return -EINVAL;
  254. r = dss_set_fck_rate(dpi->dss, ctx.fck);
  255. if (r)
  256. return r;
  257. dpi->mgr_config.clock_info = ctx.dispc_cinfo;
  258. return 0;
  259. }
  260. static int dpi_set_mode(struct dpi_data *dpi)
  261. {
  262. int r;
  263. if (dpi->pll)
  264. r = dpi_set_pll_clk(dpi, dpi->pixelclock);
  265. else
  266. r = dpi_set_dispc_clk(dpi, dpi->pixelclock);
  267. return r;
  268. }
  269. static void dpi_config_lcd_manager(struct dpi_data *dpi)
  270. {
  271. dpi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
  272. dpi->mgr_config.stallmode = false;
  273. dpi->mgr_config.fifohandcheck = false;
  274. dpi->mgr_config.video_port_width = dpi->data_lines;
  275. dpi->mgr_config.lcden_sig_polarity = 0;
  276. dss_mgr_set_lcd_config(&dpi->output, &dpi->mgr_config);
  277. }
  278. static int dpi_clock_update(struct dpi_data *dpi, unsigned long *clock)
  279. {
  280. int lck_div, pck_div;
  281. unsigned long fck;
  282. struct dpi_clk_calc_ctx ctx;
  283. if (dpi->pll) {
  284. if (!dpi_pll_clk_calc(dpi, *clock, &ctx))
  285. return -EINVAL;
  286. fck = ctx.pll_cinfo.clkout[ctx.clkout_idx];
  287. } else {
  288. if (!dpi_dss_clk_calc(dpi, *clock, &ctx))
  289. return -EINVAL;
  290. fck = ctx.fck;
  291. }
  292. lck_div = ctx.dispc_cinfo.lck_div;
  293. pck_div = ctx.dispc_cinfo.pck_div;
  294. *clock = fck / lck_div / pck_div;
  295. return 0;
  296. }
  297. static int dpi_verify_pll(struct dss_pll *pll)
  298. {
  299. int r;
  300. /* do initial setup with the PLL to see if it is operational */
  301. r = dss_pll_enable(pll);
  302. if (r)
  303. return r;
  304. dss_pll_disable(pll);
  305. return 0;
  306. }
  307. static void dpi_init_pll(struct dpi_data *dpi)
  308. {
  309. struct dss_pll *pll;
  310. if (dpi->pll)
  311. return;
  312. dpi->clk_src = dpi_get_clk_src(dpi);
  313. pll = dss_pll_find_by_src(dpi->dss, dpi->clk_src);
  314. if (!pll)
  315. return;
  316. if (dpi_verify_pll(pll)) {
  317. DSSWARN("PLL not operational\n");
  318. return;
  319. }
  320. dpi->pll = pll;
  321. }
  322. /* -----------------------------------------------------------------------------
  323. * DRM Bridge Operations
  324. */
  325. static int dpi_bridge_attach(struct drm_bridge *bridge,
  326. enum drm_bridge_attach_flags flags)
  327. {
  328. struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
  329. if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
  330. return -EINVAL;
  331. dpi_init_pll(dpi);
  332. return drm_bridge_attach(bridge->encoder, dpi->output.next_bridge,
  333. bridge, flags);
  334. }
  335. static enum drm_mode_status
  336. dpi_bridge_mode_valid(struct drm_bridge *bridge,
  337. const struct drm_display_info *info,
  338. const struct drm_display_mode *mode)
  339. {
  340. struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
  341. unsigned long clock = mode->clock * 1000;
  342. int ret;
  343. if (mode->hdisplay % 8 != 0)
  344. return MODE_BAD_WIDTH;
  345. if (mode->clock == 0)
  346. return MODE_NOCLOCK;
  347. ret = dpi_clock_update(dpi, &clock);
  348. if (ret < 0)
  349. return MODE_CLOCK_RANGE;
  350. return MODE_OK;
  351. }
  352. static bool dpi_bridge_mode_fixup(struct drm_bridge *bridge,
  353. const struct drm_display_mode *mode,
  354. struct drm_display_mode *adjusted_mode)
  355. {
  356. struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
  357. unsigned long clock = mode->clock * 1000;
  358. int ret;
  359. ret = dpi_clock_update(dpi, &clock);
  360. if (ret < 0)
  361. return false;
  362. adjusted_mode->clock = clock / 1000;
  363. return true;
  364. }
  365. static void dpi_bridge_mode_set(struct drm_bridge *bridge,
  366. const struct drm_display_mode *mode,
  367. const struct drm_display_mode *adjusted_mode)
  368. {
  369. struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
  370. dpi->pixelclock = adjusted_mode->clock * 1000;
  371. }
  372. static void dpi_bridge_enable(struct drm_bridge *bridge)
  373. {
  374. struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
  375. int r;
  376. if (dpi->vdds_dsi_reg) {
  377. r = regulator_enable(dpi->vdds_dsi_reg);
  378. if (r)
  379. return;
  380. }
  381. r = dispc_runtime_get(dpi->dss->dispc);
  382. if (r)
  383. goto err_get_dispc;
  384. r = dss_dpi_select_source(dpi->dss, dpi->id, dpi->output.dispc_channel);
  385. if (r)
  386. goto err_src_sel;
  387. if (dpi->pll) {
  388. r = dss_pll_enable(dpi->pll);
  389. if (r)
  390. goto err_pll_init;
  391. }
  392. r = dpi_set_mode(dpi);
  393. if (r)
  394. goto err_set_mode;
  395. dpi_config_lcd_manager(dpi);
  396. mdelay(2);
  397. r = dss_mgr_enable(&dpi->output);
  398. if (r)
  399. goto err_mgr_enable;
  400. return;
  401. err_mgr_enable:
  402. err_set_mode:
  403. if (dpi->pll)
  404. dss_pll_disable(dpi->pll);
  405. err_pll_init:
  406. err_src_sel:
  407. dispc_runtime_put(dpi->dss->dispc);
  408. err_get_dispc:
  409. if (dpi->vdds_dsi_reg)
  410. regulator_disable(dpi->vdds_dsi_reg);
  411. }
  412. static void dpi_bridge_disable(struct drm_bridge *bridge)
  413. {
  414. struct dpi_data *dpi = drm_bridge_to_dpi(bridge);
  415. dss_mgr_disable(&dpi->output);
  416. if (dpi->pll) {
  417. dss_select_lcd_clk_source(dpi->dss, dpi->output.dispc_channel,
  418. DSS_CLK_SRC_FCK);
  419. dss_pll_disable(dpi->pll);
  420. }
  421. dispc_runtime_put(dpi->dss->dispc);
  422. if (dpi->vdds_dsi_reg)
  423. regulator_disable(dpi->vdds_dsi_reg);
  424. }
  425. static const struct drm_bridge_funcs dpi_bridge_funcs = {
  426. .attach = dpi_bridge_attach,
  427. .mode_valid = dpi_bridge_mode_valid,
  428. .mode_fixup = dpi_bridge_mode_fixup,
  429. .mode_set = dpi_bridge_mode_set,
  430. .enable = dpi_bridge_enable,
  431. .disable = dpi_bridge_disable,
  432. };
  433. static void dpi_bridge_init(struct dpi_data *dpi)
  434. {
  435. dpi->bridge.funcs = &dpi_bridge_funcs;
  436. dpi->bridge.of_node = dpi->pdev->dev.of_node;
  437. dpi->bridge.type = DRM_MODE_CONNECTOR_DPI;
  438. drm_bridge_add(&dpi->bridge);
  439. }
  440. static void dpi_bridge_cleanup(struct dpi_data *dpi)
  441. {
  442. drm_bridge_remove(&dpi->bridge);
  443. }
  444. /* -----------------------------------------------------------------------------
  445. * Initialisation and Cleanup
  446. */
  447. /*
  448. * Return a hardcoded channel for the DPI output. This should work for
  449. * current use cases, but this can be later expanded to either resolve
  450. * the channel in some more dynamic manner, or get the channel as a user
  451. * parameter.
  452. */
  453. static enum omap_channel dpi_get_channel(struct dpi_data *dpi)
  454. {
  455. switch (dpi->dss_model) {
  456. case DSS_MODEL_OMAP2:
  457. case DSS_MODEL_OMAP3:
  458. return OMAP_DSS_CHANNEL_LCD;
  459. case DSS_MODEL_DRA7:
  460. switch (dpi->id) {
  461. case 2:
  462. return OMAP_DSS_CHANNEL_LCD3;
  463. case 1:
  464. return OMAP_DSS_CHANNEL_LCD2;
  465. case 0:
  466. default:
  467. return OMAP_DSS_CHANNEL_LCD;
  468. }
  469. case DSS_MODEL_OMAP4:
  470. return OMAP_DSS_CHANNEL_LCD2;
  471. case DSS_MODEL_OMAP5:
  472. return OMAP_DSS_CHANNEL_LCD3;
  473. default:
  474. DSSWARN("unsupported DSS version\n");
  475. return OMAP_DSS_CHANNEL_LCD;
  476. }
  477. }
  478. static int dpi_init_output_port(struct dpi_data *dpi, struct device_node *port)
  479. {
  480. struct omap_dss_device *out = &dpi->output;
  481. u32 port_num = 0;
  482. int r;
  483. dpi_bridge_init(dpi);
  484. of_property_read_u32(port, "reg", &port_num);
  485. dpi->id = port_num <= 2 ? port_num : 0;
  486. switch (port_num) {
  487. case 2:
  488. out->name = "dpi.2";
  489. break;
  490. case 1:
  491. out->name = "dpi.1";
  492. break;
  493. case 0:
  494. default:
  495. out->name = "dpi.0";
  496. break;
  497. }
  498. out->dev = &dpi->pdev->dev;
  499. out->id = OMAP_DSS_OUTPUT_DPI;
  500. out->type = OMAP_DISPLAY_TYPE_DPI;
  501. out->dispc_channel = dpi_get_channel(dpi);
  502. out->of_port = port_num;
  503. r = omapdss_device_init_output(out, &dpi->bridge);
  504. if (r < 0) {
  505. dpi_bridge_cleanup(dpi);
  506. return r;
  507. }
  508. omapdss_device_register(out);
  509. return 0;
  510. }
  511. static void dpi_uninit_output_port(struct device_node *port)
  512. {
  513. struct dpi_data *dpi = port->data;
  514. struct omap_dss_device *out = &dpi->output;
  515. omapdss_device_unregister(out);
  516. omapdss_device_cleanup_output(out);
  517. dpi_bridge_cleanup(dpi);
  518. }
  519. /* -----------------------------------------------------------------------------
  520. * Initialisation and Cleanup
  521. */
  522. static const struct soc_device_attribute dpi_soc_devices[] = {
  523. { .machine = "OMAP3[456]*" },
  524. { .machine = "[AD]M37*" },
  525. { /* sentinel */ }
  526. };
  527. static int dpi_init_regulator(struct dpi_data *dpi)
  528. {
  529. struct regulator *vdds_dsi;
  530. /*
  531. * The DPI uses the DSI VDDS on OMAP34xx, OMAP35xx, OMAP36xx, AM37xx and
  532. * DM37xx only.
  533. */
  534. if (!soc_device_match(dpi_soc_devices))
  535. return 0;
  536. vdds_dsi = devm_regulator_get(&dpi->pdev->dev, "vdds_dsi");
  537. if (IS_ERR(vdds_dsi)) {
  538. if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER)
  539. DSSERR("can't get VDDS_DSI regulator\n");
  540. return PTR_ERR(vdds_dsi);
  541. }
  542. dpi->vdds_dsi_reg = vdds_dsi;
  543. return 0;
  544. }
  545. int dpi_init_port(struct dss_device *dss, struct platform_device *pdev,
  546. struct device_node *port, enum dss_model dss_model)
  547. {
  548. struct dpi_data *dpi;
  549. struct device_node *ep;
  550. u32 datalines;
  551. int r;
  552. dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL);
  553. if (!dpi)
  554. return -ENOMEM;
  555. ep = of_get_next_child(port, NULL);
  556. if (!ep)
  557. return 0;
  558. r = of_property_read_u32(ep, "data-lines", &datalines);
  559. of_node_put(ep);
  560. if (r) {
  561. DSSERR("failed to parse datalines\n");
  562. return r;
  563. }
  564. dpi->data_lines = datalines;
  565. dpi->pdev = pdev;
  566. dpi->dss_model = dss_model;
  567. dpi->dss = dss;
  568. port->data = dpi;
  569. r = dpi_init_regulator(dpi);
  570. if (r)
  571. return r;
  572. return dpi_init_output_port(dpi, port);
  573. }
  574. void dpi_uninit_port(struct device_node *port)
  575. {
  576. struct dpi_data *dpi = port->data;
  577. if (!dpi)
  578. return;
  579. dpi_uninit_output_port(port);
  580. }