rockchip_vop_reg.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803
  1. /*
  2. * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
  3. * Author:Mark Yao <mark.yao@rock-chips.com>
  4. *
  5. * This software is licensed under the terms of the GNU General Public
  6. * License version 2, as published by the Free Software Foundation, and
  7. * may be copied, distributed, and modified under those terms.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #include <drm/drmP.h>
  15. #include <linux/kernel.h>
  16. #include <linux/component.h>
  17. #include "rockchip_drm_vop.h"
  18. #include "rockchip_vop_reg.h"
  19. #define _VOP_REG(off, _mask, _shift, _write_mask, _relaxed) \
  20. { \
  21. .offset = off, \
  22. .mask = _mask, \
  23. .shift = _shift, \
  24. .write_mask = _write_mask, \
  25. .relaxed = _relaxed, \
  26. }
  27. #define VOP_REG(off, _mask, _shift) \
  28. _VOP_REG(off, _mask, _shift, false, true)
  29. #define VOP_REG_SYNC(off, _mask, _shift) \
  30. _VOP_REG(off, _mask, _shift, false, false)
  31. #define VOP_REG_MASK_SYNC(off, _mask, _shift) \
  32. _VOP_REG(off, _mask, _shift, true, false)
  33. static const uint32_t formats_win_full[] = {
  34. DRM_FORMAT_XRGB8888,
  35. DRM_FORMAT_ARGB8888,
  36. DRM_FORMAT_XBGR8888,
  37. DRM_FORMAT_ABGR8888,
  38. DRM_FORMAT_RGB888,
  39. DRM_FORMAT_BGR888,
  40. DRM_FORMAT_RGB565,
  41. DRM_FORMAT_BGR565,
  42. DRM_FORMAT_NV12,
  43. DRM_FORMAT_NV16,
  44. DRM_FORMAT_NV24,
  45. };
  46. static const uint32_t formats_win_lite[] = {
  47. DRM_FORMAT_XRGB8888,
  48. DRM_FORMAT_ARGB8888,
  49. DRM_FORMAT_XBGR8888,
  50. DRM_FORMAT_ABGR8888,
  51. DRM_FORMAT_RGB888,
  52. DRM_FORMAT_BGR888,
  53. DRM_FORMAT_RGB565,
  54. DRM_FORMAT_BGR565,
  55. };
  56. static const struct vop_scl_regs rk3036_win_scl = {
  57. .scale_yrgb_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
  58. .scale_yrgb_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
  59. .scale_cbcr_x = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
  60. .scale_cbcr_y = VOP_REG(RK3036_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
  61. };
  62. static const struct vop_win_phy rk3036_win0_data = {
  63. .scl = &rk3036_win_scl,
  64. .data_formats = formats_win_full,
  65. .nformats = ARRAY_SIZE(formats_win_full),
  66. .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 0),
  67. .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 3),
  68. .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 15),
  69. .act_info = VOP_REG(RK3036_WIN0_ACT_INFO, 0x1fff1fff, 0),
  70. .dsp_info = VOP_REG(RK3036_WIN0_DSP_INFO, 0x0fff0fff, 0),
  71. .dsp_st = VOP_REG(RK3036_WIN0_DSP_ST, 0x1fff1fff, 0),
  72. .yrgb_mst = VOP_REG(RK3036_WIN0_YRGB_MST, 0xffffffff, 0),
  73. .uv_mst = VOP_REG(RK3036_WIN0_CBR_MST, 0xffffffff, 0),
  74. .yrgb_vir = VOP_REG(RK3036_WIN0_VIR, 0xffff, 0),
  75. .uv_vir = VOP_REG(RK3036_WIN0_VIR, 0x1fff, 16),
  76. };
  77. static const struct vop_win_phy rk3036_win1_data = {
  78. .data_formats = formats_win_lite,
  79. .nformats = ARRAY_SIZE(formats_win_lite),
  80. .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
  81. .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
  82. .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
  83. .act_info = VOP_REG(RK3036_WIN1_ACT_INFO, 0x1fff1fff, 0),
  84. .dsp_info = VOP_REG(RK3036_WIN1_DSP_INFO, 0x0fff0fff, 0),
  85. .dsp_st = VOP_REG(RK3036_WIN1_DSP_ST, 0x1fff1fff, 0),
  86. .yrgb_mst = VOP_REG(RK3036_WIN1_MST, 0xffffffff, 0),
  87. .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
  88. };
  89. static const struct vop_win_data rk3036_vop_win_data[] = {
  90. { .base = 0x00, .phy = &rk3036_win0_data,
  91. .type = DRM_PLANE_TYPE_PRIMARY },
  92. { .base = 0x00, .phy = &rk3036_win1_data,
  93. .type = DRM_PLANE_TYPE_CURSOR },
  94. };
  95. static const int rk3036_vop_intrs[] = {
  96. DSP_HOLD_VALID_INTR,
  97. FS_INTR,
  98. LINE_FLAG_INTR,
  99. BUS_ERROR_INTR,
  100. };
  101. static const struct vop_intr rk3036_intr = {
  102. .intrs = rk3036_vop_intrs,
  103. .nintrs = ARRAY_SIZE(rk3036_vop_intrs),
  104. .line_flag_num[0] = VOP_REG(RK3036_INT_STATUS, 0xfff, 12),
  105. .status = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 0),
  106. .enable = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 4),
  107. .clear = VOP_REG_SYNC(RK3036_INT_STATUS, 0xf, 8),
  108. };
  109. static const struct vop_modeset rk3036_modeset = {
  110. .htotal_pw = VOP_REG(RK3036_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
  111. .hact_st_end = VOP_REG(RK3036_DSP_HACT_ST_END, 0x1fff1fff, 0),
  112. .vtotal_pw = VOP_REG(RK3036_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
  113. .vact_st_end = VOP_REG(RK3036_DSP_VACT_ST_END, 0x1fff1fff, 0),
  114. };
  115. static const struct vop_output rk3036_output = {
  116. .pin_pol = VOP_REG(RK3036_DSP_CTRL0, 0xf, 4),
  117. };
  118. static const struct vop_common rk3036_common = {
  119. .standby = VOP_REG_SYNC(RK3036_SYS_CTRL, 0x1, 30),
  120. .out_mode = VOP_REG(RK3036_DSP_CTRL0, 0xf, 0),
  121. .dsp_blank = VOP_REG(RK3036_DSP_CTRL1, 0x1, 24),
  122. .cfg_done = VOP_REG_SYNC(RK3036_REG_CFG_DONE, 0x1, 0),
  123. };
  124. static const struct vop_data rk3036_vop = {
  125. .intr = &rk3036_intr,
  126. .common = &rk3036_common,
  127. .modeset = &rk3036_modeset,
  128. .output = &rk3036_output,
  129. .win = rk3036_vop_win_data,
  130. .win_size = ARRAY_SIZE(rk3036_vop_win_data),
  131. };
  132. static const struct vop_win_phy rk3126_win1_data = {
  133. .data_formats = formats_win_lite,
  134. .nformats = ARRAY_SIZE(formats_win_lite),
  135. .enable = VOP_REG(RK3036_SYS_CTRL, 0x1, 1),
  136. .format = VOP_REG(RK3036_SYS_CTRL, 0x7, 6),
  137. .rb_swap = VOP_REG(RK3036_SYS_CTRL, 0x1, 19),
  138. .dsp_info = VOP_REG(RK3126_WIN1_DSP_INFO, 0x0fff0fff, 0),
  139. .dsp_st = VOP_REG(RK3126_WIN1_DSP_ST, 0x1fff1fff, 0),
  140. .yrgb_mst = VOP_REG(RK3126_WIN1_MST, 0xffffffff, 0),
  141. .yrgb_vir = VOP_REG(RK3036_WIN1_VIR, 0xffff, 0),
  142. };
  143. static const struct vop_win_data rk3126_vop_win_data[] = {
  144. { .base = 0x00, .phy = &rk3036_win0_data,
  145. .type = DRM_PLANE_TYPE_PRIMARY },
  146. { .base = 0x00, .phy = &rk3126_win1_data,
  147. .type = DRM_PLANE_TYPE_CURSOR },
  148. };
  149. static const struct vop_data rk3126_vop = {
  150. .intr = &rk3036_intr,
  151. .common = &rk3036_common,
  152. .modeset = &rk3036_modeset,
  153. .output = &rk3036_output,
  154. .win = rk3126_vop_win_data,
  155. .win_size = ARRAY_SIZE(rk3126_vop_win_data),
  156. };
  157. static const int px30_vop_intrs[] = {
  158. FS_INTR,
  159. 0, 0,
  160. LINE_FLAG_INTR,
  161. 0,
  162. BUS_ERROR_INTR,
  163. 0, 0,
  164. DSP_HOLD_VALID_INTR,
  165. };
  166. static const struct vop_intr px30_intr = {
  167. .intrs = px30_vop_intrs,
  168. .nintrs = ARRAY_SIZE(px30_vop_intrs),
  169. .line_flag_num[0] = VOP_REG(PX30_LINE_FLAG, 0xfff, 0),
  170. .status = VOP_REG_MASK_SYNC(PX30_INTR_STATUS, 0xffff, 0),
  171. .enable = VOP_REG_MASK_SYNC(PX30_INTR_EN, 0xffff, 0),
  172. .clear = VOP_REG_MASK_SYNC(PX30_INTR_CLEAR, 0xffff, 0),
  173. };
  174. static const struct vop_common px30_common = {
  175. .standby = VOP_REG_SYNC(PX30_SYS_CTRL2, 0x1, 1),
  176. .out_mode = VOP_REG(PX30_DSP_CTRL2, 0xf, 16),
  177. .dsp_blank = VOP_REG(PX30_DSP_CTRL2, 0x1, 14),
  178. .cfg_done = VOP_REG_SYNC(PX30_REG_CFG_DONE, 0x1, 0),
  179. };
  180. static const struct vop_modeset px30_modeset = {
  181. .htotal_pw = VOP_REG(PX30_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
  182. .hact_st_end = VOP_REG(PX30_DSP_HACT_ST_END, 0x0fff0fff, 0),
  183. .vtotal_pw = VOP_REG(PX30_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
  184. .vact_st_end = VOP_REG(PX30_DSP_VACT_ST_END, 0x0fff0fff, 0),
  185. };
  186. static const struct vop_output px30_output = {
  187. .rgb_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0xf, 1),
  188. .mipi_pin_pol = VOP_REG(PX30_DSP_CTRL0, 0xf, 25),
  189. .rgb_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 0),
  190. .mipi_en = VOP_REG(PX30_DSP_CTRL0, 0x1, 24),
  191. };
  192. static const struct vop_scl_regs px30_win_scl = {
  193. .scale_yrgb_x = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
  194. .scale_yrgb_y = VOP_REG(PX30_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
  195. .scale_cbcr_x = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
  196. .scale_cbcr_y = VOP_REG(PX30_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
  197. };
  198. static const struct vop_win_phy px30_win0_data = {
  199. .scl = &px30_win_scl,
  200. .data_formats = formats_win_full,
  201. .nformats = ARRAY_SIZE(formats_win_full),
  202. .enable = VOP_REG(PX30_WIN0_CTRL0, 0x1, 0),
  203. .format = VOP_REG(PX30_WIN0_CTRL0, 0x7, 1),
  204. .rb_swap = VOP_REG(PX30_WIN0_CTRL0, 0x1, 12),
  205. .act_info = VOP_REG(PX30_WIN0_ACT_INFO, 0xffffffff, 0),
  206. .dsp_info = VOP_REG(PX30_WIN0_DSP_INFO, 0xffffffff, 0),
  207. .dsp_st = VOP_REG(PX30_WIN0_DSP_ST, 0xffffffff, 0),
  208. .yrgb_mst = VOP_REG(PX30_WIN0_YRGB_MST0, 0xffffffff, 0),
  209. .uv_mst = VOP_REG(PX30_WIN0_CBR_MST0, 0xffffffff, 0),
  210. .yrgb_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 0),
  211. .uv_vir = VOP_REG(PX30_WIN0_VIR, 0x1fff, 16),
  212. };
  213. static const struct vop_win_phy px30_win1_data = {
  214. .data_formats = formats_win_lite,
  215. .nformats = ARRAY_SIZE(formats_win_lite),
  216. .enable = VOP_REG(PX30_WIN1_CTRL0, 0x1, 0),
  217. .format = VOP_REG(PX30_WIN1_CTRL0, 0x7, 4),
  218. .rb_swap = VOP_REG(PX30_WIN1_CTRL0, 0x1, 12),
  219. .dsp_info = VOP_REG(PX30_WIN1_DSP_INFO, 0xffffffff, 0),
  220. .dsp_st = VOP_REG(PX30_WIN1_DSP_ST, 0xffffffff, 0),
  221. .yrgb_mst = VOP_REG(PX30_WIN1_MST, 0xffffffff, 0),
  222. .yrgb_vir = VOP_REG(PX30_WIN1_VIR, 0x1fff, 0),
  223. };
  224. static const struct vop_win_phy px30_win2_data = {
  225. .data_formats = formats_win_lite,
  226. .nformats = ARRAY_SIZE(formats_win_lite),
  227. .gate = VOP_REG(PX30_WIN2_CTRL0, 0x1, 4),
  228. .enable = VOP_REG(PX30_WIN2_CTRL0, 0x1, 0),
  229. .format = VOP_REG(PX30_WIN2_CTRL0, 0x3, 5),
  230. .rb_swap = VOP_REG(PX30_WIN2_CTRL0, 0x1, 20),
  231. .dsp_info = VOP_REG(PX30_WIN2_DSP_INFO0, 0x0fff0fff, 0),
  232. .dsp_st = VOP_REG(PX30_WIN2_DSP_ST0, 0x1fff1fff, 0),
  233. .yrgb_mst = VOP_REG(PX30_WIN2_MST0, 0xffffffff, 0),
  234. .yrgb_vir = VOP_REG(PX30_WIN2_VIR0_1, 0x1fff, 0),
  235. };
  236. static const struct vop_win_data px30_vop_big_win_data[] = {
  237. { .base = 0x00, .phy = &px30_win0_data,
  238. .type = DRM_PLANE_TYPE_PRIMARY },
  239. { .base = 0x00, .phy = &px30_win1_data,
  240. .type = DRM_PLANE_TYPE_OVERLAY },
  241. { .base = 0x00, .phy = &px30_win2_data,
  242. .type = DRM_PLANE_TYPE_CURSOR },
  243. };
  244. static const struct vop_data px30_vop_big = {
  245. .intr = &px30_intr,
  246. .feature = VOP_FEATURE_INTERNAL_RGB,
  247. .common = &px30_common,
  248. .modeset = &px30_modeset,
  249. .output = &px30_output,
  250. .win = px30_vop_big_win_data,
  251. .win_size = ARRAY_SIZE(px30_vop_big_win_data),
  252. };
  253. static const struct vop_win_data px30_vop_lit_win_data[] = {
  254. { .base = 0x00, .phy = &px30_win1_data,
  255. .type = DRM_PLANE_TYPE_PRIMARY },
  256. };
  257. static const struct vop_data px30_vop_lit = {
  258. .intr = &px30_intr,
  259. .feature = VOP_FEATURE_INTERNAL_RGB,
  260. .common = &px30_common,
  261. .modeset = &px30_modeset,
  262. .output = &px30_output,
  263. .win = px30_vop_lit_win_data,
  264. .win_size = ARRAY_SIZE(px30_vop_lit_win_data),
  265. };
  266. static const struct vop_scl_regs rk3188_win_scl = {
  267. .scale_yrgb_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
  268. .scale_yrgb_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
  269. .scale_cbcr_x = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
  270. .scale_cbcr_y = VOP_REG(RK3188_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
  271. };
  272. static const struct vop_win_phy rk3188_win0_data = {
  273. .scl = &rk3188_win_scl,
  274. .data_formats = formats_win_full,
  275. .nformats = ARRAY_SIZE(formats_win_full),
  276. .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 0),
  277. .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 3),
  278. .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 15),
  279. .act_info = VOP_REG(RK3188_WIN0_ACT_INFO, 0x1fff1fff, 0),
  280. .dsp_info = VOP_REG(RK3188_WIN0_DSP_INFO, 0x0fff0fff, 0),
  281. .dsp_st = VOP_REG(RK3188_WIN0_DSP_ST, 0x1fff1fff, 0),
  282. .yrgb_mst = VOP_REG(RK3188_WIN0_YRGB_MST0, 0xffffffff, 0),
  283. .uv_mst = VOP_REG(RK3188_WIN0_CBR_MST0, 0xffffffff, 0),
  284. .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 0),
  285. };
  286. static const struct vop_win_phy rk3188_win1_data = {
  287. .data_formats = formats_win_lite,
  288. .nformats = ARRAY_SIZE(formats_win_lite),
  289. .enable = VOP_REG(RK3188_SYS_CTRL, 0x1, 1),
  290. .format = VOP_REG(RK3188_SYS_CTRL, 0x7, 6),
  291. .rb_swap = VOP_REG(RK3188_SYS_CTRL, 0x1, 19),
  292. /* no act_info on window1 */
  293. .dsp_info = VOP_REG(RK3188_WIN1_DSP_INFO, 0x07ff07ff, 0),
  294. .dsp_st = VOP_REG(RK3188_WIN1_DSP_ST, 0x0fff0fff, 0),
  295. .yrgb_mst = VOP_REG(RK3188_WIN1_MST, 0xffffffff, 0),
  296. .yrgb_vir = VOP_REG(RK3188_WIN_VIR, 0x1fff, 16),
  297. };
  298. static const struct vop_modeset rk3188_modeset = {
  299. .htotal_pw = VOP_REG(RK3188_DSP_HTOTAL_HS_END, 0x0fff0fff, 0),
  300. .hact_st_end = VOP_REG(RK3188_DSP_HACT_ST_END, 0x0fff0fff, 0),
  301. .vtotal_pw = VOP_REG(RK3188_DSP_VTOTAL_VS_END, 0x0fff0fff, 0),
  302. .vact_st_end = VOP_REG(RK3188_DSP_VACT_ST_END, 0x0fff0fff, 0),
  303. };
  304. static const struct vop_output rk3188_output = {
  305. .pin_pol = VOP_REG(RK3188_DSP_CTRL0, 0xf, 4),
  306. };
  307. static const struct vop_common rk3188_common = {
  308. .gate_en = VOP_REG(RK3188_SYS_CTRL, 0x1, 31),
  309. .standby = VOP_REG(RK3188_SYS_CTRL, 0x1, 30),
  310. .out_mode = VOP_REG(RK3188_DSP_CTRL0, 0xf, 0),
  311. .cfg_done = VOP_REG(RK3188_REG_CFG_DONE, 0x1, 0),
  312. .dsp_blank = VOP_REG(RK3188_DSP_CTRL1, 0x3, 24),
  313. };
  314. static const struct vop_win_data rk3188_vop_win_data[] = {
  315. { .base = 0x00, .phy = &rk3188_win0_data,
  316. .type = DRM_PLANE_TYPE_PRIMARY },
  317. { .base = 0x00, .phy = &rk3188_win1_data,
  318. .type = DRM_PLANE_TYPE_CURSOR },
  319. };
  320. static const int rk3188_vop_intrs[] = {
  321. 0,
  322. FS_INTR,
  323. LINE_FLAG_INTR,
  324. BUS_ERROR_INTR,
  325. };
  326. static const struct vop_intr rk3188_vop_intr = {
  327. .intrs = rk3188_vop_intrs,
  328. .nintrs = ARRAY_SIZE(rk3188_vop_intrs),
  329. .line_flag_num[0] = VOP_REG(RK3188_INT_STATUS, 0xfff, 12),
  330. .status = VOP_REG(RK3188_INT_STATUS, 0xf, 0),
  331. .enable = VOP_REG(RK3188_INT_STATUS, 0xf, 4),
  332. .clear = VOP_REG(RK3188_INT_STATUS, 0xf, 8),
  333. };
  334. static const struct vop_data rk3188_vop = {
  335. .intr = &rk3188_vop_intr,
  336. .common = &rk3188_common,
  337. .modeset = &rk3188_modeset,
  338. .output = &rk3188_output,
  339. .win = rk3188_vop_win_data,
  340. .win_size = ARRAY_SIZE(rk3188_vop_win_data),
  341. .feature = VOP_FEATURE_INTERNAL_RGB,
  342. };
  343. static const struct vop_scl_extension rk3288_win_full_scl_ext = {
  344. .cbcr_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 31),
  345. .cbcr_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 30),
  346. .cbcr_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 28),
  347. .cbcr_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 26),
  348. .cbcr_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 24),
  349. .yrgb_vsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 23),
  350. .yrgb_vsu_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 22),
  351. .yrgb_hsd_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 20),
  352. .yrgb_ver_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 18),
  353. .yrgb_hor_scl_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 16),
  354. .line_load_mode = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 15),
  355. .cbcr_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0x7, 12),
  356. .yrgb_axi_gather_num = VOP_REG(RK3288_WIN0_CTRL1, 0xf, 8),
  357. .vsd_cbcr_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 7),
  358. .vsd_cbcr_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 6),
  359. .vsd_yrgb_gt2 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 5),
  360. .vsd_yrgb_gt4 = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 4),
  361. .bic_coe_sel = VOP_REG(RK3288_WIN0_CTRL1, 0x3, 2),
  362. .cbcr_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 1),
  363. .yrgb_axi_gather_en = VOP_REG(RK3288_WIN0_CTRL1, 0x1, 0),
  364. .lb_mode = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 5),
  365. };
  366. static const struct vop_scl_regs rk3288_win_full_scl = {
  367. .ext = &rk3288_win_full_scl_ext,
  368. .scale_yrgb_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 0x0),
  369. .scale_yrgb_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_YRGB, 0xffff, 16),
  370. .scale_cbcr_x = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 0x0),
  371. .scale_cbcr_y = VOP_REG(RK3288_WIN0_SCL_FACTOR_CBR, 0xffff, 16),
  372. };
  373. static const struct vop_win_phy rk3288_win01_data = {
  374. .scl = &rk3288_win_full_scl,
  375. .data_formats = formats_win_full,
  376. .nformats = ARRAY_SIZE(formats_win_full),
  377. .enable = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 0),
  378. .format = VOP_REG(RK3288_WIN0_CTRL0, 0x7, 1),
  379. .rb_swap = VOP_REG(RK3288_WIN0_CTRL0, 0x1, 12),
  380. .act_info = VOP_REG(RK3288_WIN0_ACT_INFO, 0x1fff1fff, 0),
  381. .dsp_info = VOP_REG(RK3288_WIN0_DSP_INFO, 0x0fff0fff, 0),
  382. .dsp_st = VOP_REG(RK3288_WIN0_DSP_ST, 0x1fff1fff, 0),
  383. .yrgb_mst = VOP_REG(RK3288_WIN0_YRGB_MST, 0xffffffff, 0),
  384. .uv_mst = VOP_REG(RK3288_WIN0_CBR_MST, 0xffffffff, 0),
  385. .yrgb_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 0),
  386. .uv_vir = VOP_REG(RK3288_WIN0_VIR, 0x3fff, 16),
  387. .src_alpha_ctl = VOP_REG(RK3288_WIN0_SRC_ALPHA_CTRL, 0xff, 0),
  388. .dst_alpha_ctl = VOP_REG(RK3288_WIN0_DST_ALPHA_CTRL, 0xff, 0),
  389. .channel = VOP_REG(RK3288_WIN0_CTRL2, 0xff, 0),
  390. };
  391. static const struct vop_win_phy rk3288_win23_data = {
  392. .data_formats = formats_win_lite,
  393. .nformats = ARRAY_SIZE(formats_win_lite),
  394. .enable = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 4),
  395. .gate = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 0),
  396. .format = VOP_REG(RK3288_WIN2_CTRL0, 0x7, 1),
  397. .rb_swap = VOP_REG(RK3288_WIN2_CTRL0, 0x1, 12),
  398. .dsp_info = VOP_REG(RK3288_WIN2_DSP_INFO0, 0x0fff0fff, 0),
  399. .dsp_st = VOP_REG(RK3288_WIN2_DSP_ST0, 0x1fff1fff, 0),
  400. .yrgb_mst = VOP_REG(RK3288_WIN2_MST0, 0xffffffff, 0),
  401. .yrgb_vir = VOP_REG(RK3288_WIN2_VIR0_1, 0x1fff, 0),
  402. .src_alpha_ctl = VOP_REG(RK3288_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
  403. .dst_alpha_ctl = VOP_REG(RK3288_WIN2_DST_ALPHA_CTRL, 0xff, 0),
  404. };
  405. static const struct vop_modeset rk3288_modeset = {
  406. .htotal_pw = VOP_REG(RK3288_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
  407. .hact_st_end = VOP_REG(RK3288_DSP_HACT_ST_END, 0x1fff1fff, 0),
  408. .vtotal_pw = VOP_REG(RK3288_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
  409. .vact_st_end = VOP_REG(RK3288_DSP_VACT_ST_END, 0x1fff1fff, 0),
  410. .hpost_st_end = VOP_REG(RK3288_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
  411. .vpost_st_end = VOP_REG(RK3288_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
  412. };
  413. static const struct vop_output rk3288_output = {
  414. .pin_pol = VOP_REG(RK3288_DSP_CTRL0, 0xf, 4),
  415. .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
  416. .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
  417. .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
  418. .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
  419. };
  420. static const struct vop_common rk3288_common = {
  421. .standby = VOP_REG_SYNC(RK3288_SYS_CTRL, 0x1, 22),
  422. .gate_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 23),
  423. .mmu_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 20),
  424. .pre_dither_down = VOP_REG(RK3288_DSP_CTRL1, 0x1, 1),
  425. .dither_down = VOP_REG(RK3288_DSP_CTRL1, 0xf, 1),
  426. .dither_up = VOP_REG(RK3288_DSP_CTRL1, 0x1, 6),
  427. .data_blank = VOP_REG(RK3288_DSP_CTRL0, 0x1, 19),
  428. .dsp_blank = VOP_REG(RK3288_DSP_CTRL0, 0x3, 18),
  429. .out_mode = VOP_REG(RK3288_DSP_CTRL0, 0xf, 0),
  430. .cfg_done = VOP_REG_SYNC(RK3288_REG_CFG_DONE, 0x1, 0),
  431. };
  432. /*
  433. * Note: rk3288 has a dedicated 'cursor' window, however, that window requires
  434. * special support to get alpha blending working. For now, just use overlay
  435. * window 3 for the drm cursor.
  436. *
  437. */
  438. static const struct vop_win_data rk3288_vop_win_data[] = {
  439. { .base = 0x00, .phy = &rk3288_win01_data,
  440. .type = DRM_PLANE_TYPE_PRIMARY },
  441. { .base = 0x40, .phy = &rk3288_win01_data,
  442. .type = DRM_PLANE_TYPE_OVERLAY },
  443. { .base = 0x00, .phy = &rk3288_win23_data,
  444. .type = DRM_PLANE_TYPE_OVERLAY },
  445. { .base = 0x50, .phy = &rk3288_win23_data,
  446. .type = DRM_PLANE_TYPE_CURSOR },
  447. };
  448. static const int rk3288_vop_intrs[] = {
  449. DSP_HOLD_VALID_INTR,
  450. FS_INTR,
  451. LINE_FLAG_INTR,
  452. BUS_ERROR_INTR,
  453. };
  454. static const struct vop_intr rk3288_vop_intr = {
  455. .intrs = rk3288_vop_intrs,
  456. .nintrs = ARRAY_SIZE(rk3288_vop_intrs),
  457. .line_flag_num[0] = VOP_REG(RK3288_INTR_CTRL0, 0x1fff, 12),
  458. .status = VOP_REG(RK3288_INTR_CTRL0, 0xf, 0),
  459. .enable = VOP_REG(RK3288_INTR_CTRL0, 0xf, 4),
  460. .clear = VOP_REG(RK3288_INTR_CTRL0, 0xf, 8),
  461. };
  462. static const struct vop_data rk3288_vop = {
  463. .version = VOP_VERSION(3, 1),
  464. .feature = VOP_FEATURE_OUTPUT_RGB10,
  465. .intr = &rk3288_vop_intr,
  466. .common = &rk3288_common,
  467. .modeset = &rk3288_modeset,
  468. .output = &rk3288_output,
  469. .win = rk3288_vop_win_data,
  470. .win_size = ARRAY_SIZE(rk3288_vop_win_data),
  471. };
  472. static const int rk3368_vop_intrs[] = {
  473. FS_INTR,
  474. 0, 0,
  475. LINE_FLAG_INTR,
  476. 0,
  477. BUS_ERROR_INTR,
  478. 0, 0, 0, 0, 0, 0, 0,
  479. DSP_HOLD_VALID_INTR,
  480. };
  481. static const struct vop_intr rk3368_vop_intr = {
  482. .intrs = rk3368_vop_intrs,
  483. .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
  484. .line_flag_num[0] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 0),
  485. .line_flag_num[1] = VOP_REG(RK3368_LINE_FLAG, 0xffff, 16),
  486. .status = VOP_REG_MASK_SYNC(RK3368_INTR_STATUS, 0x3fff, 0),
  487. .enable = VOP_REG_MASK_SYNC(RK3368_INTR_EN, 0x3fff, 0),
  488. .clear = VOP_REG_MASK_SYNC(RK3368_INTR_CLEAR, 0x3fff, 0),
  489. };
  490. static const struct vop_win_phy rk3368_win23_data = {
  491. .data_formats = formats_win_lite,
  492. .nformats = ARRAY_SIZE(formats_win_lite),
  493. .gate = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 0),
  494. .enable = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 4),
  495. .format = VOP_REG(RK3368_WIN2_CTRL0, 0x3, 5),
  496. .rb_swap = VOP_REG(RK3368_WIN2_CTRL0, 0x1, 20),
  497. .dsp_info = VOP_REG(RK3368_WIN2_DSP_INFO0, 0x0fff0fff, 0),
  498. .dsp_st = VOP_REG(RK3368_WIN2_DSP_ST0, 0x1fff1fff, 0),
  499. .yrgb_mst = VOP_REG(RK3368_WIN2_MST0, 0xffffffff, 0),
  500. .yrgb_vir = VOP_REG(RK3368_WIN2_VIR0_1, 0x1fff, 0),
  501. .src_alpha_ctl = VOP_REG(RK3368_WIN2_SRC_ALPHA_CTRL, 0xff, 0),
  502. .dst_alpha_ctl = VOP_REG(RK3368_WIN2_DST_ALPHA_CTRL, 0xff, 0),
  503. };
  504. static const struct vop_win_data rk3368_vop_win_data[] = {
  505. { .base = 0x00, .phy = &rk3288_win01_data,
  506. .type = DRM_PLANE_TYPE_PRIMARY },
  507. { .base = 0x40, .phy = &rk3288_win01_data,
  508. .type = DRM_PLANE_TYPE_OVERLAY },
  509. { .base = 0x00, .phy = &rk3368_win23_data,
  510. .type = DRM_PLANE_TYPE_OVERLAY },
  511. { .base = 0x50, .phy = &rk3368_win23_data,
  512. .type = DRM_PLANE_TYPE_CURSOR },
  513. };
  514. static const struct vop_output rk3368_output = {
  515. .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 16),
  516. .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 20),
  517. .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 24),
  518. .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 28),
  519. .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
  520. .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
  521. .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
  522. .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
  523. };
  524. static const struct vop_misc rk3368_misc = {
  525. .global_regdone_en = VOP_REG(RK3368_SYS_CTRL, 0x1, 11),
  526. };
  527. static const struct vop_data rk3368_vop = {
  528. .version = VOP_VERSION(3, 2),
  529. .intr = &rk3368_vop_intr,
  530. .common = &rk3288_common,
  531. .modeset = &rk3288_modeset,
  532. .output = &rk3368_output,
  533. .misc = &rk3368_misc,
  534. .win = rk3368_vop_win_data,
  535. .win_size = ARRAY_SIZE(rk3368_vop_win_data),
  536. };
  537. static const struct vop_intr rk3366_vop_intr = {
  538. .intrs = rk3368_vop_intrs,
  539. .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
  540. .line_flag_num[0] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 0),
  541. .line_flag_num[1] = VOP_REG(RK3366_LINE_FLAG, 0xffff, 16),
  542. .status = VOP_REG_MASK_SYNC(RK3366_INTR_STATUS0, 0xffff, 0),
  543. .enable = VOP_REG_MASK_SYNC(RK3366_INTR_EN0, 0xffff, 0),
  544. .clear = VOP_REG_MASK_SYNC(RK3366_INTR_CLEAR0, 0xffff, 0),
  545. };
  546. static const struct vop_data rk3366_vop = {
  547. .version = VOP_VERSION(3, 4),
  548. .intr = &rk3366_vop_intr,
  549. .common = &rk3288_common,
  550. .modeset = &rk3288_modeset,
  551. .output = &rk3368_output,
  552. .misc = &rk3368_misc,
  553. .win = rk3368_vop_win_data,
  554. .win_size = ARRAY_SIZE(rk3368_vop_win_data),
  555. };
  556. static const struct vop_output rk3399_output = {
  557. .dp_pin_pol = VOP_REG(RK3399_DSP_CTRL1, 0xf, 16),
  558. .rgb_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 16),
  559. .hdmi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 20),
  560. .edp_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 24),
  561. .mipi_pin_pol = VOP_REG(RK3368_DSP_CTRL1, 0xf, 28),
  562. .dp_en = VOP_REG(RK3399_SYS_CTRL, 0x1, 11),
  563. .rgb_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 12),
  564. .hdmi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 13),
  565. .edp_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 14),
  566. .mipi_en = VOP_REG(RK3288_SYS_CTRL, 0x1, 15),
  567. };
  568. static const struct vop_data rk3399_vop_big = {
  569. .version = VOP_VERSION(3, 5),
  570. .feature = VOP_FEATURE_OUTPUT_RGB10,
  571. .intr = &rk3366_vop_intr,
  572. .common = &rk3288_common,
  573. .modeset = &rk3288_modeset,
  574. .output = &rk3399_output,
  575. .misc = &rk3368_misc,
  576. .win = rk3368_vop_win_data,
  577. .win_size = ARRAY_SIZE(rk3368_vop_win_data),
  578. };
  579. static const struct vop_win_data rk3399_vop_lit_win_data[] = {
  580. { .base = 0x00, .phy = &rk3288_win01_data,
  581. .type = DRM_PLANE_TYPE_PRIMARY },
  582. { .base = 0x00, .phy = &rk3368_win23_data,
  583. .type = DRM_PLANE_TYPE_CURSOR},
  584. };
  585. static const struct vop_data rk3399_vop_lit = {
  586. .version = VOP_VERSION(3, 6),
  587. .intr = &rk3366_vop_intr,
  588. .common = &rk3288_common,
  589. .modeset = &rk3288_modeset,
  590. .output = &rk3399_output,
  591. .misc = &rk3368_misc,
  592. .win = rk3399_vop_lit_win_data,
  593. .win_size = ARRAY_SIZE(rk3399_vop_lit_win_data),
  594. };
  595. static const struct vop_win_data rk3228_vop_win_data[] = {
  596. { .base = 0x00, .phy = &rk3288_win01_data,
  597. .type = DRM_PLANE_TYPE_PRIMARY },
  598. { .base = 0x40, .phy = &rk3288_win01_data,
  599. .type = DRM_PLANE_TYPE_CURSOR },
  600. };
  601. static const struct vop_data rk3228_vop = {
  602. .version = VOP_VERSION(3, 7),
  603. .feature = VOP_FEATURE_OUTPUT_RGB10,
  604. .intr = &rk3366_vop_intr,
  605. .common = &rk3288_common,
  606. .modeset = &rk3288_modeset,
  607. .output = &rk3399_output,
  608. .misc = &rk3368_misc,
  609. .win = rk3228_vop_win_data,
  610. .win_size = ARRAY_SIZE(rk3228_vop_win_data),
  611. };
  612. static const struct vop_modeset rk3328_modeset = {
  613. .htotal_pw = VOP_REG(RK3328_DSP_HTOTAL_HS_END, 0x1fff1fff, 0),
  614. .hact_st_end = VOP_REG(RK3328_DSP_HACT_ST_END, 0x1fff1fff, 0),
  615. .vtotal_pw = VOP_REG(RK3328_DSP_VTOTAL_VS_END, 0x1fff1fff, 0),
  616. .vact_st_end = VOP_REG(RK3328_DSP_VACT_ST_END, 0x1fff1fff, 0),
  617. .hpost_st_end = VOP_REG(RK3328_POST_DSP_HACT_INFO, 0x1fff1fff, 0),
  618. .vpost_st_end = VOP_REG(RK3328_POST_DSP_VACT_INFO, 0x1fff1fff, 0),
  619. };
  620. static const struct vop_output rk3328_output = {
  621. .rgb_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 12),
  622. .hdmi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 13),
  623. .edp_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 14),
  624. .mipi_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 15),
  625. .rgb_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 16),
  626. .hdmi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 20),
  627. .edp_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 24),
  628. .mipi_pin_pol = VOP_REG(RK3328_DSP_CTRL1, 0xf, 28),
  629. };
  630. static const struct vop_misc rk3328_misc = {
  631. .global_regdone_en = VOP_REG(RK3328_SYS_CTRL, 0x1, 11),
  632. };
  633. static const struct vop_common rk3328_common = {
  634. .standby = VOP_REG_SYNC(RK3328_SYS_CTRL, 0x1, 22),
  635. .dither_down = VOP_REG(RK3328_DSP_CTRL1, 0xf, 1),
  636. .dither_up = VOP_REG(RK3328_DSP_CTRL1, 0x1, 6),
  637. .dsp_blank = VOP_REG(RK3328_DSP_CTRL0, 0x3, 18),
  638. .out_mode = VOP_REG(RK3328_DSP_CTRL0, 0xf, 0),
  639. .cfg_done = VOP_REG_SYNC(RK3328_REG_CFG_DONE, 0x1, 0),
  640. };
  641. static const struct vop_intr rk3328_vop_intr = {
  642. .intrs = rk3368_vop_intrs,
  643. .nintrs = ARRAY_SIZE(rk3368_vop_intrs),
  644. .line_flag_num[0] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 0),
  645. .line_flag_num[1] = VOP_REG(RK3328_LINE_FLAG, 0xffff, 16),
  646. .status = VOP_REG_MASK_SYNC(RK3328_INTR_STATUS0, 0xffff, 0),
  647. .enable = VOP_REG_MASK_SYNC(RK3328_INTR_EN0, 0xffff, 0),
  648. .clear = VOP_REG_MASK_SYNC(RK3328_INTR_CLEAR0, 0xffff, 0),
  649. };
  650. static const struct vop_win_data rk3328_vop_win_data[] = {
  651. { .base = 0xd0, .phy = &rk3288_win01_data,
  652. .type = DRM_PLANE_TYPE_PRIMARY },
  653. { .base = 0x1d0, .phy = &rk3288_win01_data,
  654. .type = DRM_PLANE_TYPE_OVERLAY },
  655. { .base = 0x2d0, .phy = &rk3288_win01_data,
  656. .type = DRM_PLANE_TYPE_CURSOR },
  657. };
  658. static const struct vop_data rk3328_vop = {
  659. .version = VOP_VERSION(3, 8),
  660. .feature = VOP_FEATURE_OUTPUT_RGB10,
  661. .intr = &rk3328_vop_intr,
  662. .common = &rk3328_common,
  663. .modeset = &rk3328_modeset,
  664. .output = &rk3328_output,
  665. .misc = &rk3328_misc,
  666. .win = rk3328_vop_win_data,
  667. .win_size = ARRAY_SIZE(rk3328_vop_win_data),
  668. };
  669. static const struct of_device_id vop_driver_dt_match[] = {
  670. { .compatible = "rockchip,rk3036-vop",
  671. .data = &rk3036_vop },
  672. { .compatible = "rockchip,rk3126-vop",
  673. .data = &rk3126_vop },
  674. { .compatible = "rockchip,px30-vop-big",
  675. .data = &px30_vop_big },
  676. { .compatible = "rockchip,px30-vop-lit",
  677. .data = &px30_vop_lit },
  678. { .compatible = "rockchip,rk3188-vop",
  679. .data = &rk3188_vop },
  680. { .compatible = "rockchip,rk3288-vop",
  681. .data = &rk3288_vop },
  682. { .compatible = "rockchip,rk3368-vop",
  683. .data = &rk3368_vop },
  684. { .compatible = "rockchip,rk3366-vop",
  685. .data = &rk3366_vop },
  686. { .compatible = "rockchip,rk3399-vop-big",
  687. .data = &rk3399_vop_big },
  688. { .compatible = "rockchip,rk3399-vop-lit",
  689. .data = &rk3399_vop_lit },
  690. { .compatible = "rockchip,rk3228-vop",
  691. .data = &rk3228_vop },
  692. { .compatible = "rockchip,rk3328-vop",
  693. .data = &rk3328_vop },
  694. {},
  695. };
  696. MODULE_DEVICE_TABLE(of, vop_driver_dt_match);
  697. static int vop_probe(struct platform_device *pdev)
  698. {
  699. struct device *dev = &pdev->dev;
  700. if (!dev->of_node) {
  701. DRM_DEV_ERROR(dev, "can't find vop devices\n");
  702. return -ENODEV;
  703. }
  704. return component_add(dev, &vop_component_ops);
  705. }
  706. static int vop_remove(struct platform_device *pdev)
  707. {
  708. component_del(&pdev->dev, &vop_component_ops);
  709. return 0;
  710. }
  711. struct platform_driver vop_platform_driver = {
  712. .probe = vop_probe,
  713. .remove = vop_remove,
  714. .driver = {
  715. .name = "rockchip-vop",
  716. .of_match_table = of_match_ptr(vop_driver_dt_match),
  717. },
  718. };