sf_mipi.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. #include <asm/gpio.h>
  2. #include <asm/io.h>
  3. #include <common.h>
  4. #include <clk.h>
  5. #include <display.h>
  6. #include <dm.h>
  7. #include <log.h>
  8. #include <panel.h>
  9. #include <regmap.h>
  10. #include <syscon.h>
  11. #include <dm/uclass-internal.h>
  12. #include <linux/err.h>
  13. #include <linux/kernel.h>
  14. #include <linux/delay.h>
  15. #include <linux/iopoll.h>
  16. #include <linux/err.h>
  17. #include <power/regulator.h>
  18. #include <video_bridge.h>
  19. #include <dsi_host.h>
  20. #include <mipi_dsi.h>
  21. #include <reset.h>
  22. #include <video.h>
  23. #include "sf_mipi.h"
  24. static inline u32 sf_dphy_get_reg(void __iomem * io_addr, u32 shift, u32 mask)
  25. {
  26. return (readl(io_addr) & mask) >> shift;
  27. }
  28. static inline void sf_dphy_set_reg(void __iomem * io_addr, u32 data, u32 shift, u32 mask)
  29. {
  30. u32 tmp;
  31. tmp = readl(io_addr);
  32. tmp &= ~mask;
  33. tmp |= (data << shift) & mask;
  34. writel(tmp, io_addr);
  35. }
  36. static int dsi_phy_init(void *priv_data)
  37. {
  38. struct mipi_dsi_device *device = priv_data;
  39. struct udevice *dev = device->dev;
  40. struct dsi_sf_priv *dsi = dev_get_priv(dev);
  41. uint32_t temp;
  42. temp = sf_dphy_get_reg(dsi->sys_reg, AON_GP_REG_SHIFT,AON_GP_REG_MASK);
  43. if (!(temp & DPHY_TX_PSW_EN_MASK)) {
  44. temp |= DPHY_TX_PSW_EN_MASK;
  45. sf_dphy_set_reg(dsi->sys_reg, temp,AON_GP_REG_SHIFT,AON_GP_REG_MASK);
  46. }
  47. return 0;
  48. }
  49. static int is_pll_locked(void __iomem *phy_reg)
  50. {
  51. return !sf_dphy_get_reg(phy_reg + 0x8,
  52. RGS_CDTX_PLL_UNLOCK_SHIFT, RGS_CDTX_PLL_UNLOCK_MASK);
  53. }
  54. static void reset(int assert, void __iomem *phy_reg)
  55. {
  56. sf_dphy_set_reg(phy_reg + 0x64, (!assert), RESETB_SHIFT, RESETB_MASK);
  57. if (!assert) {
  58. while(!is_pll_locked(phy_reg));
  59. }
  60. }
  61. int sys_mipi_dsi_set_ppi_txbyte_hs(int enable, void *priv_data)
  62. {
  63. struct mipi_dsi_device *device = priv_data;
  64. struct udevice *dev = device->dev;
  65. struct dsi_sf_priv *priv = dev_get_priv(dev);
  66. static int status = 0;
  67. int ret;
  68. if (!enable && status) {
  69. status = 0;
  70. ret = reset_assert(&priv->txbytehs_rst);
  71. if (ret < 0) {
  72. return ret;
  73. }
  74. } else if (enable && !status) {
  75. status = 1;
  76. ret = reset_deassert(&priv->txbytehs_rst);
  77. if (ret < 0) {
  78. return ret;
  79. }
  80. }
  81. mdelay(100);
  82. return 0;
  83. }
  84. static void dsi_phy_post_set_mode(void *priv_data, unsigned long mode_flags)
  85. {
  86. struct mipi_dsi_device *device = priv_data;
  87. struct udevice *dev = device->dev;
  88. struct dsi_sf_priv *priv = dev_get_priv(dev);
  89. uint32_t bitrate;
  90. unsigned long alignment;
  91. int i;
  92. int ret;
  93. const struct m31_dphy_config *p;
  94. const uint32_t AON_POWER_READY_N_active = 0;
  95. debug("Set mode enable %ld\n",
  96. mode_flags & MIPI_DSI_MODE_VIDEO);
  97. if (!priv)
  98. return;
  99. // bitrate = 750000000;//1188M 60fps
  100. debug("dsi_phy_post_set_mode priv->timings.hactive.typ %d----\n",priv->timings.hactive.typ);
  101. debug("dsi_phy_post_set_mode priv->timings.vactive.typ %d----\n",priv->timings.vactive.typ);
  102. if (priv->timings.hactive.typ == 800)
  103. bitrate = 750000000;
  104. else if(priv->timings.hactive.typ == 1920)
  105. bitrate = 900000000;//1188M 60fps
  106. sf_dphy_set_reg(priv->phy_reg + 0x8, 0x10,
  107. RG_CDTX_L0N_HSTX_RES_SHIFT, RG_CDTX_L0N_HSTX_RES_MASK);
  108. sf_dphy_set_reg(priv->phy_reg + 0xC, 0x10,
  109. RG_CDTX_L0N_HSTX_RES_SHIFT, RG_CDTX_L0N_HSTX_RES_MASK);
  110. sf_dphy_set_reg(priv->phy_reg + 0xC, 0x10,
  111. RG_CDTX_L2N_HSTX_RES_SHIFT, RG_CDTX_L2N_HSTX_RES_MASK);
  112. sf_dphy_set_reg(priv->phy_reg + 0xC, 0x10,
  113. RG_CDTX_L3N_HSTX_RES_SHIFT, RG_CDTX_L3N_HSTX_RES_MASK);
  114. sf_dphy_set_reg(priv->phy_reg + 0x10, 0x10,
  115. RG_CDTX_L4N_HSTX_RES_SHIFT, RG_CDTX_L4N_HSTX_RES_MASK);
  116. sf_dphy_set_reg(priv->phy_reg + 0x8, 0x10,
  117. RG_CDTX_L0P_HSTX_RES_SHIFT, RG_CDTX_L0P_HSTX_RES_MASK);
  118. sf_dphy_set_reg(priv->phy_reg + 0xC, 0x10,
  119. RG_CDTX_L1P_HSTX_RES_SHIFT, RG_CDTX_L1P_HSTX_RES_MASK);
  120. sf_dphy_set_reg(priv->phy_reg + 0xC, 0x10,
  121. RG_CDTX_L2P_HSTX_RES_SHIFT, RG_CDTX_L2P_HSTX_RES_MASK);
  122. sf_dphy_set_reg(priv->phy_reg + 0xC, 0x10,
  123. RG_CDTX_L3P_HSTX_RES_SHIFT, RG_CDTX_L3P_HSTX_RES_MASK);
  124. sf_dphy_set_reg(priv->phy_reg + 0x10, 0x10,
  125. RG_CDTX_L4P_HSTX_RES_SHIFT, RG_CDTX_L4P_HSTX_RES_MASK);
  126. if (is_pll_locked(priv->phy_reg))
  127. debug("Error: MIPI dphy-tx # PLL is not supposed to be LOCKED\n");
  128. else
  129. debug("MIPI dphy-tx # PLL is not LOCKED\n");
  130. alignment = M31_DPHY_BITRATE_ALIGN;
  131. if (bitrate % alignment) {
  132. bitrate += alignment - (bitrate % alignment);
  133. }
  134. p = m31_dphy_configs;
  135. for (i = 0; i < ARRAY_SIZE(m31_dphy_configs); i++, p++) {
  136. if (p->bitrate == bitrate) {
  137. sf_dphy_set_reg(priv->phy_reg + 0x64, M31_DPHY_REFCLK, REFCLK_IN_SEL_SHIFT, REFCLK_IN_SEL_MASK);
  138. sf_dphy_set_reg(priv->phy_reg, AON_POWER_READY_N_active,
  139. AON_POWER_READY_N_SHIFT, AON_POWER_READY_N_MASK);
  140. sf_dphy_set_reg(priv->phy_reg, 0x0,
  141. CFG_L0_SWAP_SEL_SHIFT, CFG_L0_SWAP_SEL_MASK);//Lane setting
  142. sf_dphy_set_reg(priv->phy_reg, 0x1,
  143. CFG_L1_SWAP_SEL_SHIFT, CFG_L1_SWAP_SEL_MASK);
  144. #if CONFIG_IS_ENABLED(TARGET_STARFIVE_EVB)
  145. sf_dphy_set_reg(priv->phy_reg, 0x4,
  146. CFG_L2_SWAP_SEL_SHIFT, CFG_L2_SWAP_SEL_MASK);
  147. sf_dphy_set_reg(priv->phy_reg, 0x2,
  148. CFG_L3_SWAP_SEL_SHIFT, CFG_L3_SWAP_SEL_MASK);
  149. sf_dphy_set_reg(priv->phy_reg, 0x3,
  150. CFG_L4_SWAP_SEL_SHIFT, CFG_L4_SWAP_SEL_MASK);
  151. #else
  152. sf_dphy_set_reg(priv->phy_reg, 0x2,
  153. CFG_L2_SWAP_SEL_SHIFT, CFG_L2_SWAP_SEL_MASK);
  154. sf_dphy_set_reg(priv->phy_reg, 0x3,
  155. CFG_L3_SWAP_SEL_SHIFT, CFG_L3_SWAP_SEL_MASK);
  156. sf_dphy_set_reg(priv->phy_reg, 0x4,
  157. CFG_L4_SWAP_SEL_SHIFT, CFG_L4_SWAP_SEL_MASK);
  158. #endif
  159. //PLL setting
  160. sf_dphy_set_reg(priv->phy_reg + 0x1c, 0x0,
  161. RG_CDTX_PLL_SSC_EN_SHIFT, RG_CDTX_PLL_SSC_EN_MASK);
  162. sf_dphy_set_reg(priv->phy_reg + 0x18, 0x1,
  163. RG_CDTX_PLL_LDO_STB_X2_EN_SHIFT, RG_CDTX_PLL_LDO_STB_X2_EN_MASK);
  164. sf_dphy_set_reg(priv->phy_reg + 0x18, 0x1,
  165. RG_CDTX_PLL_FM_EN_SHIFT, RG_CDTX_PLL_FM_EN_MASK);
  166. sf_dphy_set_reg(priv->phy_reg + 0x18, p->pll_prev_div,
  167. RG_CDTX_PLL_PRE_DIV_SHIFT, RG_CDTX_PLL_PRE_DIV_MASK);
  168. sf_dphy_set_reg(priv->phy_reg + 0x18, p->pll_fbk_int,
  169. RG_CDTX_PLL_FBK_INT_SHIFT, RG_CDTX_PLL_FBK_INT_MASK);
  170. sf_dphy_set_reg(priv->phy_reg + 0x14, p->pll_fbk_fra,
  171. RG_CDTX_PLL_FBK_FRA_SHIFT, RG_CDTX_PLL_FBK_FRA_MASK);
  172. sf_dphy_set_reg(priv->phy_reg + 0x28, p->extd_cycle_sel,
  173. RG_EXTD_CYCLE_SEL_SHIFT, RG_EXTD_CYCLE_SEL_MASK);
  174. sf_dphy_set_reg(priv->phy_reg + 0x24, p->dlane_hs_pre_time,
  175. RG_DLANE_HS_PRE_TIME_SHIFT, RG_DLANE_HS_PRE_TIME_MASK);
  176. sf_dphy_set_reg(priv->phy_reg + 0x24, p->dlane_hs_pre_time,
  177. RG_DLANE_HS_PRE_TIME_SHIFT, RG_DLANE_HS_PRE_TIME_MASK);
  178. sf_dphy_set_reg(priv->phy_reg + 0x24, p->dlane_hs_zero_time,
  179. RG_DLANE_HS_ZERO_TIME_SHIFT, RG_DLANE_HS_ZERO_TIME_MASK);
  180. sf_dphy_set_reg(priv->phy_reg + 0x24, p->dlane_hs_trail_time,
  181. RG_DLANE_HS_TRAIL_TIME_SHIFT, RG_DLANE_HS_TRAIL_TIME_MASK);
  182. sf_dphy_set_reg(priv->phy_reg + 0x20, p->clane_hs_pre_time,
  183. RG_CLANE_HS_PRE_TIME_SHIFT, RG_CLANE_HS_PRE_TIME_MASK);
  184. sf_dphy_set_reg(priv->phy_reg + 0x24, p->clane_hs_zero_time,
  185. RG_CLANE_HS_ZERO_TIME_SHIFT, RG_CLANE_HS_ZERO_TIME_MASK);
  186. sf_dphy_set_reg(priv->phy_reg + 0x20, p->clane_hs_trail_time,
  187. RG_CLANE_HS_TRAIL_TIME_SHIFT, RG_CLANE_HS_TRAIL_TIME_MASK);
  188. sf_dphy_set_reg(priv->phy_reg + 0x20, p->clane_hs_clk_pre_time,
  189. RG_CLANE_HS_CLK_PRE_TIME_SHIFT, RG_CLANE_HS_CLK_PRE_TIME_MASK);
  190. sf_dphy_set_reg(priv->phy_reg + 0x20, p->clane_hs_clk_post_time,
  191. RG_CLANE_HS_CLK_POST_TIME_SHIFT, RG_CLANE_HS_CLK_POST_TIME_MASK);
  192. break;
  193. }
  194. }
  195. reset(0, priv->phy_reg);
  196. sf_dphy_set_reg(priv->phy_reg + 0x30, 0,
  197. SCFG_PPI_C_READY_SEL_SHIFT, SCFG_PPI_C_READY_SEL_MASK);
  198. sf_dphy_set_reg(priv->phy_reg + 0x30, 0,
  199. SCFG_DSI_TXREADY_ESC_SEL_SHIFT, SCFG_DSI_TXREADY_ESC_SEL_MASK);
  200. sf_dphy_set_reg(priv->phy_reg + 0x2c, 0x30,
  201. SCFG_C_HS_PRE_ZERO_TIME_SHIFT, SCFG_C_HS_PRE_ZERO_TIME_MASK);
  202. ret = clk_enable(&priv->dphy_txesc_clk);
  203. if (ret) {
  204. pr_err("failed to prepare/enable dphy_txesc_clk\n");
  205. return;
  206. }
  207. ret = reset_deassert(&priv->dphy_sys);
  208. if (ret < 0) {
  209. pr_err("failed to deassert dphy_sys\n");
  210. return;
  211. }
  212. ret = sys_mipi_dsi_set_ppi_txbyte_hs(1, priv_data);
  213. return;
  214. }
  215. static int dsi_get_lane_mbps(void *priv_data, struct display_timing *timings,
  216. u32 lanes, u32 format, unsigned int *lane_mbps)
  217. {
  218. return 0;
  219. }
  220. static const struct mipi_dsi_phy_ops dsi_stm_phy_ops = {
  221. .init = dsi_phy_init,
  222. .get_lane_mbps = dsi_get_lane_mbps,
  223. .post_set_mode = dsi_phy_post_set_mode,
  224. };
  225. static int dsi_sf_attach(struct udevice *dev)
  226. {
  227. struct dsi_sf_priv *priv = dev_get_priv(dev);
  228. struct mipi_dsi_device *device = &priv->device;
  229. struct mipi_dsi_panel_plat *mplat;
  230. struct display_timing timings;
  231. int ret;
  232. #if CONFIG_IS_ENABLED(TARGET_STARFIVE_DEVKITS)
  233. ret = uclass_get_device_by_name(UCLASS_PANEL, "seeed_panel@45", &priv->panel);
  234. if (ret) {
  235. debug("Could not get seeed_panel@45: %d\n", ret);
  236. ret = uclass_get_device_by_name(UCLASS_PANEL, "lt8911exb_i2c@29", &priv->panel);
  237. if (ret) {
  238. debug("Could not get lt8911exb_i2c@29: %d\n", ret);
  239. return ret;
  240. }
  241. }
  242. #else
  243. ret = uclass_first_device(UCLASS_PANEL, &priv->panel);
  244. if (ret) {
  245. debug("panel device error %d\n", ret);
  246. return ret;
  247. }
  248. #endif
  249. debug("%s,priv->panel->name = %s\n", __func__,priv->panel->name);
  250. mplat = dev_get_plat(priv->panel);
  251. mplat->device = &priv->device;
  252. device->lanes = mplat->lanes;
  253. device->format = mplat->format;
  254. device->mode_flags = mplat->mode_flags;
  255. ret = panel_get_display_timing(priv->panel, &timings);
  256. if (ret) {
  257. ret = ofnode_decode_display_timing(dev_ofnode(priv->panel),
  258. 0, &timings);
  259. if (ret) {
  260. debug("decode display timing error %d\n", ret);
  261. return ret;
  262. }
  263. }
  264. priv->timings = timings;
  265. ret = uclass_get_device(UCLASS_DSI_HOST, 0, &priv->dsi_host);
  266. if (ret) {
  267. debug("No video dsi host detected %d\n", ret);
  268. return ret;
  269. }
  270. ret = dsi_host_init(priv->dsi_host, device, &timings,
  271. mplat->lanes,
  272. &dsi_stm_phy_ops);
  273. if (ret) {
  274. debug("failed to initialize mipi dsi host\n");
  275. return ret;
  276. }
  277. return 0;
  278. }
  279. static int dsi_sf_set_backlight(struct udevice *dev, int percent)
  280. {
  281. struct dsi_sf_priv *priv = dev_get_priv(dev);
  282. int ret;
  283. ret = dsi_host_enable(priv->dsi_host);
  284. if (ret) {
  285. debug("failed to enable mipi dsi host\n");
  286. return ret;
  287. }
  288. ret = panel_enable_backlight(priv->panel);
  289. if (ret) {
  290. debug("panel %s enable backlight error %d\n",
  291. priv->panel->name, ret);
  292. return ret;
  293. }
  294. return 0;
  295. }
  296. static int sf_mipi_of_to_plat(struct udevice *dev)
  297. {
  298. struct dsi_sf_priv *priv = dev_get_priv(dev);
  299. int ret = 0;
  300. priv->dsi_reg = dev_remap_addr_name(dev, "dsi");
  301. if (!priv->dsi_reg)
  302. return -EINVAL;
  303. priv->phy_reg = dev_remap_addr_name(dev, "phy");
  304. if (!priv->phy_reg)
  305. return -EINVAL;
  306. priv->sys_reg = dev_remap_addr_name(dev, "syscon");
  307. if (!priv->phy_reg)
  308. return -EINVAL;
  309. ret = clk_get_by_name(dev, "sys", &priv->dsi_sys_clk);
  310. if (ret) {
  311. pr_err("clk_get_by_name(dsi_sys_clk) failed: %d", ret);
  312. return ret;
  313. }
  314. ret = clk_get_by_name(dev, "apb", &priv->apb_clk);
  315. if (ret) {
  316. pr_err("clk_get_by_name(apb_clk) failed: %d\n", ret);
  317. return ret;
  318. }
  319. ret = clk_get_by_name(dev, "txesc", &priv->txesc_clk);
  320. if (ret) {
  321. pr_err("clk_get_by_name(txesc_clk) failed: %d\n", ret);
  322. return ret;
  323. }
  324. ret = clk_get_by_name(dev, "dpi", &priv->dpi_clk);
  325. if (ret) {
  326. pr_err("clk_get_by_name(dpi_clk) failed: %d\n", ret);
  327. return ret;
  328. }
  329. ret = clk_get_by_name(dev, "dphy_txesc", &priv->dphy_txesc_clk);
  330. if (ret) {
  331. pr_err("clk_get_by_name(dphy_txesc_clk) failed: %d\n", ret);
  332. return ret;
  333. }
  334. ret = reset_get_by_name(dev, "dsi_dpi", &priv->dpi_rst);
  335. if (ret) {
  336. pr_err("failed to get dpi_rst reset (ret=%d)\n", ret);
  337. return ret;
  338. }
  339. ret = reset_get_by_name(dev, "dsi_apb", &priv->apb_rst);
  340. if (ret) {
  341. pr_err("failed to get apb_rst reset (ret=%d)\n", ret);
  342. return ret;
  343. }
  344. ret = reset_get_by_name(dev, "dsi_rxesc", &priv->rxesc_rst);
  345. if (ret) {
  346. pr_err("failed to get rxesc_rst reset (ret=%d)\n", ret);
  347. return ret;
  348. }
  349. ret = reset_get_by_name(dev, "dsi_sys", &priv->sys_rst);
  350. if (ret) {
  351. pr_err("failed to get sys_rst reset (ret=%d)\n", ret);
  352. return ret;
  353. }
  354. ret = reset_get_by_name(dev, "dsi_txbytehs", &priv->txbytehs_rst);
  355. if (ret) {
  356. pr_err("failed to get txbytehs_rst reset (ret=%d)\n", ret);
  357. return ret;
  358. }
  359. ret = reset_get_by_name(dev, "dsi_txesc", &priv->txesc_rst);
  360. if (ret) {
  361. pr_err("failed to get txesc_rst reset (ret=%d)\n", ret);
  362. return ret;
  363. }
  364. ret = reset_get_by_name(dev, "dphy_sys", &priv->dphy_sys);
  365. if (ret) {
  366. pr_err("failed to get dphy_sys reset (ret=%d)\n", ret);
  367. return ret;
  368. }
  369. ret = reset_get_by_name(dev, "dphy_txbytehs", &priv->dphy_txbytehs);
  370. if (ret) {
  371. pr_err("failed to get dphy_txbytehs reset (ret=%d)\n", ret);
  372. return ret;
  373. }
  374. return 0;
  375. }
  376. static int cdns_check_register_access(struct udevice *dev)
  377. {
  378. struct dsi_sf_priv *priv = dev_get_priv(dev);
  379. const uint16_t ctrl_patterns[] = {0x0000, 0xffff, 0xa5a5, 0x5a5a};
  380. int i;
  381. uint32_t rd_val;
  382. for (i = 0; i < ARRAY_SIZE_DSI(ctrl_patterns); i++) {
  383. uint32_t temp = readl(priv->dsi_reg + TEST_GENERIC);
  384. temp &= ~0xffff;
  385. temp |= TEST_CTRL(ctrl_patterns[i]);
  386. writel(temp, priv->dsi_reg + TEST_GENERIC);
  387. rd_val = readl(priv->dsi_reg + TEST_GENERIC);
  388. if (rd_val != temp) {
  389. return 1;
  390. }
  391. }
  392. return 0;
  393. }
  394. static int dsi_sf_probe(struct udevice *dev)
  395. {
  396. struct dsi_sf_priv *priv = dev_get_priv(dev);
  397. struct mipi_dsi_device *device = &priv->device;
  398. int ret;
  399. unsigned long rate;
  400. uint32_t val;
  401. device->dev = dev;
  402. ret = dev_read_u32(dev, "data-lanes-num", &priv->data_lanes);
  403. if (ret) {
  404. debug("fail to get data lanes property %d\n", ret);
  405. return 0;
  406. }
  407. ret = clk_enable(&priv->dsi_sys_clk);
  408. if (ret < 0) {
  409. pr_err("clk_enable(dsi_sys_clk) failed: %d\n", ret);
  410. return ret;
  411. }
  412. ret = clk_enable(&priv->apb_clk);
  413. if (ret < 0) {
  414. pr_err("clk_enable(apb_clk) failed: %d\n", ret);
  415. goto free_clock_apb_clk;
  416. }
  417. ret = clk_enable(&priv->txesc_clk);
  418. if (ret < 0) {
  419. pr_err("clk_enable(txesc_clk) failed: %d\n", ret);
  420. goto free_clock_txesc_clk;
  421. }
  422. ret = clk_enable(&priv->dpi_clk);
  423. if (ret < 0) {
  424. pr_err("clk_enable(dpi_clk) failed: %d\n", ret);
  425. goto free_clock_dpi_clk;
  426. }
  427. ret = reset_deassert(&priv->sys_rst);
  428. if (ret < 0) {
  429. pr_err("failed to deassert sys_rst\n");
  430. goto free_reset;
  431. }
  432. ret = reset_deassert(&priv->apb_rst);
  433. if (ret) {
  434. pr_err("failed to deassert apb_rst reset (ret=%d)\n", ret);
  435. goto free_reset;
  436. }
  437. ret = reset_deassert(&priv->txesc_rst);
  438. if (ret) {
  439. pr_err("failed to deassert txesc_rst reset (ret=%d)\n", ret);
  440. goto free_reset;
  441. }
  442. ret = reset_deassert(&priv->rxesc_rst);
  443. if (ret) {
  444. pr_err("failed to deassert rxesc_rst reset (ret=%d)\n", ret);
  445. goto free_reset;
  446. }
  447. ret = reset_deassert(&priv->dpi_rst);
  448. if (ret) {
  449. pr_err("failed to deassert dpi_rst reset (ret=%d)\n", ret);
  450. goto free_reset;
  451. }
  452. rate = clk_get_rate(&priv->dsi_sys_clk);
  453. debug("%s ok: dsi_sys_clk rate = %ld\n", __func__, rate);
  454. val = readl(priv->dsi_reg + ID_REG);
  455. debug("%s ok: ID_REG val = %08x\n", __func__, val);
  456. if (REV_VENDOR_ID(val) != 0xcad) {
  457. debug("invalid vendor id\n");
  458. ret = -EINVAL;
  459. }
  460. ret = cdns_check_register_access(dev);
  461. if (ret) {
  462. debug("error: r/w test generic reg failed\n");
  463. }
  464. val = readl(priv->dsi_reg + IP_CONF);
  465. priv->direct_cmd_fifo_depth = 1 << (DIRCMD_FIFO_DEPTH(val) + 2);
  466. priv->rx_fifo_depth = RX_FIFO_DEPTH(val);
  467. writel(0, priv->dsi_reg + MCTL_MAIN_DATA_CTL);
  468. writel(0, priv->dsi_reg + MCTL_MAIN_EN);
  469. writel(0, priv->dsi_reg + MCTL_MAIN_PHY_CTL);
  470. /* Mask all interrupts before registering the IRQ handler. */
  471. writel(0, priv->dsi_reg + MCTL_MAIN_STS_CTL);
  472. writel(0, priv->dsi_reg + MCTL_DPHY_ERR_CTL1);
  473. writel(0, priv->dsi_reg + CMD_MODE_STS_CTL);
  474. writel(0, priv->dsi_reg + DIRECT_CMD_STS_CTL);
  475. writel(0, priv->dsi_reg + DIRECT_CMD_RD_STS_CTL);
  476. writel(0, priv->dsi_reg + VID_MODE_STS_CTL);
  477. writel(0, priv->dsi_reg + TVG_STS_CTL);
  478. writel(0, priv->dsi_reg + DPI_IRQ_EN);
  479. return ret;
  480. free_reset:
  481. clk_disable(&priv->dpi_clk);
  482. free_clock_dpi_clk:
  483. clk_disable(&priv->txesc_clk);
  484. free_clock_txesc_clk:
  485. clk_disable(&priv->apb_clk);
  486. free_clock_apb_clk:
  487. clk_disable(&priv->dsi_sys_clk);
  488. return ret;
  489. }
  490. struct video_bridge_ops sf_dsi_bridge_ops = {
  491. .attach = dsi_sf_attach,
  492. .set_backlight = dsi_sf_set_backlight,
  493. };
  494. static const struct udevice_id sf_mipi_dsi_ids[] = {
  495. { .compatible = "starfive,sf_mipi_dsi" },
  496. { }
  497. };
  498. U_BOOT_DRIVER(starfive_mipi_dsi) = {
  499. .name = "starfive_mipi_dsi",
  500. .id = UCLASS_VIDEO_BRIDGE,
  501. .of_match = sf_mipi_dsi_ids,
  502. .bind = dm_scan_fdt_dev,
  503. .of_to_plat = sf_mipi_of_to_plat,
  504. .probe = dsi_sf_probe,
  505. .ops = &sf_dsi_bridge_ops,
  506. .priv_auto = sizeof(struct dsi_sf_priv),
  507. };