sf_mipi.c 16 KB

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