vs_dc.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2020 VeriSilicon Holdings Co., Ltd.
  4. */
  5. #include <linux/component.h>
  6. #include <linux/clk.h>
  7. #include <linux/delay.h>
  8. #include <linux/kernel.h>
  9. #include <linux/media-bus-format.h>
  10. #include <linux/of_graph.h>
  11. #include <linux/pm.h>
  12. #include <linux/pm_runtime.h>
  13. #include <drm/drm_framebuffer.h>
  14. #include <drm/drm_atomic.h>
  15. #include <drm/drm_atomic_helper.h>
  16. #include <drm/vs_drm.h>
  17. #include "vs_type.h"
  18. #include "vs_dc_hw.h"
  19. #include "vs_dc.h"
  20. #include "vs_crtc.h"
  21. #include "vs_drv.h"
  22. #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0)
  23. #include <drm/drm_fourcc.h>
  24. #include <drm/drm_vblank.h>
  25. #endif
  26. static inline void update_format(u32 format, u64 mod, struct dc_hw_fb *fb)
  27. {
  28. u8 f = FORMAT_A8R8G8B8;
  29. switch (format) {
  30. case DRM_FORMAT_XRGB4444:
  31. case DRM_FORMAT_RGBX4444:
  32. case DRM_FORMAT_XBGR4444:
  33. case DRM_FORMAT_BGRX4444:
  34. f = FORMAT_X4R4G4B4;
  35. break;
  36. case DRM_FORMAT_ARGB4444:
  37. case DRM_FORMAT_RGBA4444:
  38. case DRM_FORMAT_ABGR4444:
  39. case DRM_FORMAT_BGRA4444:
  40. f = FORMAT_A4R4G4B4;
  41. break;
  42. case DRM_FORMAT_XRGB1555:
  43. case DRM_FORMAT_RGBX5551:
  44. case DRM_FORMAT_XBGR1555:
  45. case DRM_FORMAT_BGRX5551:
  46. f = FORMAT_X1R5G5B5;
  47. break;
  48. case DRM_FORMAT_ARGB1555:
  49. case DRM_FORMAT_RGBA5551:
  50. case DRM_FORMAT_ABGR1555:
  51. case DRM_FORMAT_BGRA5551:
  52. f = FORMAT_A1R5G5B5;
  53. break;
  54. case DRM_FORMAT_RGB565:
  55. case DRM_FORMAT_BGR565:
  56. f = FORMAT_R5G6B5;
  57. break;
  58. case DRM_FORMAT_XRGB8888:
  59. case DRM_FORMAT_RGBX8888:
  60. case DRM_FORMAT_XBGR8888:
  61. case DRM_FORMAT_BGRX8888:
  62. f = FORMAT_X8R8G8B8;
  63. break;
  64. case DRM_FORMAT_ARGB8888:
  65. case DRM_FORMAT_RGBA8888:
  66. case DRM_FORMAT_ABGR8888:
  67. case DRM_FORMAT_BGRA8888:
  68. f = FORMAT_A8R8G8B8;
  69. break;
  70. case DRM_FORMAT_YUYV:
  71. case DRM_FORMAT_YVYU:
  72. f = FORMAT_YUY2;
  73. break;
  74. case DRM_FORMAT_UYVY:
  75. case DRM_FORMAT_VYUY:
  76. f = FORMAT_UYVY;
  77. break;
  78. case DRM_FORMAT_YUV420:
  79. case DRM_FORMAT_YVU420:
  80. f = FORMAT_YV12;
  81. break;
  82. case DRM_FORMAT_NV21:
  83. f = FORMAT_NV12;
  84. break;
  85. case DRM_FORMAT_NV16:
  86. case DRM_FORMAT_NV61:
  87. f = FORMAT_NV16;
  88. break;
  89. case DRM_FORMAT_P010:
  90. f = FORMAT_P010;
  91. break;
  92. case DRM_FORMAT_ARGB2101010:
  93. case DRM_FORMAT_RGBA1010102:
  94. case DRM_FORMAT_ABGR2101010:
  95. case DRM_FORMAT_BGRA1010102:
  96. f = FORMAT_A2R10G10B10;
  97. break;
  98. case DRM_FORMAT_NV12:
  99. if (fourcc_mod_vs_get_type(mod) ==
  100. DRM_FORMAT_MOD_VS_TYPE_CUSTOM_10BIT)
  101. f = FORMAT_NV12_10BIT;
  102. else
  103. f = FORMAT_NV12;
  104. break;
  105. case DRM_FORMAT_YUV444:
  106. if (fourcc_mod_vs_get_type(mod) ==
  107. DRM_FORMAT_MOD_VS_TYPE_CUSTOM_10BIT)
  108. f = FORMAT_YUV444_10BIT;
  109. else
  110. f = FORMAT_YUV444;
  111. break;
  112. default:
  113. break;
  114. }
  115. fb->format = f;
  116. }
  117. static inline void update_swizzle(u32 format, struct dc_hw_fb *fb)
  118. {
  119. fb->swizzle = SWIZZLE_ARGB;
  120. fb->uv_swizzle = 0;
  121. switch (format) {
  122. case DRM_FORMAT_RGBX4444:
  123. case DRM_FORMAT_RGBA4444:
  124. case DRM_FORMAT_RGBX5551:
  125. case DRM_FORMAT_RGBA5551:
  126. case DRM_FORMAT_RGBX8888:
  127. case DRM_FORMAT_RGBA8888:
  128. case DRM_FORMAT_RGBA1010102:
  129. fb->swizzle = SWIZZLE_RGBA;
  130. break;
  131. case DRM_FORMAT_XBGR4444:
  132. case DRM_FORMAT_ABGR4444:
  133. case DRM_FORMAT_XBGR1555:
  134. case DRM_FORMAT_ABGR1555:
  135. case DRM_FORMAT_BGR565:
  136. case DRM_FORMAT_XBGR8888:
  137. case DRM_FORMAT_ABGR8888:
  138. case DRM_FORMAT_ABGR2101010:
  139. fb->swizzle = SWIZZLE_ABGR;
  140. break;
  141. case DRM_FORMAT_BGRX4444:
  142. case DRM_FORMAT_BGRA4444:
  143. case DRM_FORMAT_BGRX5551:
  144. case DRM_FORMAT_BGRA5551:
  145. case DRM_FORMAT_BGRX8888:
  146. case DRM_FORMAT_BGRA8888:
  147. case DRM_FORMAT_BGRA1010102:
  148. fb->swizzle = SWIZZLE_BGRA;
  149. break;
  150. case DRM_FORMAT_YVYU:
  151. case DRM_FORMAT_VYUY:
  152. case DRM_FORMAT_NV21:
  153. case DRM_FORMAT_NV61:
  154. fb->uv_swizzle = 1;
  155. break;
  156. default:
  157. break;
  158. }
  159. }
  160. static inline void update_watermark(struct drm_property_blob *watermark,
  161. struct dc_hw_fb *fb)
  162. {
  163. struct drm_vs_watermark *data;
  164. fb->water_mark = 0;
  165. if (watermark) {
  166. data = watermark->data;
  167. fb->water_mark = data->watermark & 0xFFFFF;
  168. }
  169. }
  170. static inline u8 to_vs_rotation(unsigned int rotation)
  171. {
  172. u8 rot;
  173. switch (rotation & DRM_MODE_REFLECT_MASK) {
  174. case DRM_MODE_REFLECT_X:
  175. rot = FLIP_X;
  176. return rot;
  177. case DRM_MODE_REFLECT_Y:
  178. rot = FLIP_Y;
  179. return rot;
  180. case DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y:
  181. rot = FLIP_XY;
  182. return rot;
  183. default:
  184. break;
  185. }
  186. switch (rotation & DRM_MODE_ROTATE_MASK) {
  187. case DRM_MODE_ROTATE_0:
  188. rot = ROT_0;
  189. break;
  190. case DRM_MODE_ROTATE_90:
  191. rot = ROT_90;
  192. break;
  193. case DRM_MODE_ROTATE_180:
  194. rot = ROT_180;
  195. break;
  196. case DRM_MODE_ROTATE_270:
  197. rot = ROT_270;
  198. break;
  199. default:
  200. rot = ROT_0;
  201. break;
  202. }
  203. return rot;
  204. }
  205. static inline u8 to_vs_yuv_color_space(u32 color_space)
  206. {
  207. u8 cs;
  208. switch (color_space) {
  209. case DRM_COLOR_YCBCR_BT601:
  210. cs = COLOR_SPACE_601;
  211. break;
  212. case DRM_COLOR_YCBCR_BT709:
  213. cs = COLOR_SPACE_709;
  214. break;
  215. case DRM_COLOR_YCBCR_BT2020:
  216. cs = COLOR_SPACE_2020;
  217. break;
  218. default:
  219. cs = COLOR_SPACE_601;
  220. break;
  221. }
  222. return cs;
  223. }
  224. static inline u8 to_vs_tile_mode(u64 modifier)
  225. {
  226. return (u8)(modifier & DRM_FORMAT_MOD_VS_NORM_MODE_MASK);
  227. }
  228. static inline u8 to_vs_display_id(struct vs_dc *dc, struct drm_crtc *crtc)
  229. {
  230. u8 panel_num = dc->hw.info->panel_num;
  231. u32 index = drm_crtc_index(crtc);
  232. int i;
  233. for (i = 0; i < panel_num; i++) {
  234. if (index == dc->crtc[i]->base.index)
  235. return i;
  236. }
  237. return 0;
  238. }
  239. static void dc_deinit(struct device *dev)
  240. {
  241. struct vs_dc *dc = dev_get_drvdata(dev);
  242. pm_runtime_get_sync(dev);
  243. dc_hw_enable_interrupt(&dc->hw, 0);
  244. dc_hw_deinit(&dc->hw);
  245. pm_runtime_put(dev);
  246. }
  247. static int dc_init(struct device *dev)
  248. {
  249. struct vs_dc *dc = dev_get_drvdata(dev);
  250. int ret = 0, i;
  251. dc->first_frame = true;
  252. for (i = 0; i < DC_DISPLAY_NUM; i++)
  253. dc->pix_clk_rate[i] = clk_get_rate(dc->pixclk[i]) / 1000;
  254. pm_runtime_get_sync(dev);
  255. ret = dc_hw_init(&dc->hw);
  256. if (ret) {
  257. dev_err(dev, "failed to init DC HW\n");
  258. goto out;
  259. }
  260. out:
  261. pm_runtime_put(dev);
  262. return ret;
  263. }
  264. static void vs_dc_dump_enable(struct device *dev, dma_addr_t addr,
  265. unsigned int pitch)
  266. {
  267. struct vs_dc *dc = dev_get_drvdata(dev);
  268. dc_hw_enable_dump(&dc->hw, addr, pitch);
  269. }
  270. static void vs_dc_dump_disable(struct device *dev)
  271. {
  272. struct vs_dc *dc = dev_get_drvdata(dev);
  273. dc_hw_disable_dump(&dc->hw);
  274. }
  275. static void vs_dc_enable(struct device *dev, struct drm_crtc *crtc)
  276. {
  277. struct vs_dc *dc = dev_get_drvdata(dev);
  278. struct vs_crtc_state *crtc_state = to_vs_crtc_state(crtc->state);
  279. struct drm_display_mode *mode = &crtc->state->adjusted_mode;
  280. struct dc_hw_display display;
  281. display.bus_format = crtc_state->output_fmt;
  282. display.h_active = mode->hdisplay;
  283. display.h_total = mode->htotal;
  284. display.h_sync_start = mode->hsync_start;
  285. display.h_sync_end = mode->hsync_end;
  286. if (mode->flags & DRM_MODE_FLAG_PHSYNC)
  287. display.h_sync_polarity = true;
  288. else
  289. display.h_sync_polarity = false;
  290. display.v_active = mode->vdisplay;
  291. display.v_total = mode->vtotal;
  292. display.v_sync_start = mode->vsync_start;
  293. display.v_sync_end = mode->vsync_end;
  294. if (mode->flags & DRM_MODE_FLAG_PVSYNC)
  295. display.v_sync_polarity = true;
  296. else
  297. display.v_sync_polarity = false;
  298. display.sync_mode = crtc_state->sync_mode;
  299. display.bg_color = crtc_state->bg_color;
  300. display.id = to_vs_display_id(dc, crtc);
  301. display.sync_enable = crtc_state->sync_enable;
  302. display.dither_enable = crtc_state->dither_enable;
  303. display.enable = true;
  304. if (dc->pix_clk_rate[display.id] != mode->clock) {
  305. clk_set_rate(dc->pixclk[display.id], mode->clock * 1000);
  306. dc->pix_clk_rate[display.id] = mode->clock;
  307. }
  308. if (crtc_state->encoder_type == DRM_MODE_ENCODER_DSI ||
  309. crtc_state->encoder_type == DRM_MODE_ENCODER_DPI)
  310. dc_hw_set_out(&dc->hw, OUT_DPI, display.id);
  311. else
  312. dc_hw_set_out(&dc->hw, OUT_DP, display.id);
  313. #ifdef CONFIG_VERISILICON_MMU
  314. if (crtc_state->mmu_prefetch == VS_MMU_PREFETCH_ENABLE)
  315. dc_hw_enable_mmu_prefetch(&dc->hw, true);
  316. else
  317. dc_hw_enable_mmu_prefetch(&dc->hw, false);
  318. #endif
  319. dc_hw_setup_display(&dc->hw, &display);
  320. }
  321. static void vs_dc_disable(struct device *dev, struct drm_crtc *crtc)
  322. {
  323. struct vs_dc *dc = dev_get_drvdata(dev);
  324. struct dc_hw_display display;
  325. display.id = to_vs_display_id(dc, crtc);
  326. display.enable = false;
  327. dc_hw_setup_display(&dc->hw, &display);
  328. }
  329. static bool vs_dc_mode_fixup(struct device *dev,
  330. struct drm_crtc *crtc,
  331. const struct drm_display_mode *mode,
  332. struct drm_display_mode *adjusted_mode)
  333. {
  334. struct vs_dc *dc = dev_get_drvdata(dev);
  335. int id = to_vs_display_id(dc, crtc);
  336. long clk_rate;
  337. if (unlikely(id >= DC_DISPLAY_NUM)) {
  338. dev_err(dev, "invalid display id : %d\n", id);
  339. return false;
  340. }
  341. if (dc->pixclk[id]) {
  342. clk_rate = clk_round_rate(dc->pixclk[id],
  343. adjusted_mode->clock * 1000);
  344. adjusted_mode->clock = DIV_ROUND_UP(clk_rate, 1000);
  345. }
  346. return true;
  347. }
  348. static void vs_dc_set_gamma(struct device *dev, struct drm_crtc *crtc,
  349. struct drm_color_lut *lut, unsigned int size)
  350. {
  351. struct vs_dc *dc = dev_get_drvdata(dev);
  352. u16 i, r, g, b;
  353. u8 bits, id;
  354. if (size != dc->hw.info->gamma_size) {
  355. dev_err(dev, "gamma size does not match!\n");
  356. return;
  357. }
  358. id = to_vs_display_id(dc, crtc);
  359. bits = dc->hw.info->gamma_bits;
  360. for (i = 0; i < size; i++) {
  361. r = drm_color_lut_extract(lut[i].red, bits);
  362. g = drm_color_lut_extract(lut[i].green, bits);
  363. b = drm_color_lut_extract(lut[i].blue, bits);
  364. dc_hw_update_gamma(&dc->hw, id, i, r, g, b);
  365. }
  366. }
  367. static void vs_dc_enable_gamma(struct device *dev, struct drm_crtc *crtc,
  368. bool enable)
  369. {
  370. struct vs_dc *dc = dev_get_drvdata(dev);
  371. u8 id;
  372. id = to_vs_display_id(dc, crtc);
  373. dc_hw_enable_gamma(&dc->hw, id, enable);
  374. }
  375. static void vs_dc_enable_vblank(struct device *dev, struct drm_crtc *crtc,
  376. bool enable)
  377. {
  378. struct vs_dc *dc = dev_get_drvdata(dev);
  379. dc_hw_enable_irq(&dc->hw, crtc->index, enable);
  380. }
  381. static u32 calc_factor(u32 src, u32 dest)
  382. {
  383. u32 factor = 1 << 16;
  384. if ((src > 1) && (dest > 1))
  385. factor = ((src - 1) << 16) / (dest - 1);
  386. return factor;
  387. }
  388. static void update_scale(struct drm_plane_state *state, struct dc_hw_roi *roi,
  389. struct dc_hw_scale *scale)
  390. {
  391. int dst_w = drm_rect_width(&state->dst);
  392. int dst_h = drm_rect_height(&state->dst);
  393. int src_w, src_h, temp;
  394. scale->enable = false;
  395. if (roi->enable) {
  396. src_w = roi->width;
  397. src_h = roi->height;
  398. } else {
  399. src_w = drm_rect_width(&state->src) >> 16;
  400. src_h = drm_rect_height(&state->src) >> 16;
  401. }
  402. if (drm_rotation_90_or_270(state->rotation)) {
  403. temp = src_w;
  404. src_w = src_h;
  405. src_h = temp;
  406. }
  407. if (src_w != dst_w) {
  408. scale->scale_factor_x = calc_factor(src_w, dst_w);
  409. scale->enable = true;
  410. } else {
  411. scale->scale_factor_x = 1 << 16;
  412. }
  413. if (src_h != dst_h) {
  414. scale->scale_factor_y = calc_factor(src_h, dst_h);
  415. scale->enable = true;
  416. } else {
  417. scale->scale_factor_y = 1 << 16;
  418. }
  419. }
  420. static void update_fb(struct vs_plane *plane, u8 display_id,
  421. struct dc_hw_fb *fb)
  422. {
  423. struct drm_plane_state *state = plane->base.state;
  424. struct vs_plane_state *plane_state = to_vs_plane_state(state);
  425. struct drm_framebuffer *drm_fb = state->fb;
  426. struct drm_rect *src = &state->src;
  427. fb->display_id = display_id;
  428. fb->y_address = plane->dma_addr[0];
  429. fb->y_stride = drm_fb->pitches[0];
  430. if (drm_fb->format->format == DRM_FORMAT_YVU420) {
  431. fb->u_address = plane->dma_addr[2];
  432. fb->v_address = plane->dma_addr[1];
  433. fb->u_stride = drm_fb->pitches[2];
  434. fb->v_stride = drm_fb->pitches[1];
  435. } else {
  436. fb->u_address = plane->dma_addr[1];
  437. fb->v_address = plane->dma_addr[2];
  438. fb->u_stride = drm_fb->pitches[1];
  439. fb->v_stride = drm_fb->pitches[2];
  440. }
  441. fb->width = drm_rect_width(src) >> 16;
  442. fb->height = drm_rect_height(src) >> 16;
  443. fb->tile_mode = to_vs_tile_mode(drm_fb->modifier);
  444. fb->rotation = to_vs_rotation(state->rotation);
  445. fb->yuv_color_space = to_vs_yuv_color_space(state->color_encoding);
  446. fb->zpos = state->zpos;
  447. fb->enable = state->visible;
  448. update_format(drm_fb->format->format, drm_fb->modifier, fb);
  449. update_swizzle(drm_fb->format->format, fb);
  450. update_watermark(plane_state->watermark, fb);
  451. plane_state->status.tile_mode = fb->tile_mode;
  452. }
  453. #ifdef CONFIG_VERISILICON_DEC
  454. static u8 get_stream_base(u8 id)
  455. {
  456. u8 stream_base = 0;
  457. switch (id) {
  458. case OVERLAY_PLANE_0:
  459. stream_base = 3;
  460. break;
  461. case OVERLAY_PLANE_1:
  462. stream_base = 6;
  463. break;
  464. case PRIMARY_PLANE_1:
  465. stream_base = 16;
  466. break;
  467. case OVERLAY_PLANE_2:
  468. stream_base = 19;
  469. break;
  470. case OVERLAY_PLANE_3:
  471. stream_base = 22;
  472. break;
  473. default:
  474. break;
  475. }
  476. return stream_base;
  477. }
  478. static void update_fbc(struct vs_dc *dc, struct vs_plane *plane, bool *enable)
  479. {
  480. struct dc_dec_fb dec_fb;
  481. struct drm_plane_state *state = plane->base.state;
  482. struct drm_framebuffer *drm_fb = state->fb;
  483. struct vs_dc_plane *dc_plane = &dc->planes[plane->id];
  484. u8 i, stream_id;
  485. if (!dc->hw.info->cap_dec) {
  486. *enable = false;
  487. return;
  488. }
  489. stream_id = get_stream_base(dc_plane->id);
  490. memset(&dec_fb, 0, sizeof(struct dc_dec_fb));
  491. dec_fb.fb = drm_fb;
  492. if (fourcc_mod_vs_get_type(drm_fb->modifier) !=
  493. DRM_FORMAT_MOD_VS_TYPE_COMPRESSED) {
  494. *enable = false;
  495. } else {
  496. *enable = true;
  497. for (i = 0; i < DEC_PLANE_MAX; i++) {
  498. dec_fb.addr[i] = plane->dma_addr[i];
  499. dec_fb.stride[i] = drm_fb->pitches[i];
  500. }
  501. }
  502. dc_dec_config(&dc->dec400l, &dec_fb, stream_id);
  503. }
  504. static void disable_fbc(struct vs_dc *dc, struct vs_plane *plane)
  505. {
  506. struct vs_dc_plane *dc_plane = &dc->planes[plane->id];
  507. u8 stream_id;
  508. if (!dc->hw.info->cap_dec)
  509. return;
  510. stream_id = get_stream_base(dc_plane->id);
  511. dc_dec_config(&dc->dec400l, NULL, stream_id);
  512. }
  513. #endif
  514. static void update_degamma(struct vs_dc *dc, struct vs_plane *plane,
  515. struct vs_plane_state *plane_state)
  516. {
  517. dc_hw_update_degamma(&dc->hw, plane->id, plane_state->degamma);
  518. plane_state->degamma_changed = false;
  519. }
  520. static void update_roi(struct vs_dc *dc, u8 id,
  521. struct vs_plane_state *plane_state,
  522. struct dc_hw_roi *roi)
  523. {
  524. struct drm_vs_roi *data;
  525. struct drm_rect *src = &plane_state->base.src;
  526. u16 src_w = drm_rect_width(src) >> 16;
  527. u16 src_h = drm_rect_height(src) >> 16;
  528. if (plane_state->roi) {
  529. data = plane_state->roi->data;
  530. if (data->enable) {
  531. roi->x = data->roi_x;
  532. roi->y = data->roi_y;
  533. roi->width = (data->roi_x + data->roi_w > src_w) ?
  534. (src_w - data->roi_x) : data->roi_w;
  535. roi->height = (data->roi_y + data->roi_h > src_h) ?
  536. (src_h - data->roi_y) : data->roi_h;
  537. roi->enable = true;
  538. } else {
  539. roi->enable = false;
  540. }
  541. dc_hw_update_roi(&dc->hw, id, roi);
  542. } else {
  543. roi->enable = false;
  544. }
  545. }
  546. static void update_color_mgmt(struct vs_dc *dc, u8 id,
  547. struct dc_hw_fb *fb,
  548. struct vs_plane_state *plane_state)
  549. {
  550. struct drm_vs_color_mgmt *data;
  551. struct dc_hw_colorkey colorkey;
  552. if (plane_state->color_mgmt) {
  553. data = plane_state->color_mgmt->data;
  554. fb->clear_enable = data->clear_enable;
  555. fb->clear_value = data->clear_value;
  556. if (data->colorkey > data->colorkey_high)
  557. data->colorkey = data->colorkey_high;
  558. colorkey.colorkey = data->colorkey;
  559. colorkey.colorkey_high = data->colorkey_high;
  560. colorkey.transparency = (data->transparency) ?
  561. DC_TRANSPARENCY_KEY : DC_TRANSPARENCY_OPAQUE;
  562. dc_hw_update_colorkey(&dc->hw, id, &colorkey);
  563. }
  564. }
  565. static void update_plane(struct vs_dc *dc, struct vs_plane *plane)
  566. {
  567. struct dc_hw_fb fb = {0};
  568. struct dc_hw_scale scale;
  569. struct dc_hw_position pos;
  570. struct dc_hw_blend blend;
  571. struct dc_hw_roi roi;
  572. struct drm_plane_state *state = plane->base.state;
  573. struct vs_plane_state *plane_state = to_vs_plane_state(state);
  574. struct drm_rect *dest = &state->dst;
  575. bool dec_enable = false;
  576. u8 display_id = 0;
  577. #ifdef CONFIG_VERISILICON_DEC
  578. update_fbc(dc, plane, &dec_enable);
  579. #endif
  580. display_id = to_vs_display_id(dc, state->crtc);
  581. update_fb(plane, display_id, &fb);
  582. fb.dec_enable = dec_enable;
  583. update_roi(dc, plane->id, plane_state, &roi);
  584. update_scale(state, &roi, &scale);
  585. if (plane_state->degamma_changed)
  586. update_degamma(dc, plane, plane_state);
  587. pos.start_x = dest->x1;
  588. pos.start_y = dest->y1;
  589. pos.end_x = dest->x2;
  590. pos.end_y = dest->y2;
  591. blend.alpha = (u8)(state->alpha >> 8);
  592. blend.blend_mode = (u8)(state->pixel_blend_mode);
  593. update_color_mgmt(dc, plane->id, &fb, plane_state);
  594. dc_hw_update_plane(&dc->hw, plane->id, &fb, &scale, &pos, &blend);
  595. }
  596. static void update_qos(struct vs_dc *dc, struct vs_plane *plane)
  597. {
  598. struct drm_plane_state *state = plane->base.state;
  599. struct vs_plane_state *plane_state = to_vs_plane_state(state);
  600. struct drm_vs_watermark *data;
  601. struct dc_hw_qos qos;
  602. if (plane_state->watermark){
  603. data = plane_state->watermark->data;
  604. if (data->qos_high) {
  605. if (data->qos_low > data->qos_high)
  606. data->qos_low = data->qos_high;
  607. qos.low_value = data->qos_low & 0x0F;
  608. qos.high_value = data->qos_high & 0x0F;
  609. dc_hw_update_qos(&dc->hw, &qos);
  610. }
  611. }
  612. }
  613. static void update_cursor_size(struct drm_plane_state *state, struct dc_hw_cursor *cursor)
  614. {
  615. u8 size_type;
  616. switch (state->crtc_w) {
  617. case 32:
  618. size_type = CURSOR_SIZE_32X32;
  619. break;
  620. case 64:
  621. size_type = CURSOR_SIZE_64X64;
  622. break;
  623. default:
  624. size_type = CURSOR_SIZE_32X32;
  625. break;
  626. }
  627. cursor->size = size_type;
  628. }
  629. static void update_cursor_plane(struct vs_dc *dc, struct vs_plane *plane)
  630. {
  631. struct drm_plane_state *state = plane->base.state;
  632. struct drm_framebuffer *drm_fb = state->fb;
  633. struct dc_hw_cursor cursor;
  634. cursor.address = plane->dma_addr[0];
  635. cursor.x = state->crtc_x;
  636. cursor.y = state->crtc_y;
  637. cursor.hot_x = drm_fb->hot_x;
  638. cursor.hot_y = drm_fb->hot_y;
  639. cursor.display_id = to_vs_display_id(dc, state->crtc);
  640. update_cursor_size(state, &cursor);
  641. cursor.enable = true;
  642. dc_hw_update_cursor(&dc->hw, cursor.display_id, &cursor);
  643. }
  644. static void vs_dc_update_plane(struct device *dev, struct vs_plane *plane)
  645. {
  646. struct vs_dc *dc = dev_get_drvdata(dev);
  647. enum drm_plane_type type = plane->base.type;
  648. switch (type) {
  649. case DRM_PLANE_TYPE_PRIMARY:
  650. case DRM_PLANE_TYPE_OVERLAY:
  651. update_plane(dc, plane);
  652. update_qos(dc, plane);
  653. break;
  654. case DRM_PLANE_TYPE_CURSOR:
  655. update_cursor_plane(dc, plane);
  656. break;
  657. default:
  658. break;
  659. }
  660. }
  661. static void vs_dc_disable_plane(struct device *dev, struct vs_plane *plane,
  662. struct drm_plane_state *old_state)
  663. {
  664. struct vs_dc *dc = dev_get_drvdata(dev);
  665. enum drm_plane_type type = plane->base.type;
  666. struct dc_hw_fb fb = {0};
  667. struct dc_hw_cursor cursor = {0};
  668. switch (type) {
  669. case DRM_PLANE_TYPE_PRIMARY:
  670. case DRM_PLANE_TYPE_OVERLAY:
  671. fb.enable = false;
  672. dc_hw_update_plane(&dc->hw, plane->id, &fb, NULL, NULL, NULL);
  673. #ifdef CONFIG_VERISILICON_DEC
  674. disable_fbc(dc, plane);
  675. #endif
  676. break;
  677. case DRM_PLANE_TYPE_CURSOR:
  678. cursor.enable = false;
  679. cursor.display_id = to_vs_display_id(dc, old_state->crtc);
  680. dc_hw_update_cursor(&dc->hw, cursor.display_id, &cursor);
  681. break;
  682. default:
  683. break;
  684. }
  685. }
  686. static bool vs_dc_mod_supported(const struct vs_plane_info *plane_info,
  687. u64 modifier)
  688. {
  689. const u64 *mods;
  690. if (plane_info->modifiers == NULL)
  691. return false;
  692. for(mods = plane_info->modifiers; *mods != DRM_FORMAT_MOD_INVALID; mods++) {
  693. if (*mods == modifier)
  694. return true;
  695. }
  696. return false;
  697. }
  698. static int vs_dc_check_plane(struct device *dev, struct vs_plane *plane,
  699. struct drm_plane_state *state)
  700. {
  701. struct vs_dc *dc = dev_get_drvdata(dev);
  702. struct drm_framebuffer *fb = state->fb;
  703. const struct vs_plane_info *plane_info;
  704. struct drm_crtc *crtc = state->crtc;
  705. struct drm_crtc_state *crtc_state;
  706. plane_info = &dc->hw.info->planes[plane->id];
  707. if (plane_info == NULL)
  708. return -EINVAL;
  709. if (fb->width < plane_info->min_width ||
  710. fb->width > plane_info->max_width ||
  711. fb->height < plane_info->min_height ||
  712. fb->height > plane_info->max_height)
  713. dev_err_once(dev, "buffer size may not support on plane%d.\n",
  714. plane->id);
  715. if ((plane->base.type != DRM_PLANE_TYPE_CURSOR) &&
  716. (!vs_dc_mod_supported(plane_info, fb->modifier))) {
  717. dev_err(dev, "unsupported modifier on plane%d.\n", plane->id);
  718. return -EINVAL;
  719. }
  720. crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc);
  721. if (IS_ERR(crtc_state))
  722. return -EINVAL;
  723. /* 90/270 degree rotation requires non-linear fb */
  724. if ((state->rotation == DRM_MODE_ROTATE_90 ||
  725. state->rotation == DRM_MODE_ROTATE_270) &&
  726. (fb->modifier & DRM_FORMAT_MOD_LINEAR) == DRM_FORMAT_MOD_LINEAR)
  727. return -EINVAL;
  728. return drm_atomic_helper_check_plane_state(state, crtc_state,
  729. plane_info->min_scale,
  730. plane_info->max_scale,
  731. true, true);
  732. }
  733. static irqreturn_t dc_isr(int irq, void *data)
  734. {
  735. struct vs_dc *dc = data;
  736. struct vs_dc_info *dc_info = dc->hw.info;
  737. u32 i, intr_vec;
  738. intr_vec = dc_hw_get_interrupt(&dc->hw);
  739. for (i = 0; i < dc_info->panel_num; i++) {
  740. if (intr_vec & BIT(i))
  741. vs_crtc_handle_vblank(&dc->crtc[i]->base,
  742. dc_hw_check_underflow(&dc->hw));
  743. }
  744. if (intr_vec & ~0x3)
  745. pr_warn("%s: unhandled interrupt %#x\n", __func__, intr_vec);
  746. return IRQ_HANDLED;
  747. }
  748. static void vs_dc_commit(struct device *dev)
  749. {
  750. struct vs_dc *dc = dev_get_drvdata(dev);
  751. #ifdef CONFIG_VERISILICON_DEC
  752. if (dc->hw.info->cap_dec)
  753. dc_dec_commit(&dc->dec400l, &dc->hw);
  754. #endif
  755. dc_hw_enable_shadow_register(&dc->hw, false);
  756. dc_hw_commit(&dc->hw);
  757. if (dc->first_frame)
  758. dc->first_frame = false;
  759. dc_hw_enable_shadow_register(&dc->hw, true);
  760. }
  761. static const struct vs_crtc_funcs dc_crtc_funcs = {
  762. .enable = vs_dc_enable,
  763. .disable = vs_dc_disable,
  764. .mode_fixup = vs_dc_mode_fixup,
  765. .set_gamma = vs_dc_set_gamma,
  766. .enable_gamma = vs_dc_enable_gamma,
  767. .enable_vblank = vs_dc_enable_vblank,
  768. .commit = vs_dc_commit,
  769. };
  770. static const struct vs_plane_funcs dc_plane_funcs = {
  771. .update = vs_dc_update_plane,
  772. .disable = vs_dc_disable_plane,
  773. .check = vs_dc_check_plane,
  774. };
  775. static const struct vs_dc_funcs dc_funcs = {
  776. .dump_enable = vs_dc_dump_enable,
  777. .dump_disable = vs_dc_dump_disable,
  778. };
  779. static int dc_bind(struct device *dev, struct device *master, void *data)
  780. {
  781. struct drm_device *drm_dev = data;
  782. #ifdef CONFIG_VERISILICON_MMU
  783. struct vs_drm_private *priv = drm_dev->dev_private;
  784. #endif
  785. struct vs_dc *dc = dev_get_drvdata(dev);
  786. struct device_node *port;
  787. struct vs_crtc *crtc;
  788. struct drm_crtc *drm_crtc;
  789. struct vs_dc_info *dc_info;
  790. struct vs_plane *plane;
  791. struct drm_plane *drm_plane, *tmp;
  792. struct vs_plane_info *plane_info;
  793. int i, ret;
  794. u32 ctrc_mask = 0;
  795. if (!drm_dev || !dc) {
  796. dev_err(dev, "devices are not created.\n");
  797. return -ENODEV;
  798. }
  799. ret = dc_init(dev);
  800. if (ret < 0) {
  801. dev_err(dev, "Failed to initialize DC hardware.\n");
  802. return ret;
  803. }
  804. #ifdef CONFIG_VERISILICON_MMU
  805. ret = dc_mmu_construct(priv->dma_dev, &priv->mmu);
  806. if (ret) {
  807. dev_err(dev, "failed to construct DC MMU\n");
  808. goto err_clean_dc;
  809. }
  810. ret = dc_hw_mmu_init(&dc->hw, priv->mmu);
  811. if (ret) {
  812. dev_err(dev, "failed to init DC MMU\n");
  813. goto err_clean_dc;
  814. }
  815. #endif
  816. ret = vs_drm_iommu_attach_device(drm_dev, dev);
  817. if (ret < 0) {
  818. dev_err(dev, "Failed to attached iommu device.\n");
  819. goto err_clean_dc;
  820. }
  821. if (!of_graph_is_present(dev->of_node)) {
  822. dev_err(dev, "no port node found\n");
  823. ret = -ENODEV;
  824. goto err_detach_dev;
  825. }
  826. dc_info = dc->hw.info;
  827. for(i = 0; i < dc_info->panel_num; i++) {
  828. port = of_graph_get_port_by_id(dev->of_node, i);
  829. if (!port) {
  830. dev_err(dev, "no port node found for panel %d\n", i);
  831. ret = -ENODEV;
  832. goto err_detach_dev;
  833. };
  834. crtc = vs_crtc_create(drm_dev, dc_info);
  835. if (!crtc) {
  836. dev_err(dev, "Failed to create CRTC.\n");
  837. ret = -ENOMEM;
  838. goto err_detach_dev;
  839. }
  840. crtc->base.port = port;
  841. crtc->dev = dev;
  842. crtc->funcs = &dc_crtc_funcs;
  843. dc->crtc[i] = crtc;
  844. ctrc_mask |= drm_crtc_mask(&crtc->base);
  845. }
  846. for (i = 0; i < dc_info->plane_num; i++) {
  847. plane_info = (struct vs_plane_info *)&dc_info->planes[i];
  848. if (!strcmp(plane_info->name, "Primary") ||
  849. !strcmp(plane_info->name, "Cursor"))
  850. plane = vs_plane_create(drm_dev, plane_info, dc_info->layer_num,
  851. drm_crtc_mask(&dc->crtc[0]->base));
  852. else if (!strcmp(plane_info->name, "Primary_1") ||
  853. !strcmp(plane_info->name, "Cursor_1"))
  854. plane = vs_plane_create(drm_dev, plane_info, dc_info->layer_num,
  855. drm_crtc_mask(&dc->crtc[1]->base));
  856. else
  857. plane = vs_plane_create(drm_dev, plane_info,
  858. dc_info->layer_num, ctrc_mask);
  859. if (!plane)
  860. goto err_cleanup_planes;
  861. plane->id = i;
  862. dc->planes[i].id = plane_info->id;
  863. plane->funcs = &dc_plane_funcs;
  864. if (plane_info->type == DRM_PLANE_TYPE_PRIMARY) {
  865. if (!strcmp(plane_info->name, "Primary"))
  866. dc->crtc[0]->base.primary = &plane->base;
  867. else
  868. dc->crtc[1]->base.primary = &plane->base;
  869. drm_dev->mode_config.min_width = plane_info->min_width;
  870. drm_dev->mode_config.min_height =
  871. plane_info->min_height;
  872. drm_dev->mode_config.max_width = plane_info->max_width;
  873. drm_dev->mode_config.max_height =
  874. plane_info->max_height;
  875. }
  876. if (plane_info->type == DRM_PLANE_TYPE_CURSOR) {
  877. if (!strcmp(plane_info->name, "Cursor"))
  878. dc->crtc[0]->base.cursor = &plane->base;
  879. else
  880. dc->crtc[1]->base.cursor = &plane->base;
  881. drm_dev->mode_config.cursor_width =
  882. plane_info->max_width;
  883. drm_dev->mode_config.cursor_height =
  884. plane_info->max_height;
  885. }
  886. }
  887. dc->funcs = &dc_funcs;
  888. vs_drm_update_pitch_alignment(drm_dev, dc_info->pitch_alignment);
  889. return 0;
  890. err_cleanup_planes:
  891. list_for_each_entry_safe(drm_plane, tmp,
  892. &drm_dev->mode_config.plane_list, head)
  893. if (drm_plane->possible_crtcs & ctrc_mask)
  894. vs_plane_destory(drm_plane);
  895. drm_for_each_crtc(drm_crtc, drm_dev)
  896. vs_crtc_destroy(drm_crtc);
  897. err_detach_dev:
  898. vs_drm_iommu_detach_device(drm_dev, dev);
  899. err_clean_dc:
  900. dc_deinit(dev);
  901. return ret;
  902. }
  903. static void dc_unbind(struct device *dev, struct device *master, void *data)
  904. {
  905. struct drm_device *drm_dev = data;
  906. dc_deinit(dev);
  907. vs_drm_iommu_detach_device(drm_dev, dev);
  908. }
  909. const struct component_ops dc_component_ops = {
  910. .bind = dc_bind,
  911. .unbind = dc_unbind,
  912. };
  913. static const struct of_device_id dc_driver_dt_match[] = {
  914. { .compatible = "verisilicon,dc8200", },
  915. {},
  916. };
  917. MODULE_DEVICE_TABLE(of, dc_driver_dt_match);
  918. static void dc_get_display_pll(struct device *dev, struct vs_dc *dc)
  919. {
  920. struct device_node *np;
  921. np = of_find_node_by_name(NULL, "dw-mipi-dsi0");
  922. if (!np)
  923. dev_err(dev, "Failed to get dsi0\n");
  924. else
  925. dc->dpu0pll_on = of_device_is_available(np);
  926. np = of_find_node_by_name(NULL, "dw-mipi-dsi1");
  927. if (!np)
  928. dev_err(dev, "Failed to get dsi1\n");
  929. else
  930. dc->dpu1pll_on = of_device_is_available(np);
  931. /* dsi1/hdmi share the same pll1, hdmi detect again if dsi1 not use */
  932. if (!dc->dpu1pll_on) {
  933. np = of_find_node_by_name(NULL, "dw-hdmi-tx");
  934. if (!np)
  935. dev_err(dev, "Failed to get hdmi\n");
  936. else
  937. dc->dpu1pll_on = of_device_is_available(np);
  938. }
  939. dev_info(dev, "dpu0pll_on:%d dpu1pll_on:%d\n", dc->dpu0pll_on,
  940. dc->dpu1pll_on);
  941. }
  942. static int dc_probe(struct platform_device *pdev)
  943. {
  944. struct device *dev = &pdev->dev;
  945. struct vs_dc *dc;
  946. int irq, ret, i;
  947. char pixclk[16];
  948. dc = devm_kzalloc(dev, sizeof(*dc), GFP_KERNEL);
  949. if (!dc)
  950. return -ENOMEM;
  951. dc->hw.hi_base = devm_platform_ioremap_resource(pdev, 0);
  952. if (IS_ERR(dc->hw.hi_base))
  953. return PTR_ERR(dc->hw.hi_base);
  954. dc->hw.reg_base = devm_platform_ioremap_resource(pdev, 1);
  955. if (IS_ERR(dc->hw.reg_base))
  956. return PTR_ERR(dc->hw.reg_base);
  957. #ifdef CONFIG_VERISILICON_MMU
  958. dc->hw.mmu_base = devm_platform_ioremap_resource(pdev, 2);
  959. if (IS_ERR(dc->hw.mmu_base))
  960. return PTR_ERR(dc->hw.mmu_base);
  961. #endif
  962. irq = platform_get_irq(pdev, 0);
  963. ret = devm_request_irq(dev, irq, dc_isr, 0, dev_name(dev), dc);
  964. if (ret < 0) {
  965. dev_err(dev, "Failed to install irq:%u.\n", irq);
  966. return ret;
  967. }
  968. dc->core_clk = devm_clk_get_optional(dev, "core_clk");
  969. if (IS_ERR(dc->core_clk)) {
  970. dev_err(dev, "failed to get core_clk source\n");
  971. return PTR_ERR(dc->core_clk);
  972. }
  973. for (i = 0; i < DC_DISPLAY_NUM; i++) {
  974. snprintf(pixclk, ARRAY_SIZE(pixclk), "%s%d", "pix_clk", i);
  975. dc->pix_clk[i] = devm_clk_get_optional(dev, pixclk);
  976. if (IS_ERR(dc->pix_clk[i])) {
  977. dev_err(dev, "failed to get pix_clk %d source\n", i);
  978. return PTR_ERR(dc->pix_clk[i]);
  979. }
  980. snprintf(pixclk, ARRAY_SIZE(pixclk), "%s%d", "pixclk", i);
  981. dc->pixclk[i] = devm_clk_get_optional(dev, pixclk);
  982. if (IS_ERR(dc->pixclk[i])) {
  983. dev_err(dev, "failed to get pixclk %d source\n", i);
  984. return PTR_ERR(dc->pixclk[i]);
  985. }
  986. }
  987. dc->axi_clk = devm_clk_get_optional(dev, "axi_clk");
  988. if (IS_ERR(dc->axi_clk)) {
  989. dev_err(dev, "failed to get axi_clk source\n");
  990. return PTR_ERR(dc->axi_clk);
  991. }
  992. dc->cfg_clk = devm_clk_get_optional(dev, "cfg_clk");
  993. if (IS_ERR(dc->cfg_clk)) {
  994. dev_err(dev, "failed to get cfg_clk source\n");
  995. return PTR_ERR(dc->cfg_clk);
  996. }
  997. dc->dpu0pll_clk = devm_clk_get_optional(dev, "dpu0_pll_foutpostdiv");
  998. if (IS_ERR(dc->dpu0pll_clk)) {
  999. dev_err(dev, "failed to get dpu0pll_clk source\n");
  1000. return PTR_ERR(dc->dpu0pll_clk);
  1001. }
  1002. dc->dpu1pll_clk = devm_clk_get_optional(dev, "dpu1_pll_foutpostdiv");
  1003. if (IS_ERR(dc->dpu1pll_clk)) {
  1004. dev_err(dev, "failed to get dpu1pll_clk source\n");
  1005. return PTR_ERR(dc->dpu1pll_clk);
  1006. }
  1007. dc_get_display_pll(dev, dc);
  1008. dev_set_drvdata(dev, dc);
  1009. pm_runtime_enable(dev);
  1010. return component_add(dev, &dc_component_ops);
  1011. }
  1012. static int dc_remove(struct platform_device *pdev)
  1013. {
  1014. struct device *dev = &pdev->dev;
  1015. component_del(dev, &dc_component_ops);
  1016. pm_runtime_disable(dev);
  1017. dev_set_drvdata(dev, NULL);
  1018. return 0;
  1019. }
  1020. #ifdef CONFIG_PM
  1021. static int dc_runtime_suspend(struct device *dev)
  1022. {
  1023. int i;
  1024. struct vs_dc *dc = dev_get_drvdata(dev);
  1025. dev_dbg(dev, "%s\n", __func__);
  1026. clk_disable_unprepare(dc->axi_clk);
  1027. for (i = 0; i < DC_DISPLAY_NUM; i++)
  1028. clk_disable_unprepare(dc->pix_clk[i]);
  1029. clk_disable_unprepare(dc->core_clk);
  1030. clk_disable_unprepare(dc->cfg_clk);
  1031. if (dc->dpu0pll_on)
  1032. clk_disable_unprepare(dc->dpu0pll_clk);
  1033. if (dc->dpu1pll_on)
  1034. clk_disable_unprepare(dc->dpu1pll_clk);
  1035. return 0;
  1036. }
  1037. static int dc_runtime_resume(struct device *dev)
  1038. {
  1039. int i, ret;
  1040. struct vs_dc *dc = dev_get_drvdata(dev);
  1041. dev_dbg(dev, "%s\n", __func__);
  1042. if (dc->dpu0pll_on)
  1043. clk_prepare_enable(dc->dpu0pll_clk);
  1044. if (dc->dpu1pll_on)
  1045. clk_prepare_enable(dc->dpu1pll_clk);
  1046. ret = clk_prepare_enable(dc->cfg_clk);
  1047. if (ret < 0) {
  1048. dev_err(dev, "failed to prepare/enable cfg_clk\n");
  1049. return ret;
  1050. }
  1051. ret = clk_prepare_enable(dc->core_clk);
  1052. if (ret < 0) {
  1053. dev_err(dev, "failed to prepare/enable core_clk\n");
  1054. return ret;
  1055. }
  1056. for (i = 0; i < DC_DISPLAY_NUM; i++) {
  1057. ret = clk_prepare_enable(dc->pix_clk[i]);
  1058. if (ret < 0) {
  1059. dev_err(dev, "failed to prepare/enable pix_clk %d\n", i);
  1060. return ret;
  1061. }
  1062. }
  1063. ret = clk_prepare_enable(dc->axi_clk);
  1064. if (ret < 0) {
  1065. dev_err(dev, "failed to prepare/enable axi_clk\n");
  1066. return ret;
  1067. }
  1068. return 0;
  1069. }
  1070. #endif
  1071. static const struct dev_pm_ops dc_pm_ops = {
  1072. SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
  1073. pm_runtime_force_resume)
  1074. SET_RUNTIME_PM_OPS(dc_runtime_suspend, dc_runtime_resume, NULL)
  1075. };
  1076. struct platform_driver dc_platform_driver = {
  1077. .probe = dc_probe,
  1078. .remove = dc_remove,
  1079. .driver = {
  1080. .name = "vs-dc",
  1081. .of_match_table = of_match_ptr(dc_driver_dt_match),
  1082. .pm = &dc_pm_ops,
  1083. },
  1084. };
  1085. MODULE_DESCRIPTION("VeriSilicon DC Driver");
  1086. MODULE_LICENSE("GPL v2");