dpi.c 15 KB

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