tidss_oldi.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) 2025 - Texas Instruments Incorporated
  4. *
  5. * Aradhya Bhatia <a-bhatia1@ti.com>
  6. */
  7. #include <linux/clk.h>
  8. #include <linux/of.h>
  9. #include <linux/of_graph.h>
  10. #include <linux/mfd/syscon.h>
  11. #include <linux/media-bus-format.h>
  12. #include <linux/regmap.h>
  13. #include <drm/drm_atomic_helper.h>
  14. #include <drm/drm_bridge.h>
  15. #include <drm/drm_of.h>
  16. #include "tidss_dispc.h"
  17. #include "tidss_dispc_regs.h"
  18. #include "tidss_oldi.h"
  19. struct tidss_oldi {
  20. struct tidss_device *tidss;
  21. struct device *dev;
  22. struct drm_bridge bridge;
  23. struct drm_bridge *next_bridge;
  24. enum tidss_oldi_link_type link_type;
  25. const struct oldi_bus_format *bus_format;
  26. u32 oldi_instance;
  27. int companion_instance; /* -1 when OLDI TX operates in Single-Link */
  28. u32 parent_vp;
  29. struct clk *serial;
  30. struct regmap *io_ctrl;
  31. };
  32. struct oldi_bus_format {
  33. u32 bus_fmt;
  34. u32 data_width;
  35. enum oldi_mode_reg_val oldi_mode_reg_val;
  36. u32 input_bus_fmt;
  37. };
  38. static const struct oldi_bus_format oldi_bus_formats[] = {
  39. { MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 18, SPWG_18, MEDIA_BUS_FMT_RGB666_1X18 },
  40. { MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 24, SPWG_24, MEDIA_BUS_FMT_RGB888_1X24 },
  41. { MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, 24, JEIDA_24, MEDIA_BUS_FMT_RGB888_1X24 },
  42. };
  43. #define OLDI_IDLE_CLK_HZ 25000000 /*25 MHz */
  44. static inline struct tidss_oldi *
  45. drm_bridge_to_tidss_oldi(struct drm_bridge *bridge)
  46. {
  47. return container_of(bridge, struct tidss_oldi, bridge);
  48. }
  49. static int tidss_oldi_bridge_attach(struct drm_bridge *bridge,
  50. struct drm_encoder *encoder,
  51. enum drm_bridge_attach_flags flags)
  52. {
  53. struct tidss_oldi *oldi = drm_bridge_to_tidss_oldi(bridge);
  54. if (!oldi->next_bridge) {
  55. dev_err(oldi->dev,
  56. "%s: OLDI%u Failure attach next bridge\n",
  57. __func__, oldi->oldi_instance);
  58. return -ENODEV;
  59. }
  60. if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
  61. dev_err(oldi->dev,
  62. "%s: OLDI%u DRM_BRIDGE_ATTACH_NO_CONNECTOR is mandatory.\n",
  63. __func__, oldi->oldi_instance);
  64. return -EINVAL;
  65. }
  66. return drm_bridge_attach(encoder, oldi->next_bridge, bridge, flags);
  67. }
  68. static int
  69. tidss_oldi_set_serial_clk(struct tidss_oldi *oldi, unsigned long rate)
  70. {
  71. unsigned long new_rate;
  72. int ret;
  73. ret = clk_set_rate(oldi->serial, rate);
  74. if (ret) {
  75. dev_err(oldi->dev,
  76. "OLDI%u: failed to set serial clk rate to %lu Hz\n",
  77. oldi->oldi_instance, rate);
  78. return ret;
  79. }
  80. new_rate = clk_get_rate(oldi->serial);
  81. if (dispc_pclk_diff(rate, new_rate) > 5)
  82. dev_warn(oldi->dev,
  83. "OLDI%u Clock rate %lu differs over 5%% from requested %lu\n",
  84. oldi->oldi_instance, new_rate, rate);
  85. dev_dbg(oldi->dev, "OLDI%u: new rate %lu Hz (requested %lu Hz)\n",
  86. oldi->oldi_instance, clk_get_rate(oldi->serial), rate);
  87. return 0;
  88. }
  89. static void tidss_oldi_tx_power(struct tidss_oldi *oldi, bool enable)
  90. {
  91. u32 mask;
  92. /*
  93. * The power control bits are Active Low, and remain powered off by
  94. * default. That is, the bits are set to 1. To power on the OLDI TXes,
  95. * the bits must be cleared to 0. Since there are cases where not all
  96. * OLDI TXes are being used, the power logic selectively powers them
  97. * on.
  98. * Setting the variable 'val' to particular bit masks, makes sure that
  99. * the undesired OLDI TXes remain powered off.
  100. */
  101. if (enable) {
  102. switch (oldi->link_type) {
  103. case OLDI_MODE_SINGLE_LINK:
  104. /* Power-on only the required OLDI TX's IO*/
  105. mask = OLDI_PWRDOWN_TX(oldi->oldi_instance) | OLDI_PWRDN_BG;
  106. break;
  107. case OLDI_MODE_CLONE_SINGLE_LINK:
  108. case OLDI_MODE_DUAL_LINK:
  109. /* Power-on both the OLDI TXes' IOs */
  110. mask = OLDI_PWRDOWN_TX(oldi->oldi_instance) |
  111. OLDI_PWRDOWN_TX(oldi->companion_instance) |
  112. OLDI_PWRDN_BG;
  113. break;
  114. default:
  115. /*
  116. * This code execution should never reach here as any
  117. * OLDI with an unsupported OLDI mode would never get
  118. * registered in the first place.
  119. * However, power-off the OLDI in concern just in case.
  120. */
  121. mask = OLDI_PWRDOWN_TX(oldi->oldi_instance);
  122. enable = false;
  123. break;
  124. }
  125. } else {
  126. switch (oldi->link_type) {
  127. case OLDI_MODE_CLONE_SINGLE_LINK:
  128. case OLDI_MODE_DUAL_LINK:
  129. mask = OLDI_PWRDOWN_TX(oldi->oldi_instance) |
  130. OLDI_PWRDOWN_TX(oldi->companion_instance) |
  131. OLDI_PWRDN_BG;
  132. break;
  133. case OLDI_MODE_SINGLE_LINK:
  134. default:
  135. mask = OLDI_PWRDOWN_TX(oldi->oldi_instance);
  136. break;
  137. }
  138. }
  139. regmap_update_bits(oldi->io_ctrl, OLDI_PD_CTRL, mask, enable ? 0 : mask);
  140. }
  141. static int tidss_oldi_config(struct tidss_oldi *oldi)
  142. {
  143. const struct oldi_bus_format *bus_fmt = NULL;
  144. u32 oldi_cfg = 0;
  145. int ret;
  146. bus_fmt = oldi->bus_format;
  147. /*
  148. * MASTERSLAVE and SRC bits of OLDI Config are always set to 0.
  149. */
  150. if (bus_fmt->data_width == 24)
  151. oldi_cfg |= OLDI_MSB;
  152. else if (bus_fmt->data_width != 18)
  153. dev_warn(oldi->dev,
  154. "OLDI%u: DSS port width %d not supported\n",
  155. oldi->oldi_instance, bus_fmt->data_width);
  156. oldi_cfg |= OLDI_DEPOL;
  157. oldi_cfg = (oldi_cfg & (~OLDI_MAP)) | (bus_fmt->oldi_mode_reg_val << 1);
  158. oldi_cfg |= OLDI_SOFTRST;
  159. oldi_cfg |= OLDI_ENABLE;
  160. switch (oldi->link_type) {
  161. case OLDI_MODE_SINGLE_LINK:
  162. /* All configuration is done for this mode. */
  163. break;
  164. case OLDI_MODE_CLONE_SINGLE_LINK:
  165. oldi_cfg |= OLDI_CLONE_MODE;
  166. break;
  167. case OLDI_MODE_DUAL_LINK:
  168. /* data-mapping field also indicates dual-link mode */
  169. oldi_cfg |= BIT(3);
  170. oldi_cfg |= OLDI_DUALMODESYNC;
  171. break;
  172. default:
  173. dev_err(oldi->dev, "OLDI%u: Unsupported mode.\n",
  174. oldi->oldi_instance);
  175. return -EINVAL;
  176. }
  177. ret = tidss_configure_oldi(oldi->tidss, oldi->parent_vp, oldi_cfg);
  178. if (ret == -ETIMEDOUT)
  179. dev_warn(oldi->dev, "OLDI%u: timeout waiting for OLDI reset done.\n",
  180. oldi->oldi_instance);
  181. return ret;
  182. }
  183. static void tidss_oldi_atomic_pre_enable(struct drm_bridge *bridge,
  184. struct drm_atomic_state *state)
  185. {
  186. struct tidss_oldi *oldi = drm_bridge_to_tidss_oldi(bridge);
  187. struct drm_connector *connector;
  188. struct drm_connector_state *conn_state;
  189. struct drm_crtc_state *crtc_state;
  190. struct drm_display_mode *mode;
  191. if (oldi->link_type == OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK)
  192. return;
  193. connector = drm_atomic_get_new_connector_for_encoder(state,
  194. bridge->encoder);
  195. if (WARN_ON(!connector))
  196. return;
  197. conn_state = drm_atomic_get_new_connector_state(state, connector);
  198. if (WARN_ON(!conn_state))
  199. return;
  200. crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
  201. if (WARN_ON(!crtc_state))
  202. return;
  203. mode = &crtc_state->adjusted_mode;
  204. /* Configure the OLDI params*/
  205. tidss_oldi_config(oldi);
  206. /* Set the OLDI serial clock (7 times the pixel clock) */
  207. tidss_oldi_set_serial_clk(oldi, mode->clock * 7 * 1000);
  208. /* Enable OLDI IO power */
  209. tidss_oldi_tx_power(oldi, true);
  210. }
  211. static void tidss_oldi_atomic_post_disable(struct drm_bridge *bridge,
  212. struct drm_atomic_state *state)
  213. {
  214. struct tidss_oldi *oldi = drm_bridge_to_tidss_oldi(bridge);
  215. if (oldi->link_type == OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK)
  216. return;
  217. /* Disable OLDI IO power */
  218. tidss_oldi_tx_power(oldi, false);
  219. /* Set the OLDI serial clock to IDLE Frequency */
  220. tidss_oldi_set_serial_clk(oldi, OLDI_IDLE_CLK_HZ);
  221. /* Clear OLDI Config */
  222. tidss_disable_oldi(oldi->tidss, oldi->parent_vp);
  223. }
  224. #define MAX_INPUT_SEL_FORMATS 1
  225. static u32 *tidss_oldi_atomic_get_input_bus_fmts(struct drm_bridge *bridge,
  226. struct drm_bridge_state *bridge_state,
  227. struct drm_crtc_state *crtc_state,
  228. struct drm_connector_state *conn_state,
  229. u32 output_fmt,
  230. unsigned int *num_input_fmts)
  231. {
  232. struct tidss_oldi *oldi = drm_bridge_to_tidss_oldi(bridge);
  233. u32 *input_fmts;
  234. int i;
  235. *num_input_fmts = 0;
  236. for (i = 0; i < ARRAY_SIZE(oldi_bus_formats); i++)
  237. if (oldi_bus_formats[i].bus_fmt == output_fmt)
  238. break;
  239. if (i == ARRAY_SIZE(oldi_bus_formats))
  240. return NULL;
  241. input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts),
  242. GFP_KERNEL);
  243. if (!input_fmts)
  244. return NULL;
  245. *num_input_fmts = 1;
  246. input_fmts[0] = oldi_bus_formats[i].input_bus_fmt;
  247. oldi->bus_format = &oldi_bus_formats[i];
  248. return input_fmts;
  249. }
  250. static enum drm_mode_status
  251. tidss_oldi_mode_valid(struct drm_bridge *bridge,
  252. const struct drm_display_info *info,
  253. const struct drm_display_mode *mode)
  254. {
  255. struct tidss_oldi *oldi = drm_bridge_to_tidss_oldi(bridge);
  256. unsigned long round_clock;
  257. round_clock = clk_round_rate(oldi->serial, mode->clock * 7 * 1000);
  258. /*
  259. * To keep the check consistent with dispc_vp_set_clk_rate(),
  260. * we use the same 5% check here.
  261. */
  262. if (dispc_pclk_diff(mode->clock * 7 * 1000, round_clock) > 5)
  263. return -EINVAL;
  264. return 0;
  265. }
  266. static const struct drm_bridge_funcs tidss_oldi_bridge_funcs = {
  267. .attach = tidss_oldi_bridge_attach,
  268. .atomic_pre_enable = tidss_oldi_atomic_pre_enable,
  269. .atomic_post_disable = tidss_oldi_atomic_post_disable,
  270. .atomic_get_input_bus_fmts = tidss_oldi_atomic_get_input_bus_fmts,
  271. .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
  272. .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
  273. .atomic_reset = drm_atomic_helper_bridge_reset,
  274. .mode_valid = tidss_oldi_mode_valid,
  275. };
  276. static int get_oldi_mode(struct device_node *oldi_tx, int *companion_instance)
  277. {
  278. struct device_node *companion;
  279. struct device_node *port0, *port1;
  280. u32 companion_reg;
  281. bool secondary_oldi = false;
  282. int pixel_order;
  283. /*
  284. * Find if the OLDI is paired with another OLDI for combined OLDI
  285. * operation (dual-link or clone).
  286. */
  287. companion = of_parse_phandle(oldi_tx, "ti,companion-oldi", 0);
  288. if (!companion)
  289. /*
  290. * The OLDI TX does not have a companion, nor is it a
  291. * secondary OLDI. It will operate independently.
  292. */
  293. return OLDI_MODE_SINGLE_LINK;
  294. if (of_property_read_u32(companion, "reg", &companion_reg))
  295. return OLDI_MODE_UNSUPPORTED;
  296. if (companion_reg > (TIDSS_MAX_OLDI_TXES - 1))
  297. /* Invalid companion OLDI reg value. */
  298. return OLDI_MODE_UNSUPPORTED;
  299. *companion_instance = (int)companion_reg;
  300. if (of_property_read_bool(oldi_tx, "ti,secondary-oldi"))
  301. secondary_oldi = true;
  302. /*
  303. * We need to work out if the sink is expecting us to function in
  304. * dual-link mode. We do this by looking at the DT port nodes, the
  305. * OLDI TX ports are connected to. If they are marked as expecting
  306. * even pixels and odd pixels, then we need to enable dual-link.
  307. */
  308. port0 = of_graph_get_port_by_id(oldi_tx, 1);
  309. port1 = of_graph_get_port_by_id(companion, 1);
  310. pixel_order = drm_of_lvds_get_dual_link_pixel_order(port0, port1);
  311. of_node_put(port0);
  312. of_node_put(port1);
  313. of_node_put(companion);
  314. switch (pixel_order) {
  315. case -EINVAL:
  316. /*
  317. * The dual-link properties were not found in at least
  318. * one of the sink nodes. Since 2 OLDI ports are present
  319. * in the DT, it can be safely assumed that the required
  320. * configuration is Clone Mode.
  321. */
  322. return (secondary_oldi ? OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK :
  323. OLDI_MODE_CLONE_SINGLE_LINK);
  324. case DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS:
  325. /*
  326. * Primary OLDI can only support "ODD" pixels. So, from its
  327. * perspective, the pixel order has to be ODD-EVEN.
  328. */
  329. return (secondary_oldi ? OLDI_MODE_UNSUPPORTED :
  330. OLDI_MODE_DUAL_LINK);
  331. case DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS:
  332. /*
  333. * Secondary OLDI can only support "EVEN" pixels. So, from its
  334. * perspective, the pixel order has to be EVEN-ODD.
  335. */
  336. return (secondary_oldi ? OLDI_MODE_SECONDARY_DUAL_LINK :
  337. OLDI_MODE_UNSUPPORTED);
  338. default:
  339. return OLDI_MODE_UNSUPPORTED;
  340. }
  341. }
  342. static int get_parent_dss_vp(struct device_node *oldi_tx, u32 *parent_vp)
  343. {
  344. struct device_node *ep, *dss_port;
  345. int ret;
  346. ep = of_graph_get_endpoint_by_regs(oldi_tx, OLDI_INPUT_PORT, -1);
  347. if (ep) {
  348. dss_port = of_graph_get_remote_port(ep);
  349. if (!dss_port) {
  350. ret = -ENODEV;
  351. goto err_return_ep_port;
  352. }
  353. ret = of_property_read_u32(dss_port, "reg", parent_vp);
  354. of_node_put(dss_port);
  355. err_return_ep_port:
  356. of_node_put(ep);
  357. return ret;
  358. }
  359. return -ENODEV;
  360. }
  361. static const struct drm_bridge_timings default_tidss_oldi_timings = {
  362. .input_bus_flags = DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE
  363. | DRM_BUS_FLAG_DE_HIGH,
  364. };
  365. void tidss_oldi_deinit(struct tidss_device *tidss)
  366. {
  367. for (int i = 0; i < tidss->num_oldis; i++) {
  368. if (tidss->oldis[i]) {
  369. drm_bridge_remove(&tidss->oldis[i]->bridge);
  370. tidss->is_ext_vp_clk[tidss->oldis[i]->parent_vp] = false;
  371. tidss->oldis[i] = NULL;
  372. }
  373. }
  374. }
  375. int tidss_oldi_init(struct tidss_device *tidss)
  376. {
  377. struct tidss_oldi *oldi;
  378. struct device_node *child;
  379. struct drm_bridge *bridge;
  380. u32 parent_vp, oldi_instance;
  381. int companion_instance = -1;
  382. enum tidss_oldi_link_type link_type = OLDI_MODE_UNSUPPORTED;
  383. struct device_node *oldi_parent;
  384. int ret = 0;
  385. tidss->num_oldis = 0;
  386. oldi_parent = of_get_child_by_name(tidss->dev->of_node, "oldi-transmitters");
  387. if (!oldi_parent)
  388. /* Return gracefully */
  389. return 0;
  390. for_each_available_child_of_node(oldi_parent, child) {
  391. ret = get_parent_dss_vp(child, &parent_vp);
  392. if (ret) {
  393. if (ret == -ENODEV) {
  394. /*
  395. * ENODEV means that this particular OLDI node
  396. * is not connected with the DSS, which is not
  397. * a harmful case. There could be another OLDI
  398. * which may still be connected.
  399. * Continue to search for that.
  400. */
  401. continue;
  402. }
  403. goto err_put_node;
  404. }
  405. ret = of_property_read_u32(child, "reg", &oldi_instance);
  406. if (ret)
  407. goto err_put_node;
  408. /*
  409. * Now that it's confirmed that OLDI is connected with DSS,
  410. * let's continue getting the OLDI sinks ahead and other OLDI
  411. * properties.
  412. */
  413. bridge = devm_drm_of_get_bridge(tidss->dev, child,
  414. OLDI_OUTPUT_PORT, 0);
  415. if (IS_ERR(bridge)) {
  416. /*
  417. * Either there was no OLDI sink in the devicetree, or
  418. * the OLDI sink has not been added yet. In any case,
  419. * return.
  420. * We don't want to have an OLDI node connected to DSS
  421. * but not to any sink.
  422. */
  423. ret = dev_err_probe(tidss->dev, PTR_ERR(bridge),
  424. "no panel/bridge for OLDI%u.\n",
  425. oldi_instance);
  426. goto err_put_node;
  427. }
  428. link_type = get_oldi_mode(child, &companion_instance);
  429. if (link_type == OLDI_MODE_UNSUPPORTED) {
  430. ret = dev_err_probe(tidss->dev, -EINVAL,
  431. "OLDI%u: Unsupported OLDI connection.\n",
  432. oldi_instance);
  433. goto err_put_node;
  434. } else if ((link_type == OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK) ||
  435. (link_type == OLDI_MODE_CLONE_SINGLE_LINK)) {
  436. /*
  437. * The OLDI driver cannot support OLDI clone mode
  438. * properly at present.
  439. * The clone mode requires 2 working encoder-bridge
  440. * pipelines, generating from the same crtc. The DRM
  441. * framework does not support this at present. If
  442. * there were to be, say, 2 OLDI sink bridges each
  443. * connected to an OLDI TXes, they couldn't both be
  444. * supported simultaneously.
  445. * This driver still has some code pertaining to OLDI
  446. * clone mode configuration in DSS hardware for future,
  447. * when there is a better infrastructure in the DRM
  448. * framework to support 2 encoder-bridge pipelines
  449. * simultaneously.
  450. * Till that time, this driver shall error out if it
  451. * detects a clone mode configuration.
  452. */
  453. ret = dev_err_probe(tidss->dev, -EOPNOTSUPP,
  454. "The OLDI driver does not support Clone Mode at present.\n");
  455. goto err_put_node;
  456. } else if (link_type == OLDI_MODE_SECONDARY_DUAL_LINK) {
  457. /*
  458. * This is the secondary OLDI node, which serves as a
  459. * companion to the primary OLDI, when it is configured
  460. * for the dual-link mode. Since the primary OLDI will
  461. * be a part of bridge chain, no need to put this one
  462. * too. Continue onto the next OLDI node.
  463. */
  464. continue;
  465. }
  466. oldi = devm_drm_bridge_alloc(tidss->dev, struct tidss_oldi, bridge,
  467. &tidss_oldi_bridge_funcs);
  468. if (IS_ERR(oldi)) {
  469. ret = PTR_ERR(oldi);
  470. goto err_put_node;
  471. }
  472. oldi->parent_vp = parent_vp;
  473. oldi->oldi_instance = oldi_instance;
  474. oldi->companion_instance = companion_instance;
  475. oldi->link_type = link_type;
  476. oldi->dev = tidss->dev;
  477. oldi->next_bridge = bridge;
  478. /*
  479. * Only the primary OLDI needs to reference the io-ctrl system
  480. * registers, and the serial clock.
  481. * We don't require a check for secondary OLDI in dual-link mode
  482. * because the driver will not create a drm_bridge instance.
  483. * But the driver will need to create a drm_bridge instance,
  484. * for secondary OLDI in clone mode (once it is supported).
  485. */
  486. if (link_type != OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK) {
  487. oldi->io_ctrl = syscon_regmap_lookup_by_phandle(child,
  488. "ti,oldi-io-ctrl");
  489. if (IS_ERR(oldi->io_ctrl)) {
  490. ret = dev_err_probe(oldi->dev, PTR_ERR(oldi->io_ctrl),
  491. "OLDI%u: syscon_regmap_lookup_by_phandle failed.\n",
  492. oldi_instance);
  493. goto err_put_node;
  494. }
  495. oldi->serial = of_clk_get_by_name(child, "serial");
  496. if (IS_ERR(oldi->serial)) {
  497. ret = dev_err_probe(oldi->dev, PTR_ERR(oldi->serial),
  498. "OLDI%u: Failed to get serial clock.\n",
  499. oldi_instance);
  500. goto err_put_node;
  501. }
  502. }
  503. /* Register the bridge. */
  504. oldi->bridge.of_node = child;
  505. oldi->bridge.driver_private = oldi;
  506. oldi->bridge.timings = &default_tidss_oldi_timings;
  507. tidss->oldis[tidss->num_oldis++] = oldi;
  508. tidss->is_ext_vp_clk[oldi->parent_vp] = true;
  509. oldi->tidss = tidss;
  510. drm_bridge_add(&oldi->bridge);
  511. }
  512. of_node_put(child);
  513. of_node_put(oldi_parent);
  514. return 0;
  515. err_put_node:
  516. of_node_put(child);
  517. of_node_put(oldi_parent);
  518. return ret;
  519. }