analogix_dp_reg.c 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196
  1. /*
  2. * Analogix DP (Display port) core register interface driver.
  3. *
  4. * Copyright (C) 2012 Samsung Electronics Co., Ltd.
  5. * Author: Jingoo Han <jg1.han@samsung.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation; either version 2 of the License, or (at your
  10. * option) any later version.
  11. */
  12. #include <linux/delay.h>
  13. #include <linux/device.h>
  14. #include <linux/gpio.h>
  15. #include <linux/io.h>
  16. #include <linux/iopoll.h>
  17. #include <drm/bridge/analogix_dp.h>
  18. #include "analogix_dp_core.h"
  19. #include "analogix_dp_reg.h"
  20. #define COMMON_INT_MASK_1 0
  21. #define COMMON_INT_MASK_2 0
  22. #define COMMON_INT_MASK_3 0
  23. #define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG)
  24. #define INT_STA_MASK INT_HPD
  25. void analogix_dp_enable_video_mute(struct analogix_dp_device *dp, bool enable)
  26. {
  27. u32 reg;
  28. if (enable) {
  29. reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
  30. reg |= HDCP_VIDEO_MUTE;
  31. writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
  32. } else {
  33. reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
  34. reg &= ~HDCP_VIDEO_MUTE;
  35. writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
  36. }
  37. }
  38. void analogix_dp_stop_video(struct analogix_dp_device *dp)
  39. {
  40. u32 reg;
  41. reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
  42. reg &= ~VIDEO_EN;
  43. writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
  44. }
  45. void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable)
  46. {
  47. u32 reg;
  48. if (enable)
  49. reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 |
  50. LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3;
  51. else
  52. reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 |
  53. LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0;
  54. writel(reg, dp->reg_base + ANALOGIX_DP_LANE_MAP);
  55. }
  56. void analogix_dp_init_analog_param(struct analogix_dp_device *dp)
  57. {
  58. u32 reg;
  59. reg = TX_TERMINAL_CTRL_50_OHM;
  60. writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_1);
  61. reg = SEL_24M | TX_DVDD_BIT_1_0625V;
  62. writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_2);
  63. if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
  64. reg = REF_CLK_24M;
  65. if (dp->plat_data->dev_type == RK3288_DP)
  66. reg ^= REF_CLK_MASK;
  67. writel(reg, dp->reg_base + ANALOGIX_DP_PLL_REG_1);
  68. writel(0x95, dp->reg_base + ANALOGIX_DP_PLL_REG_2);
  69. writel(0x40, dp->reg_base + ANALOGIX_DP_PLL_REG_3);
  70. writel(0x58, dp->reg_base + ANALOGIX_DP_PLL_REG_4);
  71. writel(0x22, dp->reg_base + ANALOGIX_DP_PLL_REG_5);
  72. }
  73. reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO;
  74. writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_3);
  75. reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM |
  76. TX_CUR1_2X | TX_CUR_16_MA;
  77. writel(reg, dp->reg_base + ANALOGIX_DP_PLL_FILTER_CTL_1);
  78. reg = CH3_AMP_400_MV | CH2_AMP_400_MV |
  79. CH1_AMP_400_MV | CH0_AMP_400_MV;
  80. writel(reg, dp->reg_base + ANALOGIX_DP_TX_AMP_TUNING_CTL);
  81. }
  82. void analogix_dp_init_interrupt(struct analogix_dp_device *dp)
  83. {
  84. /* Set interrupt pin assertion polarity as high */
  85. writel(INT_POL1 | INT_POL0, dp->reg_base + ANALOGIX_DP_INT_CTL);
  86. /* Clear pending regisers */
  87. writel(0xff, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
  88. writel(0x4f, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_2);
  89. writel(0xe0, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_3);
  90. writel(0xe7, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
  91. writel(0x63, dp->reg_base + ANALOGIX_DP_INT_STA);
  92. /* 0:mask,1: unmask */
  93. writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_1);
  94. writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_2);
  95. writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_3);
  96. writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
  97. writel(0x00, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
  98. }
  99. void analogix_dp_reset(struct analogix_dp_device *dp)
  100. {
  101. u32 reg;
  102. analogix_dp_stop_video(dp);
  103. analogix_dp_enable_video_mute(dp, 0);
  104. reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N |
  105. AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N |
  106. HDCP_FUNC_EN_N | SW_FUNC_EN_N;
  107. writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
  108. reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N |
  109. SERDES_FIFO_FUNC_EN_N |
  110. LS_CLK_DOMAIN_FUNC_EN_N;
  111. writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
  112. usleep_range(20, 30);
  113. analogix_dp_lane_swap(dp, 0);
  114. writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
  115. writel(0x40, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
  116. writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
  117. writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
  118. writel(0x0, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
  119. writel(0x0, dp->reg_base + ANALOGIX_DP_HDCP_CTL);
  120. writel(0x5e, dp->reg_base + ANALOGIX_DP_HPD_DEGLITCH_L);
  121. writel(0x1a, dp->reg_base + ANALOGIX_DP_HPD_DEGLITCH_H);
  122. writel(0x10, dp->reg_base + ANALOGIX_DP_LINK_DEBUG_CTL);
  123. writel(0x0, dp->reg_base + ANALOGIX_DP_PHY_TEST);
  124. writel(0x0, dp->reg_base + ANALOGIX_DP_VIDEO_FIFO_THRD);
  125. writel(0x20, dp->reg_base + ANALOGIX_DP_AUDIO_MARGIN);
  126. writel(0x4, dp->reg_base + ANALOGIX_DP_M_VID_GEN_FILTER_TH);
  127. writel(0x2, dp->reg_base + ANALOGIX_DP_M_AUD_GEN_FILTER_TH);
  128. writel(0x00000101, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
  129. }
  130. void analogix_dp_swreset(struct analogix_dp_device *dp)
  131. {
  132. writel(RESET_DP_TX, dp->reg_base + ANALOGIX_DP_TX_SW_RESET);
  133. }
  134. void analogix_dp_config_interrupt(struct analogix_dp_device *dp)
  135. {
  136. u32 reg;
  137. /* 0: mask, 1: unmask */
  138. reg = COMMON_INT_MASK_1;
  139. writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_1);
  140. reg = COMMON_INT_MASK_2;
  141. writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_2);
  142. reg = COMMON_INT_MASK_3;
  143. writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_3);
  144. reg = COMMON_INT_MASK_4;
  145. writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
  146. reg = INT_STA_MASK;
  147. writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
  148. }
  149. void analogix_dp_mute_hpd_interrupt(struct analogix_dp_device *dp)
  150. {
  151. u32 reg;
  152. /* 0: mask, 1: unmask */
  153. reg = readl(dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
  154. reg &= ~COMMON_INT_MASK_4;
  155. writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
  156. reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
  157. reg &= ~INT_STA_MASK;
  158. writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
  159. }
  160. void analogix_dp_unmute_hpd_interrupt(struct analogix_dp_device *dp)
  161. {
  162. u32 reg;
  163. /* 0: mask, 1: unmask */
  164. reg = COMMON_INT_MASK_4;
  165. writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4);
  166. reg = INT_STA_MASK;
  167. writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK);
  168. }
  169. enum pll_status analogix_dp_get_pll_lock_status(struct analogix_dp_device *dp)
  170. {
  171. u32 reg;
  172. reg = readl(dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
  173. if (reg & PLL_LOCK)
  174. return PLL_LOCKED;
  175. else
  176. return PLL_UNLOCKED;
  177. }
  178. void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enable)
  179. {
  180. u32 reg;
  181. if (enable) {
  182. reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL);
  183. reg |= DP_PLL_PD;
  184. writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL);
  185. } else {
  186. reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL);
  187. reg &= ~DP_PLL_PD;
  188. writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL);
  189. }
  190. }
  191. void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
  192. enum analog_power_block block,
  193. bool enable)
  194. {
  195. u32 reg;
  196. u32 phy_pd_addr = ANALOGIX_DP_PHY_PD;
  197. if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
  198. phy_pd_addr = ANALOGIX_DP_PD;
  199. switch (block) {
  200. case AUX_BLOCK:
  201. if (enable) {
  202. reg = readl(dp->reg_base + phy_pd_addr);
  203. reg |= AUX_PD;
  204. writel(reg, dp->reg_base + phy_pd_addr);
  205. } else {
  206. reg = readl(dp->reg_base + phy_pd_addr);
  207. reg &= ~AUX_PD;
  208. writel(reg, dp->reg_base + phy_pd_addr);
  209. }
  210. break;
  211. case CH0_BLOCK:
  212. if (enable) {
  213. reg = readl(dp->reg_base + phy_pd_addr);
  214. reg |= CH0_PD;
  215. writel(reg, dp->reg_base + phy_pd_addr);
  216. } else {
  217. reg = readl(dp->reg_base + phy_pd_addr);
  218. reg &= ~CH0_PD;
  219. writel(reg, dp->reg_base + phy_pd_addr);
  220. }
  221. break;
  222. case CH1_BLOCK:
  223. if (enable) {
  224. reg = readl(dp->reg_base + phy_pd_addr);
  225. reg |= CH1_PD;
  226. writel(reg, dp->reg_base + phy_pd_addr);
  227. } else {
  228. reg = readl(dp->reg_base + phy_pd_addr);
  229. reg &= ~CH1_PD;
  230. writel(reg, dp->reg_base + phy_pd_addr);
  231. }
  232. break;
  233. case CH2_BLOCK:
  234. if (enable) {
  235. reg = readl(dp->reg_base + phy_pd_addr);
  236. reg |= CH2_PD;
  237. writel(reg, dp->reg_base + phy_pd_addr);
  238. } else {
  239. reg = readl(dp->reg_base + phy_pd_addr);
  240. reg &= ~CH2_PD;
  241. writel(reg, dp->reg_base + phy_pd_addr);
  242. }
  243. break;
  244. case CH3_BLOCK:
  245. if (enable) {
  246. reg = readl(dp->reg_base + phy_pd_addr);
  247. reg |= CH3_PD;
  248. writel(reg, dp->reg_base + phy_pd_addr);
  249. } else {
  250. reg = readl(dp->reg_base + phy_pd_addr);
  251. reg &= ~CH3_PD;
  252. writel(reg, dp->reg_base + phy_pd_addr);
  253. }
  254. break;
  255. case ANALOG_TOTAL:
  256. if (enable) {
  257. reg = readl(dp->reg_base + phy_pd_addr);
  258. reg |= DP_PHY_PD;
  259. writel(reg, dp->reg_base + phy_pd_addr);
  260. } else {
  261. reg = readl(dp->reg_base + phy_pd_addr);
  262. reg &= ~DP_PHY_PD;
  263. writel(reg, dp->reg_base + phy_pd_addr);
  264. }
  265. break;
  266. case POWER_ALL:
  267. if (enable) {
  268. reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD |
  269. CH1_PD | CH0_PD;
  270. writel(reg, dp->reg_base + phy_pd_addr);
  271. } else {
  272. writel(0x00, dp->reg_base + phy_pd_addr);
  273. }
  274. break;
  275. default:
  276. break;
  277. }
  278. }
  279. void analogix_dp_init_analog_func(struct analogix_dp_device *dp)
  280. {
  281. u32 reg;
  282. int timeout_loop = 0;
  283. analogix_dp_set_analog_power_down(dp, POWER_ALL, 0);
  284. reg = PLL_LOCK_CHG;
  285. writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
  286. reg = readl(dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
  287. reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL);
  288. writel(reg, dp->reg_base + ANALOGIX_DP_DEBUG_CTL);
  289. /* Power up PLL */
  290. if (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
  291. analogix_dp_set_pll_power_down(dp, 0);
  292. while (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
  293. timeout_loop++;
  294. if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
  295. dev_err(dp->dev, "failed to get pll lock status\n");
  296. return;
  297. }
  298. usleep_range(10, 20);
  299. }
  300. }
  301. /* Enable Serdes FIFO function and Link symbol clock domain module */
  302. reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
  303. reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N
  304. | AUX_FUNC_EN_N);
  305. writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
  306. }
  307. void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp)
  308. {
  309. u32 reg;
  310. if (gpio_is_valid(dp->hpd_gpio))
  311. return;
  312. reg = HOTPLUG_CHG | HPD_LOST | PLUG;
  313. writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
  314. reg = INT_HPD;
  315. writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
  316. }
  317. void analogix_dp_init_hpd(struct analogix_dp_device *dp)
  318. {
  319. u32 reg;
  320. if (gpio_is_valid(dp->hpd_gpio))
  321. return;
  322. analogix_dp_clear_hotplug_interrupts(dp);
  323. reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
  324. reg &= ~(F_HPD | HPD_CTRL);
  325. writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
  326. }
  327. void analogix_dp_force_hpd(struct analogix_dp_device *dp)
  328. {
  329. u32 reg;
  330. reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
  331. reg = (F_HPD | HPD_CTRL);
  332. writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
  333. }
  334. enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp)
  335. {
  336. u32 reg;
  337. if (gpio_is_valid(dp->hpd_gpio)) {
  338. reg = gpio_get_value(dp->hpd_gpio);
  339. if (reg)
  340. return DP_IRQ_TYPE_HP_CABLE_IN;
  341. else
  342. return DP_IRQ_TYPE_HP_CABLE_OUT;
  343. } else {
  344. /* Parse hotplug interrupt status register */
  345. reg = readl(dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4);
  346. if (reg & PLUG)
  347. return DP_IRQ_TYPE_HP_CABLE_IN;
  348. if (reg & HPD_LOST)
  349. return DP_IRQ_TYPE_HP_CABLE_OUT;
  350. if (reg & HOTPLUG_CHG)
  351. return DP_IRQ_TYPE_HP_CHANGE;
  352. return DP_IRQ_TYPE_UNKNOWN;
  353. }
  354. }
  355. void analogix_dp_reset_aux(struct analogix_dp_device *dp)
  356. {
  357. u32 reg;
  358. /* Disable AUX channel module */
  359. reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
  360. reg |= AUX_FUNC_EN_N;
  361. writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
  362. }
  363. void analogix_dp_init_aux(struct analogix_dp_device *dp)
  364. {
  365. u32 reg;
  366. /* Clear inerrupts related to AUX channel */
  367. reg = RPLY_RECEIV | AUX_ERR;
  368. writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA);
  369. analogix_dp_reset_aux(dp);
  370. /* Disable AUX transaction H/W retry */
  371. if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
  372. reg = AUX_BIT_PERIOD_EXPECTED_DELAY(0) |
  373. AUX_HW_RETRY_COUNT_SEL(3) |
  374. AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
  375. else
  376. reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) |
  377. AUX_HW_RETRY_COUNT_SEL(0) |
  378. AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
  379. writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL);
  380. /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */
  381. reg = DEFER_CTRL_EN | DEFER_COUNT(1);
  382. writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_DEFER_CTL);
  383. /* Enable AUX channel module */
  384. reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
  385. reg &= ~AUX_FUNC_EN_N;
  386. writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2);
  387. }
  388. int analogix_dp_get_plug_in_status(struct analogix_dp_device *dp)
  389. {
  390. u32 reg;
  391. if (gpio_is_valid(dp->hpd_gpio)) {
  392. if (gpio_get_value(dp->hpd_gpio))
  393. return 0;
  394. } else {
  395. reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
  396. if (reg & HPD_STATUS)
  397. return 0;
  398. }
  399. return -EINVAL;
  400. }
  401. void analogix_dp_enable_sw_function(struct analogix_dp_device *dp)
  402. {
  403. u32 reg;
  404. reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
  405. reg &= ~SW_FUNC_EN_N;
  406. writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
  407. }
  408. int analogix_dp_start_aux_transaction(struct analogix_dp_device *dp)
  409. {
  410. int reg;
  411. int retval = 0;
  412. int timeout_loop = 0;
  413. /* Enable AUX CH operation */
  414. reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
  415. reg |= AUX_EN;
  416. writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
  417. /* Is AUX CH command reply received? */
  418. reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
  419. while (!(reg & RPLY_RECEIV)) {
  420. timeout_loop++;
  421. if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) {
  422. dev_err(dp->dev, "AUX CH command reply failed!\n");
  423. return -ETIMEDOUT;
  424. }
  425. reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
  426. usleep_range(10, 11);
  427. }
  428. /* Clear interrupt source for AUX CH command reply */
  429. writel(RPLY_RECEIV, dp->reg_base + ANALOGIX_DP_INT_STA);
  430. /* Clear interrupt source for AUX CH access error */
  431. reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
  432. if (reg & AUX_ERR) {
  433. writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
  434. return -EREMOTEIO;
  435. }
  436. /* Check AUX CH error access status */
  437. reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
  438. if ((reg & AUX_STATUS_MASK) != 0) {
  439. dev_err(dp->dev, "AUX CH error happens: %d\n\n",
  440. reg & AUX_STATUS_MASK);
  441. return -EREMOTEIO;
  442. }
  443. return retval;
  444. }
  445. int analogix_dp_write_byte_to_dpcd(struct analogix_dp_device *dp,
  446. unsigned int reg_addr,
  447. unsigned char data)
  448. {
  449. u32 reg;
  450. int i;
  451. int retval;
  452. for (i = 0; i < 3; i++) {
  453. /* Clear AUX CH data buffer */
  454. reg = BUF_CLR;
  455. writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
  456. /* Select DPCD device address */
  457. reg = AUX_ADDR_7_0(reg_addr);
  458. writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
  459. reg = AUX_ADDR_15_8(reg_addr);
  460. writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
  461. reg = AUX_ADDR_19_16(reg_addr);
  462. writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
  463. /* Write data buffer */
  464. reg = (unsigned int)data;
  465. writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0);
  466. /*
  467. * Set DisplayPort transaction and write 1 byte
  468. * If bit 3 is 1, DisplayPort transaction.
  469. * If Bit 3 is 0, I2C transaction.
  470. */
  471. reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE;
  472. writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
  473. /* Start AUX transaction */
  474. retval = analogix_dp_start_aux_transaction(dp);
  475. if (retval == 0)
  476. break;
  477. dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__);
  478. }
  479. return retval;
  480. }
  481. void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype)
  482. {
  483. u32 reg;
  484. reg = bwtype;
  485. if ((bwtype == DP_LINK_BW_2_7) || (bwtype == DP_LINK_BW_1_62))
  486. writel(reg, dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
  487. }
  488. void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype)
  489. {
  490. u32 reg;
  491. reg = readl(dp->reg_base + ANALOGIX_DP_LINK_BW_SET);
  492. *bwtype = reg;
  493. }
  494. void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count)
  495. {
  496. u32 reg;
  497. reg = count;
  498. writel(reg, dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
  499. }
  500. void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count)
  501. {
  502. u32 reg;
  503. reg = readl(dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET);
  504. *count = reg;
  505. }
  506. void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp,
  507. bool enable)
  508. {
  509. u32 reg;
  510. if (enable) {
  511. reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
  512. reg |= ENHANCED;
  513. writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
  514. } else {
  515. reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
  516. reg &= ~ENHANCED;
  517. writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
  518. }
  519. }
  520. void analogix_dp_set_training_pattern(struct analogix_dp_device *dp,
  521. enum pattern_set pattern)
  522. {
  523. u32 reg;
  524. switch (pattern) {
  525. case PRBS7:
  526. reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7;
  527. writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
  528. break;
  529. case D10_2:
  530. reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2;
  531. writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
  532. break;
  533. case TRAINING_PTN1:
  534. reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1;
  535. writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
  536. break;
  537. case TRAINING_PTN2:
  538. reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2;
  539. writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
  540. break;
  541. case DP_NONE:
  542. reg = SCRAMBLING_ENABLE |
  543. LINK_QUAL_PATTERN_SET_DISABLE |
  544. SW_TRAINING_PATTERN_SET_NORMAL;
  545. writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
  546. break;
  547. default:
  548. break;
  549. }
  550. }
  551. void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp,
  552. u32 level)
  553. {
  554. u32 reg;
  555. reg = readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
  556. reg &= ~PRE_EMPHASIS_SET_MASK;
  557. reg |= level << PRE_EMPHASIS_SET_SHIFT;
  558. writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
  559. }
  560. void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp,
  561. u32 level)
  562. {
  563. u32 reg;
  564. reg = readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
  565. reg &= ~PRE_EMPHASIS_SET_MASK;
  566. reg |= level << PRE_EMPHASIS_SET_SHIFT;
  567. writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
  568. }
  569. void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp,
  570. u32 level)
  571. {
  572. u32 reg;
  573. reg = readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
  574. reg &= ~PRE_EMPHASIS_SET_MASK;
  575. reg |= level << PRE_EMPHASIS_SET_SHIFT;
  576. writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
  577. }
  578. void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp,
  579. u32 level)
  580. {
  581. u32 reg;
  582. reg = readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
  583. reg &= ~PRE_EMPHASIS_SET_MASK;
  584. reg |= level << PRE_EMPHASIS_SET_SHIFT;
  585. writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
  586. }
  587. void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp,
  588. u32 training_lane)
  589. {
  590. u32 reg;
  591. reg = training_lane;
  592. writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
  593. }
  594. void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp,
  595. u32 training_lane)
  596. {
  597. u32 reg;
  598. reg = training_lane;
  599. writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
  600. }
  601. void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp,
  602. u32 training_lane)
  603. {
  604. u32 reg;
  605. reg = training_lane;
  606. writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
  607. }
  608. void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp,
  609. u32 training_lane)
  610. {
  611. u32 reg;
  612. reg = training_lane;
  613. writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
  614. }
  615. u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp)
  616. {
  617. return readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL);
  618. }
  619. u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp)
  620. {
  621. return readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL);
  622. }
  623. u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp)
  624. {
  625. return readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL);
  626. }
  627. u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp)
  628. {
  629. return readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL);
  630. }
  631. void analogix_dp_reset_macro(struct analogix_dp_device *dp)
  632. {
  633. u32 reg;
  634. reg = readl(dp->reg_base + ANALOGIX_DP_PHY_TEST);
  635. reg |= MACRO_RST;
  636. writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
  637. /* 10 us is the minimum reset time. */
  638. usleep_range(10, 20);
  639. reg &= ~MACRO_RST;
  640. writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST);
  641. }
  642. void analogix_dp_init_video(struct analogix_dp_device *dp)
  643. {
  644. u32 reg;
  645. reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG;
  646. writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1);
  647. reg = 0x0;
  648. writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
  649. reg = CHA_CRI(4) | CHA_CTRL;
  650. writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
  651. reg = 0x0;
  652. writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
  653. reg = VID_HRES_TH(2) | VID_VRES_TH(0);
  654. writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_8);
  655. }
  656. void analogix_dp_set_video_color_format(struct analogix_dp_device *dp)
  657. {
  658. u32 reg;
  659. /* Configure the input color depth, color space, dynamic range */
  660. reg = (dp->video_info.dynamic_range << IN_D_RANGE_SHIFT) |
  661. (dp->video_info.color_depth << IN_BPC_SHIFT) |
  662. (dp->video_info.color_space << IN_COLOR_F_SHIFT);
  663. writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_2);
  664. /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */
  665. reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
  666. reg &= ~IN_YC_COEFFI_MASK;
  667. if (dp->video_info.ycbcr_coeff)
  668. reg |= IN_YC_COEFFI_ITU709;
  669. else
  670. reg |= IN_YC_COEFFI_ITU601;
  671. writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
  672. }
  673. int analogix_dp_is_slave_video_stream_clock_on(struct analogix_dp_device *dp)
  674. {
  675. u32 reg;
  676. reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
  677. writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
  678. reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
  679. if (!(reg & DET_STA)) {
  680. dev_dbg(dp->dev, "Input stream clock not detected.\n");
  681. return -EINVAL;
  682. }
  683. reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
  684. writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
  685. reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
  686. dev_dbg(dp->dev, "wait SYS_CTL_2.\n");
  687. if (reg & CHA_STA) {
  688. dev_dbg(dp->dev, "Input stream clk is changing\n");
  689. return -EINVAL;
  690. }
  691. return 0;
  692. }
  693. void analogix_dp_set_video_cr_mn(struct analogix_dp_device *dp,
  694. enum clock_recovery_m_value_type type,
  695. u32 m_value, u32 n_value)
  696. {
  697. u32 reg;
  698. if (type == REGISTER_M) {
  699. reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
  700. reg |= FIX_M_VID;
  701. writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
  702. reg = m_value & 0xff;
  703. writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_0);
  704. reg = (m_value >> 8) & 0xff;
  705. writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_1);
  706. reg = (m_value >> 16) & 0xff;
  707. writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_2);
  708. reg = n_value & 0xff;
  709. writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_0);
  710. reg = (n_value >> 8) & 0xff;
  711. writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_1);
  712. reg = (n_value >> 16) & 0xff;
  713. writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_2);
  714. } else {
  715. reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
  716. reg &= ~FIX_M_VID;
  717. writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4);
  718. writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_0);
  719. writel(0x80, dp->reg_base + ANALOGIX_DP_N_VID_1);
  720. writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_2);
  721. }
  722. }
  723. void analogix_dp_set_video_timing_mode(struct analogix_dp_device *dp, u32 type)
  724. {
  725. u32 reg;
  726. if (type == VIDEO_TIMING_FROM_CAPTURE) {
  727. reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
  728. reg &= ~FORMAT_SEL;
  729. writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
  730. } else {
  731. reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
  732. reg |= FORMAT_SEL;
  733. writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
  734. }
  735. }
  736. void analogix_dp_enable_video_master(struct analogix_dp_device *dp, bool enable)
  737. {
  738. u32 reg;
  739. if (enable) {
  740. reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
  741. reg &= ~VIDEO_MODE_MASK;
  742. reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE;
  743. writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
  744. } else {
  745. reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
  746. reg &= ~VIDEO_MODE_MASK;
  747. reg |= VIDEO_MODE_SLAVE_MODE;
  748. writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
  749. }
  750. }
  751. void analogix_dp_start_video(struct analogix_dp_device *dp)
  752. {
  753. u32 reg;
  754. reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
  755. reg |= VIDEO_EN;
  756. writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
  757. }
  758. int analogix_dp_is_video_stream_on(struct analogix_dp_device *dp)
  759. {
  760. u32 reg;
  761. reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
  762. writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
  763. reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3);
  764. if (!(reg & STRM_VALID)) {
  765. dev_dbg(dp->dev, "Input video stream is not detected.\n");
  766. return -EINVAL;
  767. }
  768. return 0;
  769. }
  770. void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp)
  771. {
  772. u32 reg;
  773. reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
  774. reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N);
  775. reg |= MASTER_VID_FUNC_EN_N;
  776. writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1);
  777. reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
  778. reg &= ~INTERACE_SCAN_CFG;
  779. reg |= (dp->video_info.interlaced << 2);
  780. writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
  781. reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
  782. reg &= ~VSYNC_POLARITY_CFG;
  783. reg |= (dp->video_info.v_sync_polarity << 1);
  784. writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
  785. reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
  786. reg &= ~HSYNC_POLARITY_CFG;
  787. reg |= (dp->video_info.h_sync_polarity << 0);
  788. writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10);
  789. reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE;
  790. writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL);
  791. }
  792. void analogix_dp_enable_scrambling(struct analogix_dp_device *dp)
  793. {
  794. u32 reg;
  795. reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
  796. reg &= ~SCRAMBLING_DISABLE;
  797. writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
  798. }
  799. void analogix_dp_disable_scrambling(struct analogix_dp_device *dp)
  800. {
  801. u32 reg;
  802. reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
  803. reg |= SCRAMBLING_DISABLE;
  804. writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET);
  805. }
  806. void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp)
  807. {
  808. writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON);
  809. }
  810. static ssize_t analogix_dp_get_psr_status(struct analogix_dp_device *dp)
  811. {
  812. ssize_t val;
  813. u8 status;
  814. val = drm_dp_dpcd_readb(&dp->aux, DP_PSR_STATUS, &status);
  815. if (val < 0) {
  816. dev_err(dp->dev, "PSR_STATUS read failed ret=%zd", val);
  817. return val;
  818. }
  819. return status;
  820. }
  821. int analogix_dp_send_psr_spd(struct analogix_dp_device *dp,
  822. struct edp_vsc_psr *vsc, bool blocking)
  823. {
  824. unsigned int val;
  825. int ret;
  826. ssize_t psr_status;
  827. /* don't send info frame */
  828. val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
  829. val &= ~IF_EN;
  830. writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
  831. /* configure single frame update mode */
  832. writel(PSR_FRAME_UP_TYPE_BURST | PSR_CRC_SEL_HARDWARE,
  833. dp->reg_base + ANALOGIX_DP_PSR_FRAME_UPDATE_CTRL);
  834. /* configure VSC HB0~HB3 */
  835. writel(vsc->sdp_header.HB0, dp->reg_base + ANALOGIX_DP_SPD_HB0);
  836. writel(vsc->sdp_header.HB1, dp->reg_base + ANALOGIX_DP_SPD_HB1);
  837. writel(vsc->sdp_header.HB2, dp->reg_base + ANALOGIX_DP_SPD_HB2);
  838. writel(vsc->sdp_header.HB3, dp->reg_base + ANALOGIX_DP_SPD_HB3);
  839. /* configure reused VSC PB0~PB3, magic number from vendor */
  840. writel(0x00, dp->reg_base + ANALOGIX_DP_SPD_PB0);
  841. writel(0x16, dp->reg_base + ANALOGIX_DP_SPD_PB1);
  842. writel(0xCE, dp->reg_base + ANALOGIX_DP_SPD_PB2);
  843. writel(0x5D, dp->reg_base + ANALOGIX_DP_SPD_PB3);
  844. /* configure DB0 / DB1 values */
  845. writel(vsc->DB0, dp->reg_base + ANALOGIX_DP_VSC_SHADOW_DB0);
  846. writel(vsc->DB1, dp->reg_base + ANALOGIX_DP_VSC_SHADOW_DB1);
  847. /* set reuse spd inforframe */
  848. val = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
  849. val |= REUSE_SPD_EN;
  850. writel(val, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3);
  851. /* mark info frame update */
  852. val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
  853. val = (val | IF_UP) & ~IF_EN;
  854. writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
  855. /* send info frame */
  856. val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
  857. val |= IF_EN;
  858. writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL);
  859. if (!blocking)
  860. return 0;
  861. ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status,
  862. psr_status >= 0 &&
  863. ((vsc->DB1 && psr_status == DP_PSR_SINK_ACTIVE_RFB) ||
  864. (!vsc->DB1 && psr_status == DP_PSR_SINK_INACTIVE)), 1500,
  865. DP_TIMEOUT_PSR_LOOP_MS * 1000);
  866. if (ret) {
  867. dev_warn(dp->dev, "Failed to apply PSR %d\n", ret);
  868. return ret;
  869. }
  870. return 0;
  871. }
  872. ssize_t analogix_dp_transfer(struct analogix_dp_device *dp,
  873. struct drm_dp_aux_msg *msg)
  874. {
  875. u32 reg;
  876. u8 *buffer = msg->buffer;
  877. int timeout_loop = 0;
  878. unsigned int i;
  879. int num_transferred = 0;
  880. /* Buffer size of AUX CH is 16 bytes */
  881. if (WARN_ON(msg->size > 16))
  882. return -E2BIG;
  883. /* Clear AUX CH data buffer */
  884. reg = BUF_CLR;
  885. writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL);
  886. switch (msg->request & ~DP_AUX_I2C_MOT) {
  887. case DP_AUX_I2C_WRITE:
  888. reg = AUX_TX_COMM_WRITE | AUX_TX_COMM_I2C_TRANSACTION;
  889. if (msg->request & DP_AUX_I2C_MOT)
  890. reg |= AUX_TX_COMM_MOT;
  891. break;
  892. case DP_AUX_I2C_READ:
  893. reg = AUX_TX_COMM_READ | AUX_TX_COMM_I2C_TRANSACTION;
  894. if (msg->request & DP_AUX_I2C_MOT)
  895. reg |= AUX_TX_COMM_MOT;
  896. break;
  897. case DP_AUX_NATIVE_WRITE:
  898. reg = AUX_TX_COMM_WRITE | AUX_TX_COMM_DP_TRANSACTION;
  899. break;
  900. case DP_AUX_NATIVE_READ:
  901. reg = AUX_TX_COMM_READ | AUX_TX_COMM_DP_TRANSACTION;
  902. break;
  903. default:
  904. return -EINVAL;
  905. }
  906. reg |= AUX_LENGTH(msg->size);
  907. writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1);
  908. /* Select DPCD device address */
  909. reg = AUX_ADDR_7_0(msg->address);
  910. writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0);
  911. reg = AUX_ADDR_15_8(msg->address);
  912. writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8);
  913. reg = AUX_ADDR_19_16(msg->address);
  914. writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16);
  915. if (!(msg->request & DP_AUX_I2C_READ)) {
  916. for (i = 0; i < msg->size; i++) {
  917. reg = buffer[i];
  918. writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
  919. 4 * i);
  920. num_transferred++;
  921. }
  922. }
  923. /* Enable AUX CH operation */
  924. reg = AUX_EN;
  925. /* Zero-sized messages specify address-only transactions. */
  926. if (msg->size < 1)
  927. reg |= ADDR_ONLY;
  928. writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2);
  929. /* Is AUX CH command reply received? */
  930. /* TODO: Wait for an interrupt instead of looping? */
  931. reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
  932. while (!(reg & RPLY_RECEIV)) {
  933. timeout_loop++;
  934. if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) {
  935. dev_err(dp->dev, "AUX CH command reply failed!\n");
  936. return -ETIMEDOUT;
  937. }
  938. reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
  939. usleep_range(10, 11);
  940. }
  941. /* Clear interrupt source for AUX CH command reply */
  942. writel(RPLY_RECEIV, dp->reg_base + ANALOGIX_DP_INT_STA);
  943. /* Clear interrupt source for AUX CH access error */
  944. reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA);
  945. if (reg & AUX_ERR) {
  946. writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA);
  947. return -EREMOTEIO;
  948. }
  949. /* Check AUX CH error access status */
  950. reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA);
  951. if ((reg & AUX_STATUS_MASK)) {
  952. dev_err(dp->dev, "AUX CH error happened: %d\n\n",
  953. reg & AUX_STATUS_MASK);
  954. return -EREMOTEIO;
  955. }
  956. if (msg->request & DP_AUX_I2C_READ) {
  957. for (i = 0; i < msg->size; i++) {
  958. reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 +
  959. 4 * i);
  960. buffer[i] = (unsigned char)reg;
  961. num_transferred++;
  962. }
  963. }
  964. /* Check if Rx sends defer */
  965. reg = readl(dp->reg_base + ANALOGIX_DP_AUX_RX_COMM);
  966. if (reg == AUX_RX_COMM_AUX_DEFER)
  967. msg->reply = DP_AUX_NATIVE_REPLY_DEFER;
  968. else if (reg == AUX_RX_COMM_I2C_DEFER)
  969. msg->reply = DP_AUX_I2C_REPLY_DEFER;
  970. else if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_WRITE ||
  971. (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_READ)
  972. msg->reply = DP_AUX_I2C_REPLY_ACK;
  973. else if ((msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_WRITE ||
  974. (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ)
  975. msg->reply = DP_AUX_NATIVE_REPLY_ACK;
  976. return num_transferred > 0 ? num_transferred : -EBUSY;
  977. }