cdns-mhdp.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Cadence MHDP DP bridge driver.
  4. *
  5. * Copyright: 2018 Cadence Design Systems, Inc.
  6. *
  7. * Author: Quentin Schulz <quentin.schulz@free-electrons.com>
  8. */
  9. #include <linux/clk.h>
  10. #include <linux/delay.h>
  11. #include <linux/err.h>
  12. #include <linux/firmware.h>
  13. #include <linux/io.h>
  14. #include <linux/iopoll.h>
  15. #include <linux/module.h>
  16. #include <linux/of.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/slab.h>
  19. #include <linux/phy/phy.h>
  20. #include <linux/phy/phy-dp.h>
  21. #include <drm/bridge/cdns-mhdp-common.h>
  22. #include <drm/drm_atomic_helper.h>
  23. #include <drm/drm_bridge.h>
  24. #include <drm/drm_connector.h>
  25. #include <drm/drm_crtc_helper.h>
  26. #include <drm/drm_dp_helper.h>
  27. #include <drm/drm_modeset_helper_vtables.h>
  28. #include <drm/drm_print.h>
  29. #include <drm/drm_crtc_helper.h>
  30. #include <sound/hdmi-codec.h>
  31. #include <linux/irq.h>
  32. #include <linux/of_irq.h>
  33. #include "cdns-mhdp.h"
  34. #include "cdns-mhdp-j721e.h"
  35. #define FW_NAME "cadence/mhdp8546.bin"
  36. #define CDNS_MHDP_IMEM 0x10000
  37. #define CDNS_DP_TRAINING_PATTERN_4 0x7
  38. #define CDNS_KEEP_ALIVE_TIMEOUT 2000
  39. static const struct of_device_id mhdp_ids[] = {
  40. { .compatible = "cdns,mhdp8546", },
  41. { /* sentinel */ }
  42. };
  43. MODULE_DEVICE_TABLE(of, mhdp_ids);
  44. #define CDNS_LANE_1 BIT(0)
  45. #define CDNS_LANE_2 BIT(1)
  46. #define CDNS_LANE_4 BIT(2)
  47. #define CDNS_SSC BIT(3)
  48. #define CDNS_SCRAMBLER BIT(4)
  49. #define CDNS_VOLT_SWING(x) ((x) & GENMASK(1, 0))
  50. #define CDNS_FORCE_VOLT_SWING BIT(2)
  51. #define CDNS_PRE_EMPHASIS(x) ((x) & GENMASK(1, 0))
  52. #define CDNS_FORCE_PRE_EMPHASIS BIT(2)
  53. #define CDNS_SUPPORT_TPS(x) BIT((x) - 1)
  54. #define CDNS_FAST_LINK_TRAINING BIT(0)
  55. #define CDNS_LANE_MAPPING_TYPE_C_LANE_0(x) ((x) & GENMASK(1, 0))
  56. #define CDNS_LANE_MAPPING_TYPE_C_LANE_1(x) ((x) & GENMASK(3, 2))
  57. #define CDNS_LANE_MAPPING_TYPE_C_LANE_2(x) ((x) & GENMASK(5, 4))
  58. #define CDNS_LANE_MAPPING_TYPE_C_LANE_3(x) ((x) & GENMASK(7, 6))
  59. #define CDNS_LANE_MAPPING_NORMAL 0xe4
  60. #define CDNS_LANE_MAPPING_FLIPPED 0x1b
  61. #define CDNS_DP_MAX_NUM_LANES 4
  62. #define CDNS_DP_TEST_VSC_SDP (1 << 6) /* 1.3+ */
  63. #define CDNS_DP_TEST_COLOR_FORMAT_RAW_Y_ONLY (1 << 7)
  64. static inline struct cdns_mhdp_device *connector_to_mhdp(
  65. struct drm_connector *conn)
  66. {
  67. struct cdns_mhdp_connector *mhdp_connector = to_mhdp_connector(conn);
  68. return mhdp_connector->bridge->mhdp;
  69. }
  70. static inline struct cdns_mhdp_device *bridge_to_mhdp(
  71. struct drm_bridge *bridge)
  72. {
  73. struct cdns_mhdp_bridge *mhdp_bridge = to_mhdp_bridge(bridge);
  74. return mhdp_bridge->mhdp;
  75. }
  76. static unsigned int max_link_rate(struct cdns_mhdp_host host,
  77. struct cdns_mhdp_sink sink)
  78. {
  79. return min(host.link_rate, sink.link_rate);
  80. }
  81. static u8 eq_training_pattern_supported(struct cdns_mhdp_host host,
  82. struct cdns_mhdp_sink sink)
  83. {
  84. return fls(host.pattern_supp & sink.pattern_supp);
  85. }
  86. static void mhdp_hotplug_work_func(struct work_struct *work)
  87. {
  88. struct cdns_mhdp_device *mhdp;
  89. mhdp = container_of(work, struct cdns_mhdp_device,
  90. hotplug_work.work);
  91. drm_kms_helper_hotplug_event(mhdp->bridge.base.dev);
  92. }
  93. static irqreturn_t mhdp_irq_handler(int irq, void *data)
  94. {
  95. struct cdns_mhdp_device *mhdp = (struct cdns_mhdp_device *)data;
  96. u32 mbox_stat, apb_stat, sw_ev0, sw_ev1, sw_ev2, sw_ev3;
  97. apb_stat = readl(mhdp->regs + CDNS_APB_INT_STATUS);
  98. mbox_stat = readl(mhdp->regs + CDNS_MB_INT_STATUS);
  99. sw_ev0 = readl(mhdp->regs + CDNS_SW_EVENT0);
  100. sw_ev1 = readl(mhdp->regs + CDNS_SW_EVENT1);
  101. sw_ev2 = readl(mhdp->regs + CDNS_SW_EVENT2);
  102. sw_ev3 = readl(mhdp->regs + CDNS_SW_EVENT3);
  103. //dev_dbg(mhdp->dev, "MHDP IRQ apb %x, mbox %x, sw_ev %x/%x/%x/%x\n", apb_stat, mbox_stat, sw_ev0, sw_ev1, sw_ev2, sw_ev3);
  104. if (sw_ev0 & CDNS_DPTX_HPD)
  105. schedule_delayed_work(&mhdp->hotplug_work, 0);
  106. return IRQ_HANDLED;
  107. }
  108. static ssize_t mhdp_transfer(struct drm_dp_aux *aux,
  109. struct drm_dp_aux_msg *msg)
  110. {
  111. struct cdns_mhdp_device *mhdp = dev_get_drvdata(aux->dev);
  112. int ret;
  113. if (msg->request != DP_AUX_NATIVE_WRITE &&
  114. msg->request != DP_AUX_NATIVE_READ)
  115. return -ENOTSUPP;
  116. if (msg->request == DP_AUX_NATIVE_WRITE) {
  117. const u8 *buf = msg->buffer;
  118. int i;
  119. for (i = 0; i < msg->size; ++i) {
  120. ret = cdns_mhdp_dpcd_write(mhdp,
  121. msg->address + i, buf[i]);
  122. if (!ret)
  123. continue;
  124. DRM_DEV_ERROR(mhdp->dev, "Failed to write DPCD\n");
  125. return ret;
  126. }
  127. } else {
  128. ret = cdns_mhdp_dpcd_read(mhdp, msg->address,
  129. msg->buffer, msg->size);
  130. if (ret) {
  131. DRM_DEV_ERROR(mhdp->dev, "Failed to read DPCD\n");
  132. return ret;
  133. }
  134. }
  135. return msg->size;
  136. }
  137. static int cdns_mhdp_get_modes(struct drm_connector *connector)
  138. {
  139. struct cdns_mhdp_device *mhdp = connector_to_mhdp(connector);
  140. struct edid *edid;
  141. int num_modes;
  142. edid = drm_do_get_edid(connector, cdns_mhdp_get_edid_block, mhdp);
  143. if (!edid) {
  144. DRM_DEV_ERROR(mhdp->dev, "Failed to read EDID\n");
  145. return 0;
  146. }
  147. drm_connector_update_edid_property(connector, edid);
  148. num_modes = drm_add_edid_modes(connector, edid);
  149. kfree(edid);
  150. /*
  151. * HACK: Warn about unsupported display formats until we deal
  152. * with them correctly.
  153. */
  154. if (!(connector->display_info.color_formats &
  155. mhdp->display_fmt.color_format))
  156. dev_warn(mhdp->dev,
  157. "%s: No supported color_format found (0x%08x)\n",
  158. __func__, connector->display_info.color_formats);
  159. if (connector->display_info.bpc < mhdp->display_fmt.bpc)
  160. dev_warn(mhdp->dev, "%s: Display bpc only %d < %d\n",
  161. __func__, connector->display_info.bpc,
  162. mhdp->display_fmt.bpc);
  163. return num_modes;
  164. }
  165. static const struct drm_connector_helper_funcs cdns_mhdp_conn_helper_funcs = {
  166. .get_modes = cdns_mhdp_get_modes,
  167. };
  168. static enum drm_connector_status cdns_mhdp_detect(struct drm_connector *conn,
  169. bool force)
  170. {
  171. struct cdns_mhdp_device *mhdp = connector_to_mhdp(conn);
  172. int ret;
  173. ret = cdns_mhdp_get_hpd_status(mhdp);
  174. if (ret > 0) {
  175. mhdp->plugged = true;
  176. return connector_status_connected;
  177. }
  178. if (ret < 0)
  179. dev_err(mhdp->dev, "Failed to obtain HPD state\n");
  180. mhdp->plugged = false;
  181. return connector_status_disconnected;
  182. }
  183. static const struct drm_connector_funcs cdns_mhdp_conn_funcs = {
  184. .fill_modes = drm_helper_probe_single_connector_modes,
  185. .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
  186. .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
  187. .reset = drm_atomic_helper_connector_reset,
  188. .destroy = drm_connector_cleanup,
  189. .detect = cdns_mhdp_detect,
  190. };
  191. static int cdns_mhdp_attach(struct drm_bridge *bridge)
  192. {
  193. struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
  194. u32 bus_format = MEDIA_BUS_FMT_RGB121212_1X36;
  195. struct drm_connector *conn = &mhdp->connector.base;
  196. int ret;
  197. if (&mhdp->bridge.base != bridge)
  198. return -ENODEV;
  199. conn->polled = DRM_CONNECTOR_POLL_HPD;
  200. ret = drm_connector_init(bridge->dev, conn, &cdns_mhdp_conn_funcs,
  201. DRM_MODE_CONNECTOR_DisplayPort);
  202. if (ret) {
  203. dev_err(mhdp->dev, "failed to init connector\n");
  204. return ret;
  205. }
  206. drm_connector_helper_add(conn, &cdns_mhdp_conn_helper_funcs);
  207. ret = drm_display_info_set_bus_formats(&conn->display_info,
  208. &bus_format, 1);
  209. if (ret)
  210. return ret;
  211. conn->display_info.bus_flags = DRM_BUS_FLAG_DE_HIGH;
  212. /*
  213. * HACK: DP is internal to J7 SoC and we need to use DRIVE_POSEDGE
  214. * in the display controller. This is achieved for the time being
  215. * by defining SAMPLE_NEGEDGE here.
  216. */
  217. conn->display_info.bus_flags |= DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE |
  218. DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE;
  219. ret = drm_connector_attach_encoder(conn, bridge->encoder);
  220. if (ret) {
  221. dev_err(mhdp->dev, "failed to attach connector to encoder\n");
  222. return ret;
  223. }
  224. /* enable interrupts */
  225. //writel(~CDNS_APB_INT_MASK_SW_EVENT_INT, mhdp->regs + CDNS_APB_INT_MASK);
  226. writel(0, mhdp->regs + CDNS_APB_INT_MASK);
  227. writel(0, mhdp->regs + CDNS_MB_INT_MASK);
  228. return 0;
  229. }
  230. static void mhdp_link_training_init(struct cdns_mhdp_device *mhdp)
  231. {
  232. u32 reg32;
  233. u8 i;
  234. union phy_configure_opts phy_cfg;
  235. drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
  236. DP_TRAINING_PATTERN_DISABLE);
  237. /* Reset PHY configuration */
  238. reg32 = CDNS_PHY_COMMON_CONFIG | CDNS_PHY_TRAINING_TYPE(1);
  239. if (!(mhdp->host.lanes_cnt & CDNS_SCRAMBLER))
  240. reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
  241. cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
  242. cdns_mhdp_reg_write(mhdp, CDNS_DP_ENHNCD,
  243. mhdp->sink.enhanced & mhdp->host.enhanced);
  244. cdns_mhdp_reg_write(mhdp, CDNS_DP_LANE_EN,
  245. CDNS_DP_LANE_EN_LANES(mhdp->link.num_lanes));
  246. drm_dp_link_configure(&mhdp->aux, &mhdp->link);
  247. phy_cfg.dp.link_rate = (mhdp->link.rate / 100);
  248. phy_cfg.dp.lanes = (mhdp->link.num_lanes);
  249. for (i = 0; i < 4; i++) {
  250. phy_cfg.dp.voltage[i] = 0;
  251. phy_cfg.dp.pre[i] = 0;
  252. }
  253. phy_cfg.dp.ssc = false;
  254. phy_cfg.dp.set_lanes = true;
  255. phy_cfg.dp.set_rate = true;
  256. phy_cfg.dp.set_voltages = true;
  257. phy_configure(mhdp->phy, &phy_cfg);
  258. cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG,
  259. CDNS_PHY_COMMON_CONFIG |
  260. CDNS_PHY_TRAINING_EN |
  261. CDNS_PHY_TRAINING_TYPE(1) |
  262. CDNS_PHY_SCRAMBLER_BYPASS);
  263. drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
  264. DP_TRAINING_PATTERN_1 | DP_LINK_SCRAMBLING_DISABLE);
  265. }
  266. static void mhdp_get_adjust_train(struct cdns_mhdp_device *mhdp,
  267. u8 link_status[DP_LINK_STATUS_SIZE],
  268. u8 lanes_data[CDNS_DP_MAX_NUM_LANES],
  269. union phy_configure_opts *phy_cfg)
  270. {
  271. unsigned int i;
  272. u8 adjust, max_pre_emphasis, max_volt_swing;
  273. u8 set_volt, set_pre;
  274. max_pre_emphasis = CDNS_PRE_EMPHASIS(mhdp->host.pre_emphasis)
  275. << DP_TRAIN_PRE_EMPHASIS_SHIFT;
  276. max_volt_swing = CDNS_VOLT_SWING(mhdp->host.volt_swing);
  277. for (i = 0; i < mhdp->link.num_lanes; i++) {
  278. /* Check if Voltage swing and pre-emphasis are within limits */
  279. adjust = drm_dp_get_adjust_request_voltage(link_status, i);
  280. set_volt = min_t(u8, adjust, max_volt_swing);
  281. adjust = drm_dp_get_adjust_request_pre_emphasis(link_status, i);
  282. set_pre = min_t(u8, adjust, max_pre_emphasis) >> DP_TRAIN_PRE_EMPHASIS_SHIFT;
  283. /* Voltage swing level and pre-emphasis level combination is not allowed:
  284. * leaving pre-emphasis as-is, and adjusting voltage swing.
  285. */
  286. if (set_volt + set_pre > 3)
  287. set_volt = 3 - set_pre;
  288. phy_cfg->dp.voltage[i] = set_volt;
  289. lanes_data[i] = set_volt;
  290. if (set_volt == max_volt_swing)
  291. lanes_data[i] |= DP_TRAIN_MAX_SWING_REACHED;
  292. phy_cfg->dp.pre[i] = set_pre;
  293. lanes_data[i] |= (set_pre << DP_TRAIN_PRE_EMPHASIS_SHIFT);
  294. if (set_pre == (max_pre_emphasis >> DP_TRAIN_PRE_EMPHASIS_SHIFT))
  295. lanes_data[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
  296. }
  297. }
  298. static void mhdp_set_adjust_request_voltage(
  299. u8 link_status[DP_LINK_STATUS_SIZE], int lane, u8 volt)
  300. {
  301. int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
  302. int s = ((lane & 1) ?
  303. DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT :
  304. DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT);
  305. int idx = i - DP_LANE0_1_STATUS;
  306. link_status[idx] &= ~(DP_ADJUST_VOLTAGE_SWING_LANE0_MASK << s);
  307. link_status[idx] |= volt << s;
  308. }
  309. static void mhdp_set_adjust_request_pre_emphasis(
  310. u8 link_status[DP_LINK_STATUS_SIZE], int lane, u8 pre_emphasis)
  311. {
  312. int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
  313. int s = ((lane & 1) ?
  314. DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT :
  315. DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT);
  316. int idx = i - DP_LANE0_1_STATUS;
  317. link_status[idx] &= ~(DP_ADJUST_PRE_EMPHASIS_LANE0_MASK << s);
  318. link_status[idx] |= pre_emphasis << s;
  319. }
  320. static void mhdp_adjust_requested_eq(struct cdns_mhdp_device *mhdp,
  321. u8 link_status[DP_LINK_STATUS_SIZE])
  322. {
  323. unsigned int i;
  324. u8 volt, pre, max_volt = CDNS_VOLT_SWING(mhdp->host.volt_swing),
  325. max_pre = CDNS_PRE_EMPHASIS(mhdp->host.pre_emphasis);
  326. for (i = 0; i < mhdp->link.num_lanes; i++) {
  327. volt = drm_dp_get_adjust_request_voltage(link_status, i);
  328. pre = drm_dp_get_adjust_request_pre_emphasis(link_status, i);
  329. if (volt + pre > 3)
  330. mhdp_set_adjust_request_voltage(link_status, i,
  331. 3 - pre);
  332. if (mhdp->host.volt_swing & CDNS_FORCE_VOLT_SWING)
  333. mhdp_set_adjust_request_voltage(link_status, i,
  334. max_volt);
  335. if (mhdp->host.pre_emphasis & CDNS_FORCE_PRE_EMPHASIS)
  336. mhdp_set_adjust_request_pre_emphasis(link_status, i,
  337. max_pre);
  338. }
  339. }
  340. static bool mhdp_link_training_channel_eq(struct cdns_mhdp_device *mhdp,
  341. u8 eq_tps,
  342. unsigned int training_interval)
  343. {
  344. u8 lanes_data[CDNS_DP_MAX_NUM_LANES], fail_counter_short = 0;
  345. u8 dpcd[DP_LINK_STATUS_SIZE];
  346. u32 reg32;
  347. union phy_configure_opts phy_cfg;
  348. dev_dbg(mhdp->dev, "Link training - Starting EQ phase\n");
  349. /* Enable link training TPS[eq_tps] in PHY */
  350. reg32 = CDNS_PHY_COMMON_CONFIG | CDNS_PHY_TRAINING_EN |
  351. CDNS_PHY_TRAINING_TYPE(eq_tps);
  352. if (eq_tps != 4)
  353. reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
  354. cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
  355. drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
  356. (eq_tps != 4) ? eq_tps | DP_LINK_SCRAMBLING_DISABLE :
  357. CDNS_DP_TRAINING_PATTERN_4);
  358. drm_dp_dpcd_read_link_status(&mhdp->aux, dpcd);
  359. do {
  360. mhdp_get_adjust_train(mhdp, dpcd, lanes_data, &phy_cfg);
  361. phy_cfg.dp.lanes = (mhdp->link.num_lanes);
  362. phy_cfg.dp.ssc = false;
  363. phy_cfg.dp.set_lanes = false;
  364. phy_cfg.dp.set_rate = false;
  365. phy_cfg.dp.set_voltages = true;
  366. phy_configure(mhdp->phy, &phy_cfg);
  367. cdns_mhdp_adjust_lt(mhdp, mhdp->link.num_lanes,
  368. training_interval, lanes_data, dpcd);
  369. if (!drm_dp_clock_recovery_ok(dpcd, mhdp->link.num_lanes))
  370. goto err;
  371. if (drm_dp_channel_eq_ok(dpcd, mhdp->link.num_lanes)) {
  372. dev_dbg(mhdp->dev,
  373. "Link training: EQ phase succeeded\n");
  374. return true;
  375. }
  376. fail_counter_short++;
  377. mhdp_adjust_requested_eq(mhdp, dpcd);
  378. } while (fail_counter_short < 5);
  379. err:
  380. dev_dbg(mhdp->dev,
  381. "Link training - EQ phase failed for %d lanes and %d rate\n",
  382. mhdp->link.num_lanes, mhdp->link.rate);
  383. return false;
  384. }
  385. static void mhdp_adjust_requested_cr(struct cdns_mhdp_device *mhdp,
  386. u8 link_status[DP_LINK_STATUS_SIZE],
  387. u8 *req_volt, u8 *req_pre)
  388. {
  389. const u32 max_volt = CDNS_VOLT_SWING(mhdp->host.volt_swing),
  390. max_pre = CDNS_PRE_EMPHASIS(mhdp->host.pre_emphasis);
  391. unsigned int i;
  392. for (i = 0; i < mhdp->link.num_lanes; i++) {
  393. unsigned int val;
  394. val = mhdp->host.volt_swing & CDNS_FORCE_VOLT_SWING ?
  395. max_volt : req_volt[i];
  396. mhdp_set_adjust_request_voltage(link_status, i, val);
  397. val = mhdp->host.pre_emphasis & CDNS_FORCE_PRE_EMPHASIS ?
  398. max_pre : req_pre[i];
  399. mhdp_set_adjust_request_pre_emphasis(link_status, i, val);
  400. }
  401. }
  402. static void mhdp_validate_cr(struct cdns_mhdp_device *mhdp, bool *cr_done,
  403. bool *same_before_adjust, bool *max_swing_reached,
  404. u8 before_cr[DP_LINK_STATUS_SIZE],
  405. u8 after_cr[DP_LINK_STATUS_SIZE], u8 *req_volt,
  406. u8 *req_pre)
  407. {
  408. const u8 max_volt = CDNS_VOLT_SWING(mhdp->host.volt_swing),
  409. max_pre = CDNS_PRE_EMPHASIS(mhdp->host.pre_emphasis);
  410. bool same_pre, same_volt;
  411. unsigned int i;
  412. *same_before_adjust = false;
  413. *max_swing_reached = false;
  414. *cr_done = drm_dp_clock_recovery_ok(after_cr, mhdp->link.num_lanes);
  415. for (i = 0; i < mhdp->link.num_lanes; i++) {
  416. u8 tmp;
  417. tmp = drm_dp_get_adjust_request_voltage(after_cr, i);
  418. req_volt[i] = min_t(u8, tmp, max_volt);
  419. tmp = drm_dp_get_adjust_request_pre_emphasis(after_cr, i) >>
  420. DP_TRAIN_PRE_EMPHASIS_SHIFT;
  421. req_pre[i] = min_t(u8, tmp, max_pre);
  422. same_pre = (before_cr[i] & DP_TRAIN_PRE_EMPHASIS_MASK) ==
  423. req_pre[i] << DP_TRAIN_PRE_EMPHASIS_SHIFT;
  424. same_volt = (before_cr[i] & DP_TRAIN_VOLTAGE_SWING_MASK) ==
  425. req_volt[i];
  426. if (same_pre && same_volt)
  427. *same_before_adjust = true;
  428. /* 3.1.5.2 in DP Standard v1.4. Table 3-1 */
  429. if (!*cr_done && req_volt[i] + req_pre[i] >= 3) {
  430. *max_swing_reached = true;
  431. return;
  432. }
  433. }
  434. }
  435. static bool mhdp_link_training_clock_recovery(struct cdns_mhdp_device *mhdp)
  436. {
  437. u8 lanes_data[CDNS_DP_MAX_NUM_LANES],
  438. fail_counter_short = 0, fail_counter_cr_long = 0;
  439. u8 dpcd[DP_LINK_STATUS_SIZE];
  440. bool cr_done;
  441. union phy_configure_opts phy_cfg;
  442. dev_dbg(mhdp->dev, "Link training starting CR phase\n");
  443. mhdp_link_training_init(mhdp);
  444. drm_dp_dpcd_read_link_status(&mhdp->aux, dpcd);
  445. do {
  446. u8 requested_adjust_volt_swing[CDNS_DP_MAX_NUM_LANES] = {},
  447. requested_adjust_pre_emphasis[CDNS_DP_MAX_NUM_LANES] = {};
  448. bool same_before_adjust, max_swing_reached;
  449. mhdp_get_adjust_train(mhdp, dpcd, lanes_data, &phy_cfg);
  450. phy_cfg.dp.lanes = (mhdp->link.num_lanes);
  451. phy_cfg.dp.ssc = false;
  452. phy_cfg.dp.set_lanes = false;
  453. phy_cfg.dp.set_rate = false;
  454. phy_cfg.dp.set_voltages = true;
  455. phy_configure(mhdp->phy, &phy_cfg);
  456. cdns_mhdp_adjust_lt(mhdp, mhdp->link.num_lanes, 100,
  457. lanes_data, dpcd);
  458. mhdp_validate_cr(mhdp, &cr_done, &same_before_adjust,
  459. &max_swing_reached, lanes_data, dpcd,
  460. requested_adjust_volt_swing,
  461. requested_adjust_pre_emphasis);
  462. if (max_swing_reached) {
  463. dev_err(mhdp->dev, "CR: max swing reached\n");
  464. goto err;
  465. }
  466. if (cr_done) {
  467. dev_dbg(mhdp->dev,
  468. "Link training: CR phase succeeded\n");
  469. return true;
  470. }
  471. /* Not all CR_DONE bits set */
  472. fail_counter_cr_long++;
  473. if (same_before_adjust) {
  474. fail_counter_short++;
  475. continue;
  476. }
  477. fail_counter_short = 0;
  478. /*
  479. * Voltage swing/pre-emphasis adjust requested
  480. * during CR phase
  481. */
  482. mhdp_adjust_requested_cr(mhdp, dpcd,
  483. requested_adjust_volt_swing,
  484. requested_adjust_pre_emphasis);
  485. } while (fail_counter_short < 5 && fail_counter_cr_long < 10);
  486. err:
  487. dev_dbg(mhdp->dev,
  488. "Link training: CR phase failed for %d lanes and %d rate\n",
  489. mhdp->link.num_lanes, mhdp->link.rate);
  490. return false;
  491. }
  492. static void lower_link_rate(struct drm_dp_link *link)
  493. {
  494. switch (drm_dp_link_rate_to_bw_code(link->rate)) {
  495. case DP_LINK_BW_2_7:
  496. link->rate = drm_dp_bw_code_to_link_rate(DP_LINK_BW_1_62);
  497. break;
  498. case DP_LINK_BW_5_4:
  499. link->rate = drm_dp_bw_code_to_link_rate(DP_LINK_BW_2_7);
  500. break;
  501. case DP_LINK_BW_8_1:
  502. link->rate = drm_dp_bw_code_to_link_rate(DP_LINK_BW_5_4);
  503. break;
  504. }
  505. }
  506. static int mhdp_link_training(struct cdns_mhdp_device *mhdp,
  507. unsigned int video_mode,
  508. unsigned int training_interval)
  509. {
  510. u32 reg32;
  511. union phy_configure_opts phy_cfg;
  512. const u8 eq_tps = eq_training_pattern_supported(mhdp->host, mhdp->sink);
  513. while (1) {
  514. if (!mhdp_link_training_clock_recovery(mhdp)) {
  515. if (drm_dp_link_rate_to_bw_code(mhdp->link.rate) !=
  516. DP_LINK_BW_1_62) {
  517. dev_dbg(mhdp->dev,
  518. "Reducing link rate during CR phase\n");
  519. lower_link_rate(&mhdp->link);
  520. drm_dp_link_configure(&mhdp->aux, &mhdp->link);
  521. phy_cfg.dp.link_rate = (mhdp->link.rate / 100);
  522. phy_cfg.dp.lanes = (mhdp->link.num_lanes);
  523. phy_cfg.dp.ssc = false;
  524. phy_cfg.dp.set_lanes = false;
  525. phy_cfg.dp.set_rate = true;
  526. phy_cfg.dp.set_voltages = false;
  527. phy_configure(mhdp->phy, &phy_cfg);
  528. continue;
  529. } else if (mhdp->link.num_lanes > 1) {
  530. dev_dbg(mhdp->dev,
  531. "Reducing lanes number during CR phase\n");
  532. mhdp->link.num_lanes >>= 1;
  533. mhdp->link.rate = max_link_rate(mhdp->host,
  534. mhdp->sink);
  535. drm_dp_link_configure(&mhdp->aux, &mhdp->link);
  536. phy_cfg.dp.link_rate = (mhdp->link.rate / 100);
  537. phy_cfg.dp.lanes = (mhdp->link.num_lanes);
  538. phy_cfg.dp.ssc = false;
  539. phy_cfg.dp.set_lanes = true;
  540. phy_cfg.dp.set_rate = false;
  541. phy_cfg.dp.set_voltages = false;
  542. phy_configure(mhdp->phy, &phy_cfg);
  543. continue;
  544. }
  545. dev_dbg(mhdp->dev,
  546. "Link training failed during CR phase\n");
  547. goto err;
  548. }
  549. if (mhdp_link_training_channel_eq(mhdp, eq_tps,
  550. training_interval))
  551. break;
  552. if (mhdp->link.num_lanes > 1) {
  553. dev_dbg(mhdp->dev,
  554. "Reducing lanes number during EQ phase\n");
  555. mhdp->link.num_lanes >>= 1;
  556. drm_dp_link_configure(&mhdp->aux, &mhdp->link);
  557. phy_cfg.dp.link_rate = (mhdp->link.rate / 100);
  558. phy_cfg.dp.lanes = (mhdp->link.num_lanes);
  559. phy_cfg.dp.ssc = false;
  560. phy_cfg.dp.set_lanes = true;
  561. phy_cfg.dp.set_rate = false;
  562. phy_cfg.dp.set_voltages = false;
  563. phy_configure(mhdp->phy, &phy_cfg);
  564. continue;
  565. } else if (drm_dp_link_rate_to_bw_code(mhdp->link.rate) !=
  566. DP_LINK_BW_1_62) {
  567. dev_dbg(mhdp->dev,
  568. "Reducing link rate during EQ phase\n");
  569. lower_link_rate(&mhdp->link);
  570. drm_dp_link_configure(&mhdp->aux, &mhdp->link);
  571. phy_cfg.dp.link_rate = (mhdp->link.rate / 100);
  572. phy_cfg.dp.lanes = (mhdp->link.num_lanes);
  573. phy_cfg.dp.ssc = false;
  574. phy_cfg.dp.set_lanes = false;
  575. phy_cfg.dp.set_rate = true;
  576. phy_cfg.dp.set_voltages = false;
  577. phy_configure(mhdp->phy, &phy_cfg);
  578. continue;
  579. }
  580. dev_dbg(mhdp->dev, "Link training failed during EQ phase\n");
  581. goto err;
  582. }
  583. dev_dbg(mhdp->dev, "Link training successful\n");
  584. drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
  585. (mhdp->host.lanes_cnt & CDNS_SCRAMBLER) ? 0 :
  586. DP_LINK_SCRAMBLING_DISABLE);
  587. /* SW reset DPTX framer */
  588. cdns_mhdp_reg_write(mhdp, CDNS_DP_SW_RESET, 1);
  589. cdns_mhdp_reg_write(mhdp, CDNS_DP_SW_RESET, 0);
  590. cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG,
  591. CDNS_DP_NUM_LANES(mhdp->link.num_lanes) |
  592. CDNS_DP_DISABLE_PHY_RST |
  593. CDNS_DP_WR_FAILING_EDGE_VSYNC |
  594. (!video_mode ? CDNS_DP_NO_VIDEO_MODE : 0));
  595. /* Reset PHY config */
  596. reg32 = CDNS_PHY_COMMON_CONFIG | CDNS_PHY_TRAINING_TYPE(1);
  597. if (!(mhdp->host.lanes_cnt & CDNS_SCRAMBLER))
  598. reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
  599. cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
  600. return 0;
  601. err:
  602. /* Reset PHY config */
  603. reg32 = CDNS_PHY_COMMON_CONFIG | CDNS_PHY_TRAINING_TYPE(1);
  604. if (!(mhdp->host.lanes_cnt & CDNS_SCRAMBLER))
  605. reg32 |= CDNS_PHY_SCRAMBLER_BYPASS;
  606. cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG, reg32);
  607. drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
  608. DP_TRAINING_PATTERN_DISABLE);
  609. return -EIO;
  610. }
  611. static void cdns_mhdp_disable(struct drm_bridge *bridge)
  612. {
  613. struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
  614. dev_dbg(mhdp->dev, "bridge disable\n");
  615. cdns_mhdp_set_video_status(mhdp, 0);
  616. mhdp->link_up = false;
  617. if (mhdp->plugged)
  618. drm_dp_link_power_down(&mhdp->aux, &mhdp->link);
  619. cdns_mhdp_j721e_disable(mhdp);
  620. }
  621. static u32 get_training_interval_us(struct cdns_mhdp_device *mhdp,
  622. u32 interval)
  623. {
  624. if (interval == 0)
  625. return 400;
  626. if (interval < 5)
  627. return 4000 << (interval - 1);
  628. dev_err(mhdp->dev,
  629. "wrong training interval returned by DPCD: %d\n", interval);
  630. return 0;
  631. }
  632. static int cdns_mhdp_link_up(struct cdns_mhdp_device *mhdp)
  633. {
  634. u32 resp, dp_framer_global_config, video_mode;
  635. u8 reg0[DP_RECEIVER_CAP_SIZE], amp[2];
  636. /*
  637. * Upon power-on reset/device disconnection: [2:0] bits should be 0b001
  638. * and [7:5] bits 0b000.
  639. */
  640. drm_dp_dpcd_writeb(&mhdp->aux, DP_SET_POWER, 1);
  641. drm_dp_link_probe(&mhdp->aux, &mhdp->link);
  642. dev_dbg(mhdp->dev, "Set sink device power state via DPCD\n");
  643. drm_dp_link_power_up(&mhdp->aux, &mhdp->link);
  644. /* FIXME (CDNS): do we have to wait for 100ms before going on? */
  645. mdelay(100);
  646. mhdp->sink.link_rate = mhdp->link.rate;
  647. mhdp->sink.lanes_cnt = mhdp->link.num_lanes;
  648. mhdp->sink.enhanced = !!(mhdp->link.capabilities &
  649. DP_LINK_CAP_ENHANCED_FRAMING);
  650. drm_dp_dpcd_read(&mhdp->aux, DP_DPCD_REV, reg0, DP_RECEIVER_CAP_SIZE);
  651. mhdp->sink.pattern_supp = CDNS_SUPPORT_TPS(1) | CDNS_SUPPORT_TPS(2);
  652. if (drm_dp_tps3_supported(reg0))
  653. mhdp->sink.pattern_supp |= CDNS_SUPPORT_TPS(3);
  654. if (drm_dp_tps4_supported(reg0))
  655. mhdp->sink.pattern_supp |= CDNS_SUPPORT_TPS(4);
  656. mhdp->sink.fast_link = !!(reg0[DP_MAX_DOWNSPREAD] &
  657. DP_NO_AUX_HANDSHAKE_LINK_TRAINING);
  658. mhdp->link.rate = max_link_rate(mhdp->host, mhdp->sink);
  659. mhdp->link.num_lanes = min_t(u8, mhdp->sink.lanes_cnt,
  660. mhdp->host.lanes_cnt & GENMASK(2, 0));
  661. cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &resp);
  662. dp_framer_global_config = be32_to_cpu(resp);
  663. video_mode = !(dp_framer_global_config & CDNS_DP_NO_VIDEO_MODE);
  664. if (dp_framer_global_config & CDNS_DP_FRAMER_EN)
  665. cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG,
  666. dp_framer_global_config &
  667. ~CDNS_DP_FRAMER_EN);
  668. /* Spread AMP if required, enable 8b/10b coding */
  669. amp[0] = (mhdp->host.lanes_cnt & CDNS_SSC) ? DP_SPREAD_AMP_0_5 : 0;
  670. amp[1] = DP_SET_ANSI_8B10B;
  671. drm_dp_dpcd_write(&mhdp->aux, DP_DOWNSPREAD_CTRL, amp, 2);
  672. if (mhdp->host.fast_link & mhdp->sink.fast_link) {
  673. /* FIXME: implement fastlink */
  674. dev_dbg(mhdp->dev, "fastlink\n");
  675. } else {
  676. const u32 interval = reg0[DP_TRAINING_AUX_RD_INTERVAL] &
  677. DP_TRAINING_AUX_RD_MASK;
  678. const u32 interval_us = get_training_interval_us(mhdp,
  679. interval);
  680. if (!interval_us ||
  681. mhdp_link_training(mhdp, video_mode, interval_us)) {
  682. dev_err(mhdp->dev, "Link training failed. Exiting.\n");
  683. return -EIO;
  684. }
  685. }
  686. mhdp->link_up = true;
  687. return 0;
  688. }
  689. u32 cdns_mhdp_get_bpp(struct cdns_mhdp_display_fmt *fmt)
  690. {
  691. u32 bpp;
  692. if (fmt->y_only)
  693. return fmt->bpc;
  694. switch (fmt->color_format) {
  695. case DRM_COLOR_FORMAT_RGB444:
  696. case DRM_COLOR_FORMAT_YCRCB444:
  697. bpp = fmt->bpc * 3;
  698. break;
  699. case DRM_COLOR_FORMAT_YCRCB422:
  700. bpp = fmt->bpc * 2;
  701. break;
  702. case DRM_COLOR_FORMAT_YCRCB420:
  703. bpp = fmt->bpc * 3 / 2;
  704. break;
  705. default:
  706. bpp = fmt->bpc * 3;
  707. WARN_ON(1);
  708. }
  709. return bpp;
  710. }
  711. static int cdns_mhdp_sst_enable(struct drm_bridge *bridge)
  712. {
  713. struct cdns_mhdp_bridge *mhdp_bridge = to_mhdp_bridge(bridge);
  714. struct cdns_mhdp_device *mhdp = mhdp_bridge->mhdp;
  715. u32 rate, vs, vs_f, required_bandwidth, available_bandwidth;
  716. u32 tu_size = 30, line_thresh1, line_thresh2, line_thresh = 0;
  717. struct drm_display_mode *mode;
  718. int pxlclock;
  719. u32 bpp, bpc, pxlfmt;
  720. pxlfmt = mhdp->display_fmt.color_format;
  721. bpc = mhdp->display_fmt.bpc;
  722. mode = &bridge->encoder->crtc->state->mode;
  723. pxlclock = mode->crtc_clock;
  724. mhdp_bridge->stream_id = 0;
  725. rate = mhdp->link.rate / 1000;
  726. bpp = cdns_mhdp_get_bpp(&mhdp->display_fmt);
  727. /* find optimal tu_size */
  728. required_bandwidth = pxlclock * bpp / 8;
  729. available_bandwidth = mhdp->link.num_lanes * rate;
  730. do {
  731. tu_size += 2;
  732. vs_f = tu_size * required_bandwidth / available_bandwidth;
  733. vs = vs_f / 1000;
  734. vs_f = vs_f % 1000;
  735. /*
  736. * FIXME (CDNS): downspreading?
  737. * It's unused is what I've been told.
  738. */
  739. } while ((vs == 1 || ((vs_f > 850 || vs_f < 100) && vs_f != 0) ||
  740. tu_size - vs < 2) && tu_size < 64);
  741. if (vs > 64)
  742. return -EINVAL;
  743. cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_TU,
  744. CDNS_DP_FRAMER_TU_VS(vs) |
  745. CDNS_DP_FRAMER_TU_SIZE(tu_size) |
  746. CDNS_DP_FRAMER_TU_CNT_RST_EN);
  747. line_thresh1 = ((vs + 1) << 5) * 8 / bpp;
  748. line_thresh2 = (pxlclock << 5) / 1000 / rate * (vs + 1) - (1 << 5);
  749. line_thresh = line_thresh1 - line_thresh2 / mhdp->link.num_lanes;
  750. line_thresh = (line_thresh >> 5) + 2;
  751. cdns_mhdp_reg_write(mhdp, CDNS_DP_LINE_THRESH(0),
  752. line_thresh & GENMASK(5, 0));
  753. cdns_mhdp_reg_write(mhdp, CDNS_DP_STREAM_CONFIG_2(0),
  754. CDNS_DP_SC2_TU_VS_DIFF((tu_size - vs > 3) ?
  755. 0 : tu_size - vs));
  756. cdns_mhdp_configure_video(bridge);
  757. cdns_mhdp_set_video_status(mhdp, 1);
  758. return 0;
  759. }
  760. void cdns_mhdp_configure_video(struct drm_bridge *bridge)
  761. {
  762. struct cdns_mhdp_bridge *mhdp_bridge = to_mhdp_bridge(bridge);
  763. struct cdns_mhdp_device *mhdp = mhdp_bridge->mhdp;
  764. unsigned int dp_framer_sp = 0, msa_horizontal_1,
  765. msa_vertical_1, bnd_hsync2vsync, hsync2vsync_pol_ctrl,
  766. misc0 = 0, misc1 = 0, pxl_repr,
  767. front_porch, back_porch, msa_h0, msa_v0, hsync, vsync,
  768. dp_vertical_1;
  769. struct drm_display_mode *mode;
  770. u32 bpp, bpc, pxlfmt;
  771. u32 tmp;
  772. u8 stream_id = mhdp_bridge->stream_id;
  773. mode = &bridge->encoder->crtc->state->mode;
  774. pxlfmt = mhdp->display_fmt.color_format;
  775. bpc = mhdp->display_fmt.bpc;
  776. /* if YCBCR supported and stream not SD, use ITU709 */
  777. /* FIXME: handle ITU version with YCBCR420 when supported */
  778. if ((pxlfmt == DRM_COLOR_FORMAT_YCRCB444 ||
  779. pxlfmt == DRM_COLOR_FORMAT_YCRCB422) && mode->crtc_vdisplay >= 720)
  780. misc0 = DP_YCBCR_COEFFICIENTS_ITU709;
  781. bpp = cdns_mhdp_get_bpp(&mhdp->display_fmt);
  782. switch (pxlfmt) {
  783. case DRM_COLOR_FORMAT_RGB444:
  784. pxl_repr = CDNS_DP_FRAMER_RGB << CDNS_DP_FRAMER_PXL_FORMAT;
  785. misc0 |= DP_COLOR_FORMAT_RGB;
  786. break;
  787. case DRM_COLOR_FORMAT_YCRCB444:
  788. pxl_repr = CDNS_DP_FRAMER_YCBCR444 << CDNS_DP_FRAMER_PXL_FORMAT;
  789. misc0 |= DP_COLOR_FORMAT_YCbCr444 | DP_TEST_DYNAMIC_RANGE_CEA;
  790. break;
  791. case DRM_COLOR_FORMAT_YCRCB422:
  792. pxl_repr = CDNS_DP_FRAMER_YCBCR422 << CDNS_DP_FRAMER_PXL_FORMAT;
  793. misc0 |= DP_COLOR_FORMAT_YCbCr422 | DP_TEST_DYNAMIC_RANGE_CEA;
  794. break;
  795. case DRM_COLOR_FORMAT_YCRCB420:
  796. pxl_repr = CDNS_DP_FRAMER_YCBCR420 << CDNS_DP_FRAMER_PXL_FORMAT;
  797. break;
  798. default:
  799. pxl_repr = CDNS_DP_FRAMER_Y_ONLY << CDNS_DP_FRAMER_PXL_FORMAT;
  800. }
  801. switch (bpc) {
  802. case 6:
  803. misc0 |= DP_TEST_BIT_DEPTH_6;
  804. pxl_repr |= CDNS_DP_FRAMER_6_BPC;
  805. break;
  806. case 8:
  807. misc0 |= DP_TEST_BIT_DEPTH_8;
  808. pxl_repr |= CDNS_DP_FRAMER_8_BPC;
  809. break;
  810. case 10:
  811. misc0 |= DP_TEST_BIT_DEPTH_10;
  812. pxl_repr |= CDNS_DP_FRAMER_10_BPC;
  813. break;
  814. case 12:
  815. misc0 |= DP_TEST_BIT_DEPTH_12;
  816. pxl_repr |= CDNS_DP_FRAMER_12_BPC;
  817. break;
  818. case 16:
  819. misc0 |= DP_TEST_BIT_DEPTH_16;
  820. pxl_repr |= CDNS_DP_FRAMER_16_BPC;
  821. break;
  822. }
  823. bnd_hsync2vsync = CDNS_IP_BYPASS_V_INTERFACE;
  824. if (mode->flags & DRM_MODE_FLAG_INTERLACE)
  825. bnd_hsync2vsync |= CDNS_IP_DET_INTERLACE_FORMAT;
  826. cdns_mhdp_reg_write(mhdp, CDNS_BND_HSYNC2VSYNC(stream_id),
  827. bnd_hsync2vsync);
  828. if (mode->flags & DRM_MODE_FLAG_INTERLACE &&
  829. mode->flags & DRM_MODE_FLAG_PHSYNC)
  830. hsync2vsync_pol_ctrl = CDNS_H2V_HSYNC_POL_ACTIVE_LOW |
  831. CDNS_H2V_VSYNC_POL_ACTIVE_LOW;
  832. else
  833. hsync2vsync_pol_ctrl = 0;
  834. cdns_mhdp_reg_write(mhdp, CDNS_HSYNC2VSYNC_POL_CTRL(stream_id),
  835. hsync2vsync_pol_ctrl);
  836. cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_PXL_REPR(stream_id), pxl_repr);
  837. if (mode->flags & DRM_MODE_FLAG_INTERLACE)
  838. dp_framer_sp |= CDNS_DP_FRAMER_INTERLACE;
  839. if (mode->flags & DRM_MODE_FLAG_NHSYNC)
  840. dp_framer_sp |= CDNS_DP_FRAMER_HSYNC_POL_LOW;
  841. if (mode->flags & DRM_MODE_FLAG_NVSYNC)
  842. dp_framer_sp |= CDNS_DP_FRAMER_VSYNC_POL_LOW;
  843. cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_SP(stream_id), dp_framer_sp);
  844. front_porch = mode->crtc_hsync_start - mode->crtc_hdisplay;
  845. back_porch = mode->crtc_htotal - mode->crtc_hsync_end;
  846. cdns_mhdp_reg_write(mhdp, CDNS_DP_FRONT_BACK_PORCH(stream_id),
  847. CDNS_DP_FRONT_PORCH(front_porch) |
  848. CDNS_DP_BACK_PORCH(back_porch));
  849. cdns_mhdp_reg_write(mhdp, CDNS_DP_BYTE_COUNT(stream_id),
  850. mode->crtc_hdisplay * bpp / 8);
  851. msa_h0 = mode->crtc_htotal - mode->crtc_hsync_start;
  852. cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_HORIZONTAL_0(stream_id),
  853. CDNS_DP_MSAH0_H_TOTAL(mode->crtc_htotal) |
  854. CDNS_DP_MSAH0_HSYNC_START(msa_h0));
  855. hsync = mode->crtc_hsync_end - mode->crtc_hsync_start;
  856. msa_horizontal_1 = CDNS_DP_MSAH1_HSYNC_WIDTH(hsync) |
  857. CDNS_DP_MSAH1_HDISP_WIDTH(mode->crtc_hdisplay);
  858. if (mode->flags & DRM_MODE_FLAG_NHSYNC)
  859. msa_horizontal_1 |= CDNS_DP_MSAH1_HSYNC_POL_LOW;
  860. cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_HORIZONTAL_1(stream_id),
  861. msa_horizontal_1);
  862. msa_v0 = mode->crtc_vtotal - mode->crtc_vsync_start;
  863. cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_VERTICAL_0(stream_id),
  864. CDNS_DP_MSAV0_V_TOTAL(mode->crtc_vtotal) |
  865. CDNS_DP_MSAV0_VSYNC_START(msa_v0));
  866. vsync = mode->crtc_vsync_end - mode->crtc_vsync_start;
  867. msa_vertical_1 = CDNS_DP_MSAV1_VSYNC_WIDTH(vsync) |
  868. CDNS_DP_MSAV1_VDISP_WIDTH(mode->crtc_vdisplay);
  869. if (mode->flags & DRM_MODE_FLAG_NVSYNC)
  870. msa_vertical_1 |= CDNS_DP_MSAV1_VSYNC_POL_LOW;
  871. cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_VERTICAL_1(stream_id),
  872. msa_vertical_1);
  873. if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
  874. mode->crtc_vtotal % 2 == 0)
  875. misc1 = DP_TEST_INTERLACED;
  876. if (mhdp->display_fmt.y_only)
  877. misc1 |= CDNS_DP_TEST_COLOR_FORMAT_RAW_Y_ONLY;
  878. /* FIXME: use VSC SDP for Y420 */
  879. /* FIXME: (CDNS) no code for Y420 in bare metal test */
  880. if (pxlfmt == DRM_COLOR_FORMAT_YCRCB420)
  881. misc1 = CDNS_DP_TEST_VSC_SDP;
  882. cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_MISC(stream_id),
  883. misc0 | (misc1 << 8));
  884. cdns_mhdp_reg_write(mhdp, CDNS_DP_HORIZONTAL(stream_id),
  885. CDNS_DP_H_HSYNC_WIDTH(hsync) |
  886. CDNS_DP_H_H_TOTAL(mode->crtc_hdisplay));
  887. cdns_mhdp_reg_write(mhdp, CDNS_DP_VERTICAL_0(stream_id),
  888. CDNS_DP_V0_VHEIGHT(mode->crtc_vdisplay) |
  889. CDNS_DP_V0_VSTART(msa_v0));
  890. dp_vertical_1 = CDNS_DP_V1_VTOTAL(mode->crtc_vtotal);
  891. if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
  892. mode->crtc_vtotal % 2 == 0)
  893. dp_vertical_1 |= CDNS_DP_V1_VTOTAL_EVEN;
  894. cdns_mhdp_reg_write(mhdp, CDNS_DP_VERTICAL_1(stream_id), dp_vertical_1);
  895. cdns_mhdp_reg_write_bit(mhdp, CDNS_DP_VB_ID(stream_id), 2, 1,
  896. (mode->flags & DRM_MODE_FLAG_INTERLACE) ?
  897. CDNS_DP_VB_ID_INTERLACED : 0);
  898. cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &tmp);
  899. tmp |= CDNS_DP_FRAMER_EN;
  900. cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, tmp);
  901. }
  902. void cdns_mhdp_enable(struct drm_bridge *bridge)
  903. {
  904. struct cdns_mhdp_bridge *mhdp_bridge = to_mhdp_bridge(bridge);
  905. struct cdns_mhdp_device *mhdp = mhdp_bridge->mhdp;
  906. dev_dbg(mhdp->dev, "bridge enable\n");
  907. cdns_mhdp_j721e_enable(mhdp);
  908. if (!mhdp->link_up)
  909. cdns_mhdp_link_up(mhdp);
  910. cdns_mhdp_sst_enable(bridge);
  911. }
  912. static void cdns_mhdp_detach(struct drm_bridge *bridge)
  913. {
  914. struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
  915. writel(~0, mhdp->regs + CDNS_APB_INT_MASK);
  916. writel(~0, mhdp->regs + CDNS_MB_INT_MASK);
  917. }
  918. static bool cdns_mhdp_mode_fixup(struct drm_bridge *bridge,
  919. const struct drm_display_mode *mode,
  920. struct drm_display_mode *adj)
  921. {
  922. /* Fixup sync polarities, both hsync and vsync are active high */
  923. adj->flags = mode->flags;
  924. adj->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
  925. adj->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
  926. return true;
  927. }
  928. static const struct drm_bridge_funcs cdns_mhdp_bridge_funcs = {
  929. .enable = cdns_mhdp_enable,
  930. .disable = cdns_mhdp_disable,
  931. .attach = cdns_mhdp_attach,
  932. .detach = cdns_mhdp_detach,
  933. .mode_fixup = cdns_mhdp_mode_fixup,
  934. };
  935. static int load_firmware(struct cdns_mhdp_device *mhdp, const char *name,
  936. unsigned int addr)
  937. {
  938. const struct firmware *fw;
  939. int ret;
  940. ret = request_firmware(&fw, name, mhdp->dev);
  941. if (ret) {
  942. dev_err(mhdp->dev, "failed to load firmware (%s), ret: %d\n",
  943. name, ret);
  944. return ret;
  945. }
  946. memcpy_toio(mhdp->regs + addr, fw->data, fw->size);
  947. release_firmware(fw);
  948. return 0;
  949. }
  950. static int cdns_mhdp_audio_hw_params(struct device *dev, void *data,
  951. struct hdmi_codec_daifmt *daifmt,
  952. struct hdmi_codec_params *params)
  953. {
  954. struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev);
  955. struct audio_info audio = {
  956. .sample_width = params->sample_width,
  957. .sample_rate = params->sample_rate,
  958. .channels = params->channels,
  959. };
  960. int ret;
  961. if (daifmt->fmt != HDMI_I2S) {
  962. DRM_DEV_ERROR(dev, "Invalid format %d\n", daifmt->fmt);
  963. return -EINVAL;
  964. }
  965. audio.format = AFMT_I2S;
  966. ret = cdns_mhdp_audio_config(mhdp, &audio);
  967. if (!ret)
  968. mhdp->audio_info = audio;
  969. return 0;
  970. }
  971. static void cdns_mhdp_audio_shutdown(struct device *dev, void *data)
  972. {
  973. struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev);
  974. int ret;
  975. ret = cdns_mhdp_audio_stop(mhdp, &mhdp->audio_info);
  976. if (!ret)
  977. mhdp->audio_info.format = AFMT_UNUSED;
  978. }
  979. static int cdns_mhdp_audio_digital_mute(struct device *dev, void *data,
  980. bool enable)
  981. {
  982. struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev);
  983. return cdns_mhdp_audio_mute(mhdp, enable);
  984. }
  985. static int cdns_mhdp_audio_get_eld(struct device *dev, void *data,
  986. u8 *buf, size_t len)
  987. {
  988. struct cdns_mhdp_device *mhdp = dev_get_drvdata(dev);
  989. memcpy(buf, mhdp->connector.base.eld,
  990. min(sizeof(mhdp->connector.base.eld), len));
  991. return 0;
  992. }
  993. static const struct hdmi_codec_ops audio_codec_ops = {
  994. .hw_params = cdns_mhdp_audio_hw_params,
  995. .audio_shutdown = cdns_mhdp_audio_shutdown,
  996. .digital_mute = cdns_mhdp_audio_digital_mute,
  997. .get_eld = cdns_mhdp_audio_get_eld,
  998. };
  999. static int mhdp_probe(struct platform_device *pdev)
  1000. {
  1001. struct resource *regs;
  1002. struct cdns_mhdp_device *mhdp;
  1003. struct clk *clk;
  1004. int ret;
  1005. unsigned int reg;
  1006. unsigned long rate;
  1007. u32 resp;
  1008. int irq;
  1009. u32 lanes_prop;
  1010. struct hdmi_codec_pdata codec_data = {
  1011. .i2s = 1,
  1012. .max_i2s_channels = 8,
  1013. .ops = &audio_codec_ops,
  1014. };
  1015. mhdp = devm_kzalloc(&pdev->dev, sizeof(struct cdns_mhdp_device),
  1016. GFP_KERNEL);
  1017. if (!mhdp)
  1018. return -ENOMEM;
  1019. clk = devm_clk_get(&pdev->dev, NULL);
  1020. if (IS_ERR(clk)) {
  1021. dev_err(&pdev->dev, "couldn't get clk: %ld\n", PTR_ERR(clk));
  1022. return PTR_ERR(clk);
  1023. }
  1024. mhdp->clk = clk;
  1025. mhdp->dev = &pdev->dev;
  1026. dev_set_drvdata(&pdev->dev, mhdp);
  1027. drm_dp_aux_init(&mhdp->aux);
  1028. mhdp->aux.dev = &pdev->dev;
  1029. mhdp->aux.transfer = mhdp_transfer;
  1030. regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  1031. mhdp->regs = devm_ioremap_resource(&pdev->dev, regs);
  1032. if (IS_ERR(mhdp->regs))
  1033. return PTR_ERR(mhdp->regs);
  1034. mhdp->phy = devm_phy_get(&pdev->dev, "dpphy");
  1035. if (IS_ERR(mhdp->phy)) {
  1036. dev_err(&pdev->dev, "no PHY configured\n");
  1037. return PTR_ERR(mhdp->phy);
  1038. }
  1039. platform_set_drvdata(pdev, mhdp);
  1040. clk_prepare_enable(clk);
  1041. pm_runtime_enable(&pdev->dev);
  1042. ret = pm_runtime_get_sync(&pdev->dev);
  1043. if (ret < 0) {
  1044. dev_err(&pdev->dev, "pm_runtime_get_sync failed\n");
  1045. return ret;
  1046. }
  1047. ret = cdns_mhdp_j721e_init(mhdp);
  1048. if (ret != 0) {
  1049. dev_err(&pdev->dev, "J721E Wrapper initialization failed: %d\n",
  1050. ret);
  1051. return ret;
  1052. }
  1053. /* Release uCPU reset and stall it. */
  1054. writel(CDNS_CPU_STALL, mhdp->regs + CDNS_APB_CTRL);
  1055. ret = load_firmware(mhdp, FW_NAME, CDNS_MHDP_IMEM);
  1056. if (ret)
  1057. return ret;
  1058. rate = clk_get_rate(clk);
  1059. writel(rate % 1000000, mhdp->regs + CDNS_SW_CLK_L);
  1060. writel(rate / 1000000, mhdp->regs + CDNS_SW_CLK_H);
  1061. dev_dbg(&pdev->dev, "func clk rate %lu Hz\n", rate);
  1062. /* Leave debug mode, release stall */
  1063. writel(0, mhdp->regs + CDNS_APB_CTRL);
  1064. writel(~0, mhdp->regs + CDNS_MB_INT_MASK);
  1065. writel(~0, mhdp->regs + CDNS_APB_INT_MASK);
  1066. irq = platform_get_irq(pdev, 0);
  1067. ret = devm_request_irq(mhdp->dev, irq, mhdp_irq_handler, 0,
  1068. "mhdp8546", mhdp);
  1069. if (ret) {
  1070. dev_err(&pdev->dev,
  1071. "cannot install IRQ %d\n", irq);
  1072. return -EIO;
  1073. }
  1074. /*
  1075. * Wait for the KEEP_ALIVE "message" on the first 8 bits.
  1076. * Updated each sched "tick" (~2ms)
  1077. */
  1078. ret = readl_poll_timeout(mhdp->regs + CDNS_KEEP_ALIVE, reg,
  1079. reg & CDNS_KEEP_ALIVE_MASK, 500,
  1080. CDNS_KEEP_ALIVE_TIMEOUT);
  1081. if (ret) {
  1082. dev_err(&pdev->dev,
  1083. "device didn't give any life sign: reg %d\n", reg);
  1084. return -EIO;
  1085. }
  1086. /* Read source capabilities, based on PHY's device tree properties. */
  1087. ret = device_property_read_u32(&(mhdp->phy->dev), "num_lanes",
  1088. &(lanes_prop));
  1089. if (ret)
  1090. mhdp->host.lanes_cnt = CDNS_LANE_4 | CDNS_SCRAMBLER;
  1091. else
  1092. mhdp->host.lanes_cnt = lanes_prop | CDNS_SCRAMBLER;
  1093. ret = device_property_read_u32(&(mhdp->phy->dev), "max_bit_rate",
  1094. &(mhdp->host.link_rate));
  1095. if (ret)
  1096. mhdp->host.link_rate = drm_dp_bw_code_to_link_rate(DP_LINK_BW_8_1);
  1097. else
  1098. /* PHY uses Mb/s, DRM uses tens of kb/s. */
  1099. mhdp->host.link_rate *= 100;
  1100. mhdp->host.volt_swing = CDNS_VOLT_SWING(3);
  1101. mhdp->host.pre_emphasis = CDNS_PRE_EMPHASIS(3);
  1102. mhdp->host.pattern_supp = CDNS_SUPPORT_TPS(1) |
  1103. CDNS_SUPPORT_TPS(2) | CDNS_SUPPORT_TPS(3) |
  1104. CDNS_SUPPORT_TPS(4);
  1105. mhdp->host.fast_link = 0;
  1106. mhdp->host.lane_mapping = CDNS_LANE_MAPPING_NORMAL;
  1107. mhdp->host.enhanced = true;
  1108. /* The only currently supported format */
  1109. mhdp->display_fmt.y_only = false;
  1110. mhdp->display_fmt.color_format = DRM_COLOR_FORMAT_RGB444;
  1111. mhdp->display_fmt.bpc = 8;
  1112. mhdp->bridge.base.of_node = pdev->dev.of_node;
  1113. mhdp->bridge.base.funcs = &cdns_mhdp_bridge_funcs;
  1114. /* Init events to 0 as it's not cleared by FW at boot but on read */
  1115. readl(mhdp->regs + CDNS_SW_EVENT0);
  1116. readl(mhdp->regs + CDNS_SW_EVENT1);
  1117. readl(mhdp->regs + CDNS_SW_EVENT2);
  1118. readl(mhdp->regs + CDNS_SW_EVENT3);
  1119. /* Activate uCPU */
  1120. ret = cdns_mhdp_set_firmware_active(mhdp, true);
  1121. if (ret) {
  1122. dev_err(mhdp->dev, "Failed to activate DP\n");
  1123. return ret;
  1124. }
  1125. mhdp->audio_pdev = platform_device_register_data(
  1126. mhdp->dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO,
  1127. &codec_data, sizeof(codec_data));
  1128. ret = phy_init(mhdp->phy);
  1129. if (ret) {
  1130. dev_err(mhdp->dev, "Failed to initialize PHY: %d\n", ret);
  1131. return ret;
  1132. }
  1133. /* Enable VIF clock for stream 0 */
  1134. cdns_mhdp_reg_read(mhdp, CDNS_DPTX_CAR, &resp);
  1135. cdns_mhdp_reg_write(mhdp, CDNS_DPTX_CAR,
  1136. resp | CDNS_VIF_CLK_EN | CDNS_VIF_CLK_RSTN);
  1137. INIT_DELAYED_WORK(&mhdp->hotplug_work, mhdp_hotplug_work_func);
  1138. mhdp->bridge.connector = &mhdp->connector;
  1139. mhdp->connector.bridge = &mhdp->bridge;
  1140. mhdp->bridge.mhdp = mhdp;
  1141. mhdp->bridge.is_active = false;
  1142. drm_bridge_add(&mhdp->bridge.base);
  1143. return 0;
  1144. }
  1145. MODULE_FIRMWARE(FW_NAME);
  1146. static int mhdp_remove(struct platform_device *pdev)
  1147. {
  1148. struct cdns_mhdp_device *mhdp = dev_get_drvdata(&pdev->dev);
  1149. int ret;
  1150. flush_delayed_work(&mhdp->hotplug_work);
  1151. platform_device_unregister(mhdp->audio_pdev);
  1152. drm_bridge_remove(&mhdp->bridge.base);
  1153. ret = cdns_mhdp_set_firmware_active(mhdp, false);
  1154. if (ret) {
  1155. dev_err(mhdp->dev, "Failed to de-activate DP\n");
  1156. return ret;
  1157. }
  1158. pm_runtime_put_sync(&pdev->dev);
  1159. pm_runtime_disable(&pdev->dev);
  1160. clk_disable_unprepare(mhdp->clk);
  1161. /* FIXME: check for missing functions */
  1162. return 0;
  1163. }
  1164. static struct platform_driver mhdp_driver = {
  1165. .driver = {
  1166. .name = "cdns-mhdp",
  1167. .of_match_table = of_match_ptr(mhdp_ids),
  1168. },
  1169. .probe = mhdp_probe,
  1170. .remove = mhdp_remove,
  1171. };
  1172. module_platform_driver(mhdp_driver);
  1173. MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
  1174. MODULE_AUTHOR("Przemyslaw Gaj <pgaj@cadence.com>");
  1175. MODULE_AUTHOR("Damian Kos <dkos@cadence.com>");
  1176. MODULE_AUTHOR("Piotr Sroka <piotrs@cadence.com>");
  1177. MODULE_DESCRIPTION("Cadence MHDP DP bridge driver");
  1178. MODULE_LICENSE("GPL");
  1179. MODULE_ALIAS("platform:cdns-mhdp");