lsdc_output_7a2000.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2023 Loongson Technology Corporation Limited
  4. */
  5. #include <linux/delay.h>
  6. #include <drm/drm_atomic_helper.h>
  7. #include <drm/drm_debugfs.h>
  8. #include <drm/drm_edid.h>
  9. #include <drm/drm_probe_helper.h>
  10. #include "lsdc_drv.h"
  11. #include "lsdc_output.h"
  12. /*
  13. * The display controller in LS7A2000 has two display pipes
  14. * Display pipe 0 is attached with a built-in transparent VGA encoder and
  15. * a built-in HDMI encoder.
  16. * Display pipe 1 has only one built-in HDMI encoder connected.
  17. * ______________________ _____________
  18. * | +-----+ | | |
  19. * | CRTC0 -+--> | VGA | ----> VGA Connector ---> | VGA Monitor |<---+
  20. * | | +-----+ | |_____________| |
  21. * | | | ______________ |
  22. * | | +------+ | | | |
  23. * | +--> | HDMI | ----> HDMI Connector --> | HDMI Monitor |<--+
  24. * | +------+ | |______________| |
  25. * | +------+ | |
  26. * | | i2c6 | <-------------------------------------------+
  27. * | +------+ |
  28. * | |
  29. * | DC in LS7A2000 |
  30. * | |
  31. * | +------+ |
  32. * | | i2c7 | <--------------------------------+
  33. * | +------+ | |
  34. * | | ______|_______
  35. * | +------+ | | |
  36. * | CRTC1 ---> | HDMI | ----> HDMI Connector ---> | HDMI Monitor |
  37. * | +------+ | |______________|
  38. * |______________________|
  39. */
  40. static int ls7a2000_connector_get_modes(struct drm_connector *connector)
  41. {
  42. int num;
  43. if (connector->ddc) {
  44. const struct drm_edid *drm_edid;
  45. drm_edid = drm_edid_read(connector);
  46. drm_edid_connector_update(connector, drm_edid);
  47. num = drm_edid_connector_add_modes(connector);
  48. drm_edid_free(drm_edid);
  49. return num;
  50. }
  51. num = drm_add_modes_noedid(connector, 1920, 1200);
  52. drm_set_preferred_mode(connector, 1024, 768);
  53. return num;
  54. }
  55. static struct drm_encoder *
  56. ls7a2000_connector_get_best_encoder(struct drm_connector *connector,
  57. struct drm_atomic_state *state)
  58. {
  59. struct lsdc_output *output = connector_to_lsdc_output(connector);
  60. return &output->encoder;
  61. }
  62. static const struct drm_connector_helper_funcs ls7a2000_connector_helpers = {
  63. .atomic_best_encoder = ls7a2000_connector_get_best_encoder,
  64. .get_modes = ls7a2000_connector_get_modes,
  65. };
  66. /* debugfs */
  67. #define LSDC_HDMI_REG(i, reg) { \
  68. .name = __stringify_1(LSDC_HDMI##i##_##reg##_REG), \
  69. .offset = LSDC_HDMI##i##_##reg##_REG, \
  70. }
  71. static const struct lsdc_reg32 ls7a2000_hdmi0_encoder_regs[] = {
  72. LSDC_HDMI_REG(0, ZONE),
  73. LSDC_HDMI_REG(0, INTF_CTRL),
  74. LSDC_HDMI_REG(0, PHY_CTRL),
  75. LSDC_HDMI_REG(0, PHY_PLL),
  76. LSDC_HDMI_REG(0, AVI_INFO_CRTL),
  77. LSDC_HDMI_REG(0, PHY_CAL),
  78. LSDC_HDMI_REG(0, AUDIO_PLL_LO),
  79. LSDC_HDMI_REG(0, AUDIO_PLL_HI),
  80. {NULL, 0}, /* MUST be {NULL, 0} terminated */
  81. };
  82. static const struct lsdc_reg32 ls7a2000_hdmi1_encoder_regs[] = {
  83. LSDC_HDMI_REG(1, ZONE),
  84. LSDC_HDMI_REG(1, INTF_CTRL),
  85. LSDC_HDMI_REG(1, PHY_CTRL),
  86. LSDC_HDMI_REG(1, PHY_PLL),
  87. LSDC_HDMI_REG(1, AVI_INFO_CRTL),
  88. LSDC_HDMI_REG(1, PHY_CAL),
  89. LSDC_HDMI_REG(1, AUDIO_PLL_LO),
  90. LSDC_HDMI_REG(1, AUDIO_PLL_HI),
  91. {NULL, 0}, /* MUST be {NULL, 0} terminated */
  92. };
  93. static int ls7a2000_hdmi_encoder_regs_show(struct seq_file *m, void *data)
  94. {
  95. struct drm_info_node *node = (struct drm_info_node *)m->private;
  96. struct drm_device *ddev = node->minor->dev;
  97. struct lsdc_device *ldev = to_lsdc(ddev);
  98. const struct lsdc_reg32 *preg;
  99. preg = (const struct lsdc_reg32 *)node->info_ent->data;
  100. while (preg->name) {
  101. u32 offset = preg->offset;
  102. seq_printf(m, "%s (0x%04x): 0x%08x\n",
  103. preg->name, offset, lsdc_rreg32(ldev, offset));
  104. ++preg;
  105. }
  106. return 0;
  107. }
  108. static const struct drm_info_list ls7a2000_hdmi0_debugfs_files[] = {
  109. { "regs", ls7a2000_hdmi_encoder_regs_show, 0, (void *)ls7a2000_hdmi0_encoder_regs },
  110. };
  111. static const struct drm_info_list ls7a2000_hdmi1_debugfs_files[] = {
  112. { "regs", ls7a2000_hdmi_encoder_regs_show, 0, (void *)ls7a2000_hdmi1_encoder_regs },
  113. };
  114. static void ls7a2000_hdmi0_late_register(struct drm_connector *connector,
  115. struct dentry *root)
  116. {
  117. struct drm_device *ddev = connector->dev;
  118. struct drm_minor *minor = ddev->primary;
  119. drm_debugfs_create_files(ls7a2000_hdmi0_debugfs_files,
  120. ARRAY_SIZE(ls7a2000_hdmi0_debugfs_files),
  121. root, minor);
  122. }
  123. static void ls7a2000_hdmi1_late_register(struct drm_connector *connector,
  124. struct dentry *root)
  125. {
  126. struct drm_device *ddev = connector->dev;
  127. struct drm_minor *minor = ddev->primary;
  128. drm_debugfs_create_files(ls7a2000_hdmi1_debugfs_files,
  129. ARRAY_SIZE(ls7a2000_hdmi1_debugfs_files),
  130. root, minor);
  131. }
  132. /* monitor present detection */
  133. static enum drm_connector_status
  134. ls7a2000_hdmi0_vga_connector_detect(struct drm_connector *connector, bool force)
  135. {
  136. struct drm_device *ddev = connector->dev;
  137. struct lsdc_device *ldev = to_lsdc(ddev);
  138. u32 val;
  139. val = lsdc_rreg32(ldev, LSDC_HDMI_HPD_STATUS_REG);
  140. if (val & HDMI0_HPD_FLAG)
  141. return connector_status_connected;
  142. if (connector->ddc) {
  143. if (drm_probe_ddc(connector->ddc))
  144. return connector_status_connected;
  145. return connector_status_disconnected;
  146. }
  147. return connector_status_unknown;
  148. }
  149. static enum drm_connector_status
  150. ls7a2000_hdmi1_connector_detect(struct drm_connector *connector, bool force)
  151. {
  152. struct lsdc_device *ldev = to_lsdc(connector->dev);
  153. u32 val;
  154. val = lsdc_rreg32(ldev, LSDC_HDMI_HPD_STATUS_REG);
  155. if (val & HDMI1_HPD_FLAG)
  156. return connector_status_connected;
  157. return connector_status_disconnected;
  158. }
  159. static const struct drm_connector_funcs ls7a2000_hdmi_connector_funcs[2] = {
  160. {
  161. .detect = ls7a2000_hdmi0_vga_connector_detect,
  162. .fill_modes = drm_helper_probe_single_connector_modes,
  163. .destroy = drm_connector_cleanup,
  164. .reset = drm_atomic_helper_connector_reset,
  165. .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
  166. .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
  167. .debugfs_init = ls7a2000_hdmi0_late_register,
  168. },
  169. {
  170. .detect = ls7a2000_hdmi1_connector_detect,
  171. .fill_modes = drm_helper_probe_single_connector_modes,
  172. .destroy = drm_connector_cleanup,
  173. .reset = drm_atomic_helper_connector_reset,
  174. .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
  175. .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
  176. .debugfs_init = ls7a2000_hdmi1_late_register,
  177. },
  178. };
  179. /* Even though some board has only one hdmi on display pipe 1,
  180. * We still need hook lsdc_encoder_funcs up on display pipe 0,
  181. * This is because we need its reset() callback get called, to
  182. * set the LSDC_HDMIx_CTRL_REG using software gpio emulated i2c.
  183. * Otherwise, the firmware may set LSDC_HDMIx_CTRL_REG blindly.
  184. */
  185. static void ls7a2000_hdmi0_encoder_reset(struct drm_encoder *encoder)
  186. {
  187. struct drm_device *ddev = encoder->dev;
  188. struct lsdc_device *ldev = to_lsdc(ddev);
  189. u32 val;
  190. val = PHY_CLOCK_POL | PHY_CLOCK_EN | PHY_DATA_EN;
  191. lsdc_wreg32(ldev, LSDC_CRTC0_DVO_CONF_REG, val);
  192. /* using software gpio emulated i2c */
  193. val = lsdc_rreg32(ldev, LSDC_HDMI0_INTF_CTRL_REG);
  194. val &= ~HW_I2C_EN;
  195. lsdc_wreg32(ldev, LSDC_HDMI0_INTF_CTRL_REG, val);
  196. /* help the hdmi phy to get out of reset state */
  197. lsdc_wreg32(ldev, LSDC_HDMI0_PHY_CTRL_REG, HDMI_PHY_RESET_N);
  198. mdelay(20);
  199. drm_dbg(ddev, "HDMI-0 Reset\n");
  200. }
  201. static void ls7a2000_hdmi1_encoder_reset(struct drm_encoder *encoder)
  202. {
  203. struct drm_device *ddev = encoder->dev;
  204. struct lsdc_device *ldev = to_lsdc(ddev);
  205. u32 val;
  206. val = PHY_CLOCK_POL | PHY_CLOCK_EN | PHY_DATA_EN;
  207. lsdc_wreg32(ldev, LSDC_CRTC1_DVO_CONF_REG, val);
  208. /* using software gpio emulated i2c */
  209. val = lsdc_rreg32(ldev, LSDC_HDMI1_INTF_CTRL_REG);
  210. val &= ~HW_I2C_EN;
  211. lsdc_wreg32(ldev, LSDC_HDMI1_INTF_CTRL_REG, val);
  212. /* help the hdmi phy to get out of reset state */
  213. lsdc_wreg32(ldev, LSDC_HDMI1_PHY_CTRL_REG, HDMI_PHY_RESET_N);
  214. mdelay(20);
  215. drm_dbg(ddev, "HDMI-1 Reset\n");
  216. }
  217. static const struct drm_encoder_funcs ls7a2000_encoder_funcs[2] = {
  218. {
  219. .reset = ls7a2000_hdmi0_encoder_reset,
  220. .destroy = drm_encoder_cleanup,
  221. },
  222. {
  223. .reset = ls7a2000_hdmi1_encoder_reset,
  224. .destroy = drm_encoder_cleanup,
  225. },
  226. };
  227. static int ls7a2000_hdmi_set_avi_infoframe(struct drm_encoder *encoder,
  228. struct drm_display_mode *mode)
  229. {
  230. struct lsdc_output *output = encoder_to_lsdc_output(encoder);
  231. struct lsdc_display_pipe *dispipe = output_to_display_pipe(output);
  232. unsigned int index = dispipe->index;
  233. struct drm_device *ddev = encoder->dev;
  234. struct lsdc_device *ldev = to_lsdc(ddev);
  235. struct hdmi_avi_infoframe infoframe;
  236. u8 buffer[HDMI_INFOFRAME_SIZE(AVI)];
  237. unsigned char *ptr = &buffer[HDMI_INFOFRAME_HEADER_SIZE];
  238. unsigned int content0, content1, content2, content3;
  239. int err;
  240. err = drm_hdmi_avi_infoframe_from_display_mode(&infoframe,
  241. &output->connector,
  242. mode);
  243. if (err < 0) {
  244. drm_err(ddev, "failed to setup AVI infoframe: %d\n", err);
  245. return err;
  246. }
  247. /* Fixed infoframe configuration not linked to the mode */
  248. infoframe.colorspace = HDMI_COLORSPACE_RGB;
  249. infoframe.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT;
  250. infoframe.colorimetry = HDMI_COLORIMETRY_NONE;
  251. err = hdmi_avi_infoframe_pack(&infoframe, buffer, sizeof(buffer));
  252. if (err < 0) {
  253. drm_err(ddev, "failed to pack AVI infoframe: %d\n", err);
  254. return err;
  255. }
  256. content0 = *(unsigned int *)ptr;
  257. content1 = *(ptr + 4);
  258. content2 = *(unsigned int *)(ptr + 5);
  259. content3 = *(unsigned int *)(ptr + 9);
  260. lsdc_pipe_wreg32(ldev, LSDC_HDMI0_AVI_CONTENT0, index, content0);
  261. lsdc_pipe_wreg32(ldev, LSDC_HDMI0_AVI_CONTENT1, index, content1);
  262. lsdc_pipe_wreg32(ldev, LSDC_HDMI0_AVI_CONTENT2, index, content2);
  263. lsdc_pipe_wreg32(ldev, LSDC_HDMI0_AVI_CONTENT3, index, content3);
  264. lsdc_pipe_wreg32(ldev, LSDC_HDMI0_AVI_INFO_CRTL_REG, index,
  265. AVI_PKT_ENABLE | AVI_PKT_UPDATE);
  266. drm_dbg(ddev, "Update HDMI-%u avi infoframe\n", index);
  267. return 0;
  268. }
  269. static void ls7a2000_hdmi_atomic_disable(struct drm_encoder *encoder,
  270. struct drm_atomic_state *state)
  271. {
  272. struct lsdc_output *output = encoder_to_lsdc_output(encoder);
  273. struct lsdc_display_pipe *dispipe = output_to_display_pipe(output);
  274. unsigned int index = dispipe->index;
  275. struct drm_device *ddev = encoder->dev;
  276. struct lsdc_device *ldev = to_lsdc(ddev);
  277. u32 val;
  278. /* Disable the hdmi phy */
  279. val = lsdc_pipe_rreg32(ldev, LSDC_HDMI0_PHY_CTRL_REG, index);
  280. val &= ~HDMI_PHY_EN;
  281. lsdc_pipe_wreg32(ldev, LSDC_HDMI0_PHY_CTRL_REG, index, val);
  282. /* Disable the hdmi interface */
  283. val = lsdc_pipe_rreg32(ldev, LSDC_HDMI0_INTF_CTRL_REG, index);
  284. val &= ~HDMI_INTERFACE_EN;
  285. lsdc_pipe_wreg32(ldev, LSDC_HDMI0_INTF_CTRL_REG, index, val);
  286. drm_dbg(ddev, "HDMI-%u disabled\n", index);
  287. }
  288. static void ls7a2000_hdmi_atomic_enable(struct drm_encoder *encoder,
  289. struct drm_atomic_state *state)
  290. {
  291. struct drm_device *ddev = encoder->dev;
  292. struct lsdc_device *ldev = to_lsdc(ddev);
  293. struct lsdc_output *output = encoder_to_lsdc_output(encoder);
  294. struct lsdc_display_pipe *dispipe = output_to_display_pipe(output);
  295. unsigned int index = dispipe->index;
  296. u32 val;
  297. /* datasheet say it should larger than 48 */
  298. val = 64 << HDMI_H_ZONE_IDLE_SHIFT | 64 << HDMI_V_ZONE_IDLE_SHIFT;
  299. lsdc_pipe_wreg32(ldev, LSDC_HDMI0_ZONE_REG, index, val);
  300. val = HDMI_PHY_TERM_STATUS |
  301. HDMI_PHY_TERM_DET_EN |
  302. HDMI_PHY_TERM_H_EN |
  303. HDMI_PHY_TERM_L_EN |
  304. HDMI_PHY_RESET_N |
  305. HDMI_PHY_EN;
  306. lsdc_pipe_wreg32(ldev, LSDC_HDMI0_PHY_CTRL_REG, index, val);
  307. udelay(2);
  308. val = HDMI_CTL_PERIOD_MODE |
  309. HDMI_AUDIO_EN |
  310. HDMI_PACKET_EN |
  311. HDMI_INTERFACE_EN |
  312. (8 << HDMI_VIDEO_PREAMBLE_SHIFT);
  313. lsdc_pipe_wreg32(ldev, LSDC_HDMI0_INTF_CTRL_REG, index, val);
  314. drm_dbg(ddev, "HDMI-%u enabled\n", index);
  315. }
  316. /*
  317. * Fout = M * Fin
  318. *
  319. * M = (4 * LF) / (IDF * ODF)
  320. *
  321. * IDF: Input Division Factor
  322. * ODF: Output Division Factor
  323. * LF: Loop Factor
  324. * M: Required Mult
  325. *
  326. * +--------------------------------------------------------+
  327. * | Fin (kHZ) | M | IDF | LF | ODF | Fout(Mhz) |
  328. * |-------------------+----+-----+----+-----+--------------|
  329. * | 170000 ~ 340000 | 10 | 16 | 40 | 1 | 1700 ~ 3400 |
  330. * | 85000 ~ 170000 | 10 | 8 | 40 | 2 | 850 ~ 1700 |
  331. * | 42500 ~ 85000 | 10 | 4 | 40 | 4 | 425 ~ 850 |
  332. * | 21250 ~ 42500 | 10 | 2 | 40 | 8 | 212.5 ~ 425 |
  333. * | 20000 ~ 21250 | 10 | 1 | 40 | 16 | 200 ~ 212.5 |
  334. * +--------------------------------------------------------+
  335. */
  336. static void ls7a2000_hdmi_phy_pll_config(struct lsdc_device *ldev,
  337. int fin,
  338. unsigned int index)
  339. {
  340. struct drm_device *ddev = &ldev->base;
  341. int count = 0;
  342. u32 val;
  343. /* Firstly, disable phy pll */
  344. lsdc_pipe_wreg32(ldev, LSDC_HDMI0_PHY_PLL_REG, index, 0x0);
  345. /*
  346. * Most of time, loongson HDMI require M = 10
  347. * for example, 10 = (4 * 40) / (8 * 2)
  348. * here, write "1" to the ODF will get "2"
  349. */
  350. if (fin >= 170000)
  351. val = (16 << HDMI_PLL_IDF_SHIFT) |
  352. (40 << HDMI_PLL_LF_SHIFT) |
  353. (0 << HDMI_PLL_ODF_SHIFT);
  354. else if (fin >= 85000)
  355. val = (8 << HDMI_PLL_IDF_SHIFT) |
  356. (40 << HDMI_PLL_LF_SHIFT) |
  357. (1 << HDMI_PLL_ODF_SHIFT);
  358. else if (fin >= 42500)
  359. val = (4 << HDMI_PLL_IDF_SHIFT) |
  360. (40 << HDMI_PLL_LF_SHIFT) |
  361. (2 << HDMI_PLL_ODF_SHIFT);
  362. else if (fin >= 21250)
  363. val = (2 << HDMI_PLL_IDF_SHIFT) |
  364. (40 << HDMI_PLL_LF_SHIFT) |
  365. (3 << HDMI_PLL_ODF_SHIFT);
  366. else
  367. val = (1 << HDMI_PLL_IDF_SHIFT) |
  368. (40 << HDMI_PLL_LF_SHIFT) |
  369. (4 << HDMI_PLL_ODF_SHIFT);
  370. lsdc_pipe_wreg32(ldev, LSDC_HDMI0_PHY_PLL_REG, index, val);
  371. val |= HDMI_PLL_ENABLE;
  372. lsdc_pipe_wreg32(ldev, LSDC_HDMI0_PHY_PLL_REG, index, val);
  373. udelay(2);
  374. drm_dbg(ddev, "Fin of HDMI-%u: %d kHz\n", index, fin);
  375. /* Wait hdmi phy pll lock */
  376. do {
  377. val = lsdc_pipe_rreg32(ldev, LSDC_HDMI0_PHY_PLL_REG, index);
  378. if (val & HDMI_PLL_LOCKED) {
  379. drm_dbg(ddev, "Setting HDMI-%u PLL take %d cycles\n",
  380. index, count);
  381. break;
  382. }
  383. ++count;
  384. } while (count < 1000);
  385. lsdc_pipe_wreg32(ldev, LSDC_HDMI0_PHY_CAL_REG, index, 0x0f000ff0);
  386. if (count >= 1000)
  387. drm_err(ddev, "Setting HDMI-%u PLL failed\n", index);
  388. }
  389. static void ls7a2000_hdmi_atomic_mode_set(struct drm_encoder *encoder,
  390. struct drm_crtc_state *crtc_state,
  391. struct drm_connector_state *conn_state)
  392. {
  393. struct lsdc_output *output = encoder_to_lsdc_output(encoder);
  394. struct lsdc_display_pipe *dispipe = output_to_display_pipe(output);
  395. unsigned int index = dispipe->index;
  396. struct drm_device *ddev = encoder->dev;
  397. struct lsdc_device *ldev = to_lsdc(ddev);
  398. struct drm_display_mode *mode = &crtc_state->mode;
  399. ls7a2000_hdmi_phy_pll_config(ldev, mode->clock, index);
  400. ls7a2000_hdmi_set_avi_infoframe(encoder, mode);
  401. drm_dbg(ddev, "%s modeset finished\n", encoder->name);
  402. }
  403. static const struct drm_encoder_helper_funcs ls7a2000_encoder_helper_funcs = {
  404. .atomic_disable = ls7a2000_hdmi_atomic_disable,
  405. .atomic_enable = ls7a2000_hdmi_atomic_enable,
  406. .atomic_mode_set = ls7a2000_hdmi_atomic_mode_set,
  407. };
  408. /*
  409. * For LS7A2000:
  410. *
  411. * 1) Most of board export one vga + hdmi output interface.
  412. * 2) Yet, Some boards export double hdmi output interface.
  413. * 3) Still have boards export three output(2 hdmi + 1 vga).
  414. *
  415. * So let's hook hdmi helper funcs to all display pipe, don't miss.
  416. * writing hdmi register do no harms.
  417. */
  418. int ls7a2000_output_init(struct drm_device *ddev,
  419. struct lsdc_display_pipe *dispipe,
  420. struct i2c_adapter *ddc,
  421. unsigned int pipe)
  422. {
  423. struct lsdc_output *output = &dispipe->output;
  424. struct drm_encoder *encoder = &output->encoder;
  425. struct drm_connector *connector = &output->connector;
  426. int ret;
  427. ret = drm_encoder_init(ddev, encoder, &ls7a2000_encoder_funcs[pipe],
  428. DRM_MODE_ENCODER_TMDS, "encoder-%u", pipe);
  429. if (ret)
  430. return ret;
  431. encoder->possible_crtcs = BIT(pipe);
  432. drm_encoder_helper_add(encoder, &ls7a2000_encoder_helper_funcs);
  433. ret = drm_connector_init_with_ddc(ddev, connector,
  434. &ls7a2000_hdmi_connector_funcs[pipe],
  435. DRM_MODE_CONNECTOR_HDMIA, ddc);
  436. if (ret)
  437. return ret;
  438. drm_info(ddev, "display pipe-%u has HDMI %s\n", pipe, pipe ? "" : "and/or VGA");
  439. drm_connector_helper_add(connector, &ls7a2000_connector_helpers);
  440. drm_connector_attach_encoder(connector, encoder);
  441. connector->polled = DRM_CONNECTOR_POLL_CONNECT |
  442. DRM_CONNECTOR_POLL_DISCONNECT;
  443. connector->interlace_allowed = 0;
  444. connector->doublescan_allowed = 0;
  445. return 0;
  446. }