zx_vou.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922
  1. /*
  2. * Copyright 2016 Linaro Ltd.
  3. * Copyright 2016 ZTE Corporation.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. */
  10. #include <linux/clk.h>
  11. #include <linux/component.h>
  12. #include <linux/of_address.h>
  13. #include <video/videomode.h>
  14. #include <drm/drm_atomic_helper.h>
  15. #include <drm/drm_crtc.h>
  16. #include <drm/drm_crtc_helper.h>
  17. #include <drm/drm_fb_cma_helper.h>
  18. #include <drm/drm_fb_helper.h>
  19. #include <drm/drm_gem_cma_helper.h>
  20. #include <drm/drm_of.h>
  21. #include <drm/drm_plane_helper.h>
  22. #include <drm/drmP.h>
  23. #include "zx_common_regs.h"
  24. #include "zx_drm_drv.h"
  25. #include "zx_plane.h"
  26. #include "zx_vou.h"
  27. #include "zx_vou_regs.h"
  28. #define GL_NUM 2
  29. #define VL_NUM 3
  30. enum vou_chn_type {
  31. VOU_CHN_MAIN,
  32. VOU_CHN_AUX,
  33. };
  34. struct zx_crtc_regs {
  35. u32 fir_active;
  36. u32 fir_htiming;
  37. u32 fir_vtiming;
  38. u32 sec_vtiming;
  39. u32 timing_shift;
  40. u32 timing_pi_shift;
  41. };
  42. static const struct zx_crtc_regs main_crtc_regs = {
  43. .fir_active = FIR_MAIN_ACTIVE,
  44. .fir_htiming = FIR_MAIN_H_TIMING,
  45. .fir_vtiming = FIR_MAIN_V_TIMING,
  46. .sec_vtiming = SEC_MAIN_V_TIMING,
  47. .timing_shift = TIMING_MAIN_SHIFT,
  48. .timing_pi_shift = TIMING_MAIN_PI_SHIFT,
  49. };
  50. static const struct zx_crtc_regs aux_crtc_regs = {
  51. .fir_active = FIR_AUX_ACTIVE,
  52. .fir_htiming = FIR_AUX_H_TIMING,
  53. .fir_vtiming = FIR_AUX_V_TIMING,
  54. .sec_vtiming = SEC_AUX_V_TIMING,
  55. .timing_shift = TIMING_AUX_SHIFT,
  56. .timing_pi_shift = TIMING_AUX_PI_SHIFT,
  57. };
  58. struct zx_crtc_bits {
  59. u32 polarity_mask;
  60. u32 polarity_shift;
  61. u32 int_frame_mask;
  62. u32 tc_enable;
  63. u32 sec_vactive_shift;
  64. u32 sec_vactive_mask;
  65. u32 interlace_select;
  66. u32 pi_enable;
  67. u32 div_vga_shift;
  68. u32 div_pic_shift;
  69. u32 div_tvenc_shift;
  70. u32 div_hdmi_pnx_shift;
  71. u32 div_hdmi_shift;
  72. u32 div_inf_shift;
  73. u32 div_layer_shift;
  74. };
  75. static const struct zx_crtc_bits main_crtc_bits = {
  76. .polarity_mask = MAIN_POL_MASK,
  77. .polarity_shift = MAIN_POL_SHIFT,
  78. .int_frame_mask = TIMING_INT_MAIN_FRAME,
  79. .tc_enable = MAIN_TC_EN,
  80. .sec_vactive_shift = SEC_VACT_MAIN_SHIFT,
  81. .sec_vactive_mask = SEC_VACT_MAIN_MASK,
  82. .interlace_select = MAIN_INTERLACE_SEL,
  83. .pi_enable = MAIN_PI_EN,
  84. .div_vga_shift = VGA_MAIN_DIV_SHIFT,
  85. .div_pic_shift = PIC_MAIN_DIV_SHIFT,
  86. .div_tvenc_shift = TVENC_MAIN_DIV_SHIFT,
  87. .div_hdmi_pnx_shift = HDMI_MAIN_PNX_DIV_SHIFT,
  88. .div_hdmi_shift = HDMI_MAIN_DIV_SHIFT,
  89. .div_inf_shift = INF_MAIN_DIV_SHIFT,
  90. .div_layer_shift = LAYER_MAIN_DIV_SHIFT,
  91. };
  92. static const struct zx_crtc_bits aux_crtc_bits = {
  93. .polarity_mask = AUX_POL_MASK,
  94. .polarity_shift = AUX_POL_SHIFT,
  95. .int_frame_mask = TIMING_INT_AUX_FRAME,
  96. .tc_enable = AUX_TC_EN,
  97. .sec_vactive_shift = SEC_VACT_AUX_SHIFT,
  98. .sec_vactive_mask = SEC_VACT_AUX_MASK,
  99. .interlace_select = AUX_INTERLACE_SEL,
  100. .pi_enable = AUX_PI_EN,
  101. .div_vga_shift = VGA_AUX_DIV_SHIFT,
  102. .div_pic_shift = PIC_AUX_DIV_SHIFT,
  103. .div_tvenc_shift = TVENC_AUX_DIV_SHIFT,
  104. .div_hdmi_pnx_shift = HDMI_AUX_PNX_DIV_SHIFT,
  105. .div_hdmi_shift = HDMI_AUX_DIV_SHIFT,
  106. .div_inf_shift = INF_AUX_DIV_SHIFT,
  107. .div_layer_shift = LAYER_AUX_DIV_SHIFT,
  108. };
  109. struct zx_crtc {
  110. struct drm_crtc crtc;
  111. struct drm_plane *primary;
  112. struct zx_vou_hw *vou;
  113. void __iomem *chnreg;
  114. void __iomem *chncsc;
  115. void __iomem *dither;
  116. const struct zx_crtc_regs *regs;
  117. const struct zx_crtc_bits *bits;
  118. enum vou_chn_type chn_type;
  119. struct clk *pixclk;
  120. };
  121. #define to_zx_crtc(x) container_of(x, struct zx_crtc, crtc)
  122. struct vou_layer_bits {
  123. u32 enable;
  124. u32 chnsel;
  125. u32 clksel;
  126. };
  127. static const struct vou_layer_bits zx_gl_bits[GL_NUM] = {
  128. {
  129. .enable = OSD_CTRL0_GL0_EN,
  130. .chnsel = OSD_CTRL0_GL0_SEL,
  131. .clksel = VOU_CLK_GL0_SEL,
  132. }, {
  133. .enable = OSD_CTRL0_GL1_EN,
  134. .chnsel = OSD_CTRL0_GL1_SEL,
  135. .clksel = VOU_CLK_GL1_SEL,
  136. },
  137. };
  138. static const struct vou_layer_bits zx_vl_bits[VL_NUM] = {
  139. {
  140. .enable = OSD_CTRL0_VL0_EN,
  141. .chnsel = OSD_CTRL0_VL0_SEL,
  142. .clksel = VOU_CLK_VL0_SEL,
  143. }, {
  144. .enable = OSD_CTRL0_VL1_EN,
  145. .chnsel = OSD_CTRL0_VL1_SEL,
  146. .clksel = VOU_CLK_VL1_SEL,
  147. }, {
  148. .enable = OSD_CTRL0_VL2_EN,
  149. .chnsel = OSD_CTRL0_VL2_SEL,
  150. .clksel = VOU_CLK_VL2_SEL,
  151. },
  152. };
  153. struct zx_vou_hw {
  154. struct device *dev;
  155. void __iomem *osd;
  156. void __iomem *timing;
  157. void __iomem *vouctl;
  158. void __iomem *otfppu;
  159. void __iomem *dtrc;
  160. struct clk *axi_clk;
  161. struct clk *ppu_clk;
  162. struct clk *main_clk;
  163. struct clk *aux_clk;
  164. struct zx_crtc *main_crtc;
  165. struct zx_crtc *aux_crtc;
  166. };
  167. enum vou_inf_data_sel {
  168. VOU_YUV444 = 0,
  169. VOU_RGB_101010 = 1,
  170. VOU_RGB_888 = 2,
  171. VOU_RGB_666 = 3,
  172. };
  173. struct vou_inf {
  174. enum vou_inf_id id;
  175. enum vou_inf_data_sel data_sel;
  176. u32 clocks_en_bits;
  177. u32 clocks_sel_bits;
  178. };
  179. static struct vou_inf vou_infs[] = {
  180. [VOU_HDMI] = {
  181. .data_sel = VOU_YUV444,
  182. .clocks_en_bits = BIT(24) | BIT(18) | BIT(6),
  183. .clocks_sel_bits = BIT(13) | BIT(2),
  184. },
  185. [VOU_TV_ENC] = {
  186. .data_sel = VOU_YUV444,
  187. .clocks_en_bits = BIT(15),
  188. .clocks_sel_bits = BIT(11) | BIT(0),
  189. },
  190. [VOU_VGA] = {
  191. .data_sel = VOU_RGB_888,
  192. .clocks_en_bits = BIT(1),
  193. .clocks_sel_bits = BIT(10),
  194. },
  195. };
  196. static inline struct zx_vou_hw *crtc_to_vou(struct drm_crtc *crtc)
  197. {
  198. struct zx_crtc *zcrtc = to_zx_crtc(crtc);
  199. return zcrtc->vou;
  200. }
  201. void vou_inf_hdmi_audio_sel(struct drm_crtc *crtc,
  202. enum vou_inf_hdmi_audio aud)
  203. {
  204. struct zx_crtc *zcrtc = to_zx_crtc(crtc);
  205. struct zx_vou_hw *vou = zcrtc->vou;
  206. zx_writel_mask(vou->vouctl + VOU_INF_HDMI_CTRL, VOU_HDMI_AUD_MASK, aud);
  207. }
  208. void vou_inf_enable(enum vou_inf_id id, struct drm_crtc *crtc)
  209. {
  210. struct zx_crtc *zcrtc = to_zx_crtc(crtc);
  211. struct zx_vou_hw *vou = zcrtc->vou;
  212. struct vou_inf *inf = &vou_infs[id];
  213. void __iomem *dither = zcrtc->dither;
  214. void __iomem *csc = zcrtc->chncsc;
  215. bool is_main = zcrtc->chn_type == VOU_CHN_MAIN;
  216. u32 data_sel_shift = id << 1;
  217. if (inf->data_sel != VOU_YUV444) {
  218. /* Enable channel CSC for RGB output */
  219. zx_writel_mask(csc + CSC_CTRL0, CSC_COV_MODE_MASK,
  220. CSC_BT709_IMAGE_YCBCR2RGB << CSC_COV_MODE_SHIFT);
  221. zx_writel_mask(csc + CSC_CTRL0, CSC_WORK_ENABLE,
  222. CSC_WORK_ENABLE);
  223. /* Bypass Dither block for RGB output */
  224. zx_writel_mask(dither + OSD_DITHER_CTRL0, DITHER_BYSPASS,
  225. DITHER_BYSPASS);
  226. } else {
  227. zx_writel_mask(csc + CSC_CTRL0, CSC_WORK_ENABLE, 0);
  228. zx_writel_mask(dither + OSD_DITHER_CTRL0, DITHER_BYSPASS, 0);
  229. }
  230. /* Select data format */
  231. zx_writel_mask(vou->vouctl + VOU_INF_DATA_SEL, 0x3 << data_sel_shift,
  232. inf->data_sel << data_sel_shift);
  233. /* Select channel */
  234. zx_writel_mask(vou->vouctl + VOU_INF_CH_SEL, 0x1 << id,
  235. zcrtc->chn_type << id);
  236. /* Select interface clocks */
  237. zx_writel_mask(vou->vouctl + VOU_CLK_SEL, inf->clocks_sel_bits,
  238. is_main ? 0 : inf->clocks_sel_bits);
  239. /* Enable interface clocks */
  240. zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits,
  241. inf->clocks_en_bits);
  242. /* Enable the device */
  243. zx_writel_mask(vou->vouctl + VOU_INF_EN, 1 << id, 1 << id);
  244. }
  245. void vou_inf_disable(enum vou_inf_id id, struct drm_crtc *crtc)
  246. {
  247. struct zx_vou_hw *vou = crtc_to_vou(crtc);
  248. struct vou_inf *inf = &vou_infs[id];
  249. /* Disable the device */
  250. zx_writel_mask(vou->vouctl + VOU_INF_EN, 1 << id, 0);
  251. /* Disable interface clocks */
  252. zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits, 0);
  253. }
  254. void zx_vou_config_dividers(struct drm_crtc *crtc,
  255. struct vou_div_config *configs, int num)
  256. {
  257. struct zx_crtc *zcrtc = to_zx_crtc(crtc);
  258. struct zx_vou_hw *vou = zcrtc->vou;
  259. const struct zx_crtc_bits *bits = zcrtc->bits;
  260. int i;
  261. /* Clear update flag bit */
  262. zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE, 0);
  263. for (i = 0; i < num; i++) {
  264. struct vou_div_config *cfg = configs + i;
  265. u32 reg, shift;
  266. switch (cfg->id) {
  267. case VOU_DIV_VGA:
  268. reg = VOU_CLK_SEL;
  269. shift = bits->div_vga_shift;
  270. break;
  271. case VOU_DIV_PIC:
  272. reg = VOU_CLK_SEL;
  273. shift = bits->div_pic_shift;
  274. break;
  275. case VOU_DIV_TVENC:
  276. reg = VOU_DIV_PARA;
  277. shift = bits->div_tvenc_shift;
  278. break;
  279. case VOU_DIV_HDMI_PNX:
  280. reg = VOU_DIV_PARA;
  281. shift = bits->div_hdmi_pnx_shift;
  282. break;
  283. case VOU_DIV_HDMI:
  284. reg = VOU_DIV_PARA;
  285. shift = bits->div_hdmi_shift;
  286. break;
  287. case VOU_DIV_INF:
  288. reg = VOU_DIV_PARA;
  289. shift = bits->div_inf_shift;
  290. break;
  291. case VOU_DIV_LAYER:
  292. reg = VOU_DIV_PARA;
  293. shift = bits->div_layer_shift;
  294. break;
  295. default:
  296. continue;
  297. }
  298. /* Each divider occupies 3 bits */
  299. zx_writel_mask(vou->vouctl + reg, 0x7 << shift,
  300. cfg->val << shift);
  301. }
  302. /* Set update flag bit to get dividers effected */
  303. zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE,
  304. DIV_PARA_UPDATE);
  305. }
  306. static inline void vou_chn_set_update(struct zx_crtc *zcrtc)
  307. {
  308. zx_writel(zcrtc->chnreg + CHN_UPDATE, 1);
  309. }
  310. static void zx_crtc_atomic_enable(struct drm_crtc *crtc,
  311. struct drm_crtc_state *old_state)
  312. {
  313. struct drm_display_mode *mode = &crtc->state->adjusted_mode;
  314. bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE;
  315. struct zx_crtc *zcrtc = to_zx_crtc(crtc);
  316. struct zx_vou_hw *vou = zcrtc->vou;
  317. const struct zx_crtc_regs *regs = zcrtc->regs;
  318. const struct zx_crtc_bits *bits = zcrtc->bits;
  319. struct videomode vm;
  320. u32 scan_mask;
  321. u32 pol = 0;
  322. u32 val;
  323. int ret;
  324. drm_display_mode_to_videomode(mode, &vm);
  325. /* Set up timing parameters */
  326. val = V_ACTIVE((interlaced ? vm.vactive / 2 : vm.vactive) - 1);
  327. val |= H_ACTIVE(vm.hactive - 1);
  328. zx_writel(vou->timing + regs->fir_active, val);
  329. val = SYNC_WIDE(vm.hsync_len - 1);
  330. val |= BACK_PORCH(vm.hback_porch - 1);
  331. val |= FRONT_PORCH(vm.hfront_porch - 1);
  332. zx_writel(vou->timing + regs->fir_htiming, val);
  333. val = SYNC_WIDE(vm.vsync_len - 1);
  334. val |= BACK_PORCH(vm.vback_porch - 1);
  335. val |= FRONT_PORCH(vm.vfront_porch - 1);
  336. zx_writel(vou->timing + regs->fir_vtiming, val);
  337. if (interlaced) {
  338. u32 shift = bits->sec_vactive_shift;
  339. u32 mask = bits->sec_vactive_mask;
  340. val = zx_readl(vou->timing + SEC_V_ACTIVE);
  341. val &= ~mask;
  342. val |= ((vm.vactive / 2 - 1) << shift) & mask;
  343. zx_writel(vou->timing + SEC_V_ACTIVE, val);
  344. val = SYNC_WIDE(vm.vsync_len - 1);
  345. /*
  346. * The vback_porch for the second field needs to shift one on
  347. * the value for the first field.
  348. */
  349. val |= BACK_PORCH(vm.vback_porch);
  350. val |= FRONT_PORCH(vm.vfront_porch - 1);
  351. zx_writel(vou->timing + regs->sec_vtiming, val);
  352. }
  353. /* Set up polarities */
  354. if (vm.flags & DISPLAY_FLAGS_VSYNC_LOW)
  355. pol |= 1 << POL_VSYNC_SHIFT;
  356. if (vm.flags & DISPLAY_FLAGS_HSYNC_LOW)
  357. pol |= 1 << POL_HSYNC_SHIFT;
  358. zx_writel_mask(vou->timing + TIMING_CTRL, bits->polarity_mask,
  359. pol << bits->polarity_shift);
  360. /* Setup SHIFT register by following what ZTE BSP does */
  361. val = H_SHIFT_VAL;
  362. if (interlaced)
  363. val |= V_SHIFT_VAL << 16;
  364. zx_writel(vou->timing + regs->timing_shift, val);
  365. zx_writel(vou->timing + regs->timing_pi_shift, H_PI_SHIFT_VAL);
  366. /* Progressive or interlace scan select */
  367. scan_mask = bits->interlace_select | bits->pi_enable;
  368. zx_writel_mask(vou->timing + SCAN_CTRL, scan_mask,
  369. interlaced ? scan_mask : 0);
  370. /* Enable TIMING_CTRL */
  371. zx_writel_mask(vou->timing + TIMING_TC_ENABLE, bits->tc_enable,
  372. bits->tc_enable);
  373. /* Configure channel screen size */
  374. zx_writel_mask(zcrtc->chnreg + CHN_CTRL1, CHN_SCREEN_W_MASK,
  375. vm.hactive << CHN_SCREEN_W_SHIFT);
  376. zx_writel_mask(zcrtc->chnreg + CHN_CTRL1, CHN_SCREEN_H_MASK,
  377. vm.vactive << CHN_SCREEN_H_SHIFT);
  378. /* Configure channel interlace buffer control */
  379. zx_writel_mask(zcrtc->chnreg + CHN_INTERLACE_BUF_CTRL, CHN_INTERLACE_EN,
  380. interlaced ? CHN_INTERLACE_EN : 0);
  381. /* Update channel */
  382. vou_chn_set_update(zcrtc);
  383. /* Enable channel */
  384. zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, CHN_ENABLE);
  385. drm_crtc_vblank_on(crtc);
  386. ret = clk_set_rate(zcrtc->pixclk, mode->clock * 1000);
  387. if (ret) {
  388. DRM_DEV_ERROR(vou->dev, "failed to set pixclk rate: %d\n", ret);
  389. return;
  390. }
  391. ret = clk_prepare_enable(zcrtc->pixclk);
  392. if (ret)
  393. DRM_DEV_ERROR(vou->dev, "failed to enable pixclk: %d\n", ret);
  394. }
  395. static void zx_crtc_atomic_disable(struct drm_crtc *crtc,
  396. struct drm_crtc_state *old_state)
  397. {
  398. struct zx_crtc *zcrtc = to_zx_crtc(crtc);
  399. const struct zx_crtc_bits *bits = zcrtc->bits;
  400. struct zx_vou_hw *vou = zcrtc->vou;
  401. clk_disable_unprepare(zcrtc->pixclk);
  402. drm_crtc_vblank_off(crtc);
  403. /* Disable channel */
  404. zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, 0);
  405. /* Disable TIMING_CTRL */
  406. zx_writel_mask(vou->timing + TIMING_TC_ENABLE, bits->tc_enable, 0);
  407. }
  408. static void zx_crtc_atomic_flush(struct drm_crtc *crtc,
  409. struct drm_crtc_state *old_state)
  410. {
  411. struct drm_pending_vblank_event *event = crtc->state->event;
  412. if (!event)
  413. return;
  414. crtc->state->event = NULL;
  415. spin_lock_irq(&crtc->dev->event_lock);
  416. if (drm_crtc_vblank_get(crtc) == 0)
  417. drm_crtc_arm_vblank_event(crtc, event);
  418. else
  419. drm_crtc_send_vblank_event(crtc, event);
  420. spin_unlock_irq(&crtc->dev->event_lock);
  421. }
  422. static const struct drm_crtc_helper_funcs zx_crtc_helper_funcs = {
  423. .atomic_flush = zx_crtc_atomic_flush,
  424. .atomic_enable = zx_crtc_atomic_enable,
  425. .atomic_disable = zx_crtc_atomic_disable,
  426. };
  427. static int zx_vou_enable_vblank(struct drm_crtc *crtc)
  428. {
  429. struct zx_crtc *zcrtc = to_zx_crtc(crtc);
  430. struct zx_vou_hw *vou = crtc_to_vou(crtc);
  431. u32 int_frame_mask = zcrtc->bits->int_frame_mask;
  432. zx_writel_mask(vou->timing + TIMING_INT_CTRL, int_frame_mask,
  433. int_frame_mask);
  434. return 0;
  435. }
  436. static void zx_vou_disable_vblank(struct drm_crtc *crtc)
  437. {
  438. struct zx_crtc *zcrtc = to_zx_crtc(crtc);
  439. struct zx_vou_hw *vou = crtc_to_vou(crtc);
  440. zx_writel_mask(vou->timing + TIMING_INT_CTRL,
  441. zcrtc->bits->int_frame_mask, 0);
  442. }
  443. static const struct drm_crtc_funcs zx_crtc_funcs = {
  444. .destroy = drm_crtc_cleanup,
  445. .set_config = drm_atomic_helper_set_config,
  446. .page_flip = drm_atomic_helper_page_flip,
  447. .reset = drm_atomic_helper_crtc_reset,
  448. .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
  449. .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
  450. .enable_vblank = zx_vou_enable_vblank,
  451. .disable_vblank = zx_vou_disable_vblank,
  452. };
  453. static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou,
  454. enum vou_chn_type chn_type)
  455. {
  456. struct device *dev = vou->dev;
  457. struct zx_plane *zplane;
  458. struct zx_crtc *zcrtc;
  459. int ret;
  460. zcrtc = devm_kzalloc(dev, sizeof(*zcrtc), GFP_KERNEL);
  461. if (!zcrtc)
  462. return -ENOMEM;
  463. zcrtc->vou = vou;
  464. zcrtc->chn_type = chn_type;
  465. zplane = devm_kzalloc(dev, sizeof(*zplane), GFP_KERNEL);
  466. if (!zplane)
  467. return -ENOMEM;
  468. zplane->dev = dev;
  469. if (chn_type == VOU_CHN_MAIN) {
  470. zplane->layer = vou->osd + MAIN_GL_OFFSET;
  471. zplane->csc = vou->osd + MAIN_GL_CSC_OFFSET;
  472. zplane->hbsc = vou->osd + MAIN_HBSC_OFFSET;
  473. zplane->rsz = vou->otfppu + MAIN_RSZ_OFFSET;
  474. zplane->bits = &zx_gl_bits[0];
  475. zcrtc->chnreg = vou->osd + OSD_MAIN_CHN;
  476. zcrtc->chncsc = vou->osd + MAIN_CHN_CSC_OFFSET;
  477. zcrtc->dither = vou->osd + MAIN_DITHER_OFFSET;
  478. zcrtc->regs = &main_crtc_regs;
  479. zcrtc->bits = &main_crtc_bits;
  480. } else {
  481. zplane->layer = vou->osd + AUX_GL_OFFSET;
  482. zplane->csc = vou->osd + AUX_GL_CSC_OFFSET;
  483. zplane->hbsc = vou->osd + AUX_HBSC_OFFSET;
  484. zplane->rsz = vou->otfppu + AUX_RSZ_OFFSET;
  485. zplane->bits = &zx_gl_bits[1];
  486. zcrtc->chnreg = vou->osd + OSD_AUX_CHN;
  487. zcrtc->chncsc = vou->osd + AUX_CHN_CSC_OFFSET;
  488. zcrtc->dither = vou->osd + AUX_DITHER_OFFSET;
  489. zcrtc->regs = &aux_crtc_regs;
  490. zcrtc->bits = &aux_crtc_bits;
  491. }
  492. zcrtc->pixclk = devm_clk_get(dev, (chn_type == VOU_CHN_MAIN) ?
  493. "main_wclk" : "aux_wclk");
  494. if (IS_ERR(zcrtc->pixclk)) {
  495. ret = PTR_ERR(zcrtc->pixclk);
  496. DRM_DEV_ERROR(dev, "failed to get pix clk: %d\n", ret);
  497. return ret;
  498. }
  499. ret = zx_plane_init(drm, zplane, DRM_PLANE_TYPE_PRIMARY);
  500. if (ret) {
  501. DRM_DEV_ERROR(dev, "failed to init primary plane: %d\n", ret);
  502. return ret;
  503. }
  504. zcrtc->primary = &zplane->plane;
  505. ret = drm_crtc_init_with_planes(drm, &zcrtc->crtc, zcrtc->primary, NULL,
  506. &zx_crtc_funcs, NULL);
  507. if (ret) {
  508. DRM_DEV_ERROR(dev, "failed to init drm crtc: %d\n", ret);
  509. return ret;
  510. }
  511. drm_crtc_helper_add(&zcrtc->crtc, &zx_crtc_helper_funcs);
  512. if (chn_type == VOU_CHN_MAIN)
  513. vou->main_crtc = zcrtc;
  514. else
  515. vou->aux_crtc = zcrtc;
  516. return 0;
  517. }
  518. void zx_vou_layer_enable(struct drm_plane *plane)
  519. {
  520. struct zx_crtc *zcrtc = to_zx_crtc(plane->state->crtc);
  521. struct zx_vou_hw *vou = zcrtc->vou;
  522. struct zx_plane *zplane = to_zx_plane(plane);
  523. const struct vou_layer_bits *bits = zplane->bits;
  524. if (zcrtc->chn_type == VOU_CHN_MAIN) {
  525. zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel, 0);
  526. zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel, 0);
  527. } else {
  528. zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel,
  529. bits->chnsel);
  530. zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel,
  531. bits->clksel);
  532. }
  533. zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, bits->enable);
  534. }
  535. void zx_vou_layer_disable(struct drm_plane *plane,
  536. struct drm_plane_state *old_state)
  537. {
  538. struct zx_crtc *zcrtc = to_zx_crtc(old_state->crtc);
  539. struct zx_vou_hw *vou = zcrtc->vou;
  540. struct zx_plane *zplane = to_zx_plane(plane);
  541. const struct vou_layer_bits *bits = zplane->bits;
  542. zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, 0);
  543. }
  544. static void zx_overlay_init(struct drm_device *drm, struct zx_vou_hw *vou)
  545. {
  546. struct device *dev = vou->dev;
  547. struct zx_plane *zplane;
  548. int i;
  549. int ret;
  550. /*
  551. * VL0 has some quirks on scaling support which need special handling.
  552. * Let's leave it out for now.
  553. */
  554. for (i = 1; i < VL_NUM; i++) {
  555. zplane = devm_kzalloc(dev, sizeof(*zplane), GFP_KERNEL);
  556. if (!zplane) {
  557. DRM_DEV_ERROR(dev, "failed to allocate zplane %d\n", i);
  558. return;
  559. }
  560. zplane->layer = vou->osd + OSD_VL_OFFSET(i);
  561. zplane->hbsc = vou->osd + HBSC_VL_OFFSET(i);
  562. zplane->rsz = vou->otfppu + RSZ_VL_OFFSET(i);
  563. zplane->bits = &zx_vl_bits[i];
  564. ret = zx_plane_init(drm, zplane, DRM_PLANE_TYPE_OVERLAY);
  565. if (ret) {
  566. DRM_DEV_ERROR(dev, "failed to init overlay %d\n", i);
  567. continue;
  568. }
  569. }
  570. }
  571. static inline void zx_osd_int_update(struct zx_crtc *zcrtc)
  572. {
  573. struct drm_crtc *crtc = &zcrtc->crtc;
  574. struct drm_plane *plane;
  575. vou_chn_set_update(zcrtc);
  576. drm_for_each_plane_mask(plane, crtc->dev, crtc->state->plane_mask)
  577. zx_plane_set_update(plane);
  578. }
  579. static irqreturn_t vou_irq_handler(int irq, void *dev_id)
  580. {
  581. struct zx_vou_hw *vou = dev_id;
  582. u32 state;
  583. /* Handle TIMING_CTRL frame interrupts */
  584. state = zx_readl(vou->timing + TIMING_INT_STATE);
  585. zx_writel(vou->timing + TIMING_INT_STATE, state);
  586. if (state & TIMING_INT_MAIN_FRAME)
  587. drm_crtc_handle_vblank(&vou->main_crtc->crtc);
  588. if (state & TIMING_INT_AUX_FRAME)
  589. drm_crtc_handle_vblank(&vou->aux_crtc->crtc);
  590. /* Handle OSD interrupts */
  591. state = zx_readl(vou->osd + OSD_INT_STA);
  592. zx_writel(vou->osd + OSD_INT_CLRSTA, state);
  593. if (state & OSD_INT_MAIN_UPT)
  594. zx_osd_int_update(vou->main_crtc);
  595. if (state & OSD_INT_AUX_UPT)
  596. zx_osd_int_update(vou->aux_crtc);
  597. if (state & OSD_INT_ERROR)
  598. DRM_DEV_ERROR(vou->dev, "OSD ERROR: 0x%08x!\n", state);
  599. return IRQ_HANDLED;
  600. }
  601. static void vou_dtrc_init(struct zx_vou_hw *vou)
  602. {
  603. /* Clear bit for bypass by ID */
  604. zx_writel_mask(vou->dtrc + DTRC_DETILE_CTRL,
  605. TILE2RASTESCAN_BYPASS_MODE, 0);
  606. /* Select ARIDR mode */
  607. zx_writel_mask(vou->dtrc + DTRC_DETILE_CTRL, DETILE_ARIDR_MODE_MASK,
  608. DETILE_ARID_IN_ARIDR);
  609. /* Bypass decompression for both frames */
  610. zx_writel_mask(vou->dtrc + DTRC_F0_CTRL, DTRC_DECOMPRESS_BYPASS,
  611. DTRC_DECOMPRESS_BYPASS);
  612. zx_writel_mask(vou->dtrc + DTRC_F1_CTRL, DTRC_DECOMPRESS_BYPASS,
  613. DTRC_DECOMPRESS_BYPASS);
  614. /* Set up ARID register */
  615. zx_writel(vou->dtrc + DTRC_ARID, DTRC_ARID3(0xf) | DTRC_ARID2(0xe) |
  616. DTRC_ARID1(0xf) | DTRC_ARID0(0xe));
  617. }
  618. static void vou_hw_init(struct zx_vou_hw *vou)
  619. {
  620. /* Release reset for all VOU modules */
  621. zx_writel(vou->vouctl + VOU_SOFT_RST, ~0);
  622. /* Enable all VOU module clocks */
  623. zx_writel(vou->vouctl + VOU_CLK_EN, ~0);
  624. /* Clear both OSD and TIMING_CTRL interrupt state */
  625. zx_writel(vou->osd + OSD_INT_CLRSTA, ~0);
  626. zx_writel(vou->timing + TIMING_INT_STATE, ~0);
  627. /* Enable OSD and TIMING_CTRL interrrupts */
  628. zx_writel(vou->osd + OSD_INT_MSK, OSD_INT_ENABLE);
  629. zx_writel(vou->timing + TIMING_INT_CTRL, TIMING_INT_ENABLE);
  630. /* Select GPC as input to gl/vl scaler as a sane default setting */
  631. zx_writel(vou->otfppu + OTFPPU_RSZ_DATA_SOURCE, 0x2a);
  632. /*
  633. * Needs to reset channel and layer logic per frame when frame starts
  634. * to get VOU work properly.
  635. */
  636. zx_writel_mask(vou->osd + OSD_RST_CLR, RST_PER_FRAME, RST_PER_FRAME);
  637. vou_dtrc_init(vou);
  638. }
  639. static int zx_crtc_bind(struct device *dev, struct device *master, void *data)
  640. {
  641. struct platform_device *pdev = to_platform_device(dev);
  642. struct drm_device *drm = data;
  643. struct zx_vou_hw *vou;
  644. struct resource *res;
  645. int irq;
  646. int ret;
  647. vou = devm_kzalloc(dev, sizeof(*vou), GFP_KERNEL);
  648. if (!vou)
  649. return -ENOMEM;
  650. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "osd");
  651. vou->osd = devm_ioremap_resource(dev, res);
  652. if (IS_ERR(vou->osd)) {
  653. ret = PTR_ERR(vou->osd);
  654. DRM_DEV_ERROR(dev, "failed to remap osd region: %d\n", ret);
  655. return ret;
  656. }
  657. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "timing_ctrl");
  658. vou->timing = devm_ioremap_resource(dev, res);
  659. if (IS_ERR(vou->timing)) {
  660. ret = PTR_ERR(vou->timing);
  661. DRM_DEV_ERROR(dev, "failed to remap timing_ctrl region: %d\n",
  662. ret);
  663. return ret;
  664. }
  665. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dtrc");
  666. vou->dtrc = devm_ioremap_resource(dev, res);
  667. if (IS_ERR(vou->dtrc)) {
  668. ret = PTR_ERR(vou->dtrc);
  669. DRM_DEV_ERROR(dev, "failed to remap dtrc region: %d\n", ret);
  670. return ret;
  671. }
  672. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vou_ctrl");
  673. vou->vouctl = devm_ioremap_resource(dev, res);
  674. if (IS_ERR(vou->vouctl)) {
  675. ret = PTR_ERR(vou->vouctl);
  676. DRM_DEV_ERROR(dev, "failed to remap vou_ctrl region: %d\n",
  677. ret);
  678. return ret;
  679. }
  680. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otfppu");
  681. vou->otfppu = devm_ioremap_resource(dev, res);
  682. if (IS_ERR(vou->otfppu)) {
  683. ret = PTR_ERR(vou->otfppu);
  684. DRM_DEV_ERROR(dev, "failed to remap otfppu region: %d\n", ret);
  685. return ret;
  686. }
  687. irq = platform_get_irq(pdev, 0);
  688. if (irq < 0)
  689. return irq;
  690. vou->axi_clk = devm_clk_get(dev, "aclk");
  691. if (IS_ERR(vou->axi_clk)) {
  692. ret = PTR_ERR(vou->axi_clk);
  693. DRM_DEV_ERROR(dev, "failed to get axi_clk: %d\n", ret);
  694. return ret;
  695. }
  696. vou->ppu_clk = devm_clk_get(dev, "ppu_wclk");
  697. if (IS_ERR(vou->ppu_clk)) {
  698. ret = PTR_ERR(vou->ppu_clk);
  699. DRM_DEV_ERROR(dev, "failed to get ppu_clk: %d\n", ret);
  700. return ret;
  701. }
  702. ret = clk_prepare_enable(vou->axi_clk);
  703. if (ret) {
  704. DRM_DEV_ERROR(dev, "failed to enable axi_clk: %d\n", ret);
  705. return ret;
  706. }
  707. clk_prepare_enable(vou->ppu_clk);
  708. if (ret) {
  709. DRM_DEV_ERROR(dev, "failed to enable ppu_clk: %d\n", ret);
  710. goto disable_axi_clk;
  711. }
  712. vou->dev = dev;
  713. dev_set_drvdata(dev, vou);
  714. vou_hw_init(vou);
  715. ret = devm_request_irq(dev, irq, vou_irq_handler, 0, "zx_vou", vou);
  716. if (ret < 0) {
  717. DRM_DEV_ERROR(dev, "failed to request vou irq: %d\n", ret);
  718. goto disable_ppu_clk;
  719. }
  720. ret = zx_crtc_init(drm, vou, VOU_CHN_MAIN);
  721. if (ret) {
  722. DRM_DEV_ERROR(dev, "failed to init main channel crtc: %d\n",
  723. ret);
  724. goto disable_ppu_clk;
  725. }
  726. ret = zx_crtc_init(drm, vou, VOU_CHN_AUX);
  727. if (ret) {
  728. DRM_DEV_ERROR(dev, "failed to init aux channel crtc: %d\n",
  729. ret);
  730. goto disable_ppu_clk;
  731. }
  732. zx_overlay_init(drm, vou);
  733. return 0;
  734. disable_ppu_clk:
  735. clk_disable_unprepare(vou->ppu_clk);
  736. disable_axi_clk:
  737. clk_disable_unprepare(vou->axi_clk);
  738. return ret;
  739. }
  740. static void zx_crtc_unbind(struct device *dev, struct device *master,
  741. void *data)
  742. {
  743. struct zx_vou_hw *vou = dev_get_drvdata(dev);
  744. clk_disable_unprepare(vou->axi_clk);
  745. clk_disable_unprepare(vou->ppu_clk);
  746. }
  747. static const struct component_ops zx_crtc_component_ops = {
  748. .bind = zx_crtc_bind,
  749. .unbind = zx_crtc_unbind,
  750. };
  751. static int zx_crtc_probe(struct platform_device *pdev)
  752. {
  753. return component_add(&pdev->dev, &zx_crtc_component_ops);
  754. }
  755. static int zx_crtc_remove(struct platform_device *pdev)
  756. {
  757. component_del(&pdev->dev, &zx_crtc_component_ops);
  758. return 0;
  759. }
  760. static const struct of_device_id zx_crtc_of_match[] = {
  761. { .compatible = "zte,zx296718-dpc", },
  762. { /* end */ },
  763. };
  764. MODULE_DEVICE_TABLE(of, zx_crtc_of_match);
  765. struct platform_driver zx_crtc_driver = {
  766. .probe = zx_crtc_probe,
  767. .remove = zx_crtc_remove,
  768. .driver = {
  769. .name = "zx-crtc",
  770. .of_match_table = zx_crtc_of_match,
  771. },
  772. };