2 * Xilinx DRM crtc driver for Xilinx
4 * Copyright (C) 2013 Xilinx, Inc.
6 * Author: Hyun Woo Kwon <hyunk@xilinx.com>
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
19 #include <drm/drm_crtc.h>
20 #include <drm/drm_crtc_helper.h>
21 #include <drm/drm_fb_cma_helper.h>
22 #include <drm/drm_gem_cma_helper.h>
24 #include <linux/clk.h>
25 #include <linux/delay.h>
26 #include <linux/device.h>
27 #include <linux/i2c.h>
29 #include <video/videomode.h>
31 #include "xilinx_drm_crtc.h"
32 #include "xilinx_drm_dp_sub.h"
33 #include "xilinx_drm_drv.h"
34 #include "xilinx_drm_plane.h"
36 #include "xilinx_cresample.h"
37 #include "xilinx_rgb2yuv.h"
38 #include "xilinx_vtc.h"
40 struct xilinx_drm_crtc {
42 struct xilinx_cresample *cresample;
43 struct xilinx_rgb2yuv *rgb2yuv;
44 struct clk *pixel_clock;
45 bool pixel_clock_enabled;
46 struct xilinx_vtc *vtc;
47 struct xilinx_drm_plane_manager *plane_manager;
50 struct drm_pending_vblank_event *event;
51 struct xilinx_drm_dp_sub *dp_sub;
54 #define to_xilinx_crtc(x) container_of(x, struct xilinx_drm_crtc, base)
57 static void xilinx_drm_crtc_dpms(struct drm_crtc *base_crtc, int dpms)
59 struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
62 DRM_DEBUG_KMS("dpms: %d -> %d\n", crtc->dpms, dpms);
64 if (crtc->dpms == dpms)
70 case DRM_MODE_DPMS_ON:
71 if (!crtc->pixel_clock_enabled) {
72 ret = clk_prepare_enable(crtc->pixel_clock);
74 DRM_ERROR("failed to enable a pixel clock\n");
76 crtc->pixel_clock_enabled = true;
79 xilinx_drm_plane_manager_dpms(crtc->plane_manager, dpms);
80 xilinx_drm_plane_dpms(base_crtc->primary, dpms);
82 xilinx_rgb2yuv_enable(crtc->rgb2yuv);
84 xilinx_cresample_enable(crtc->cresample);
86 xilinx_vtc_enable(crtc->vtc);
90 xilinx_vtc_disable(crtc->vtc);
91 xilinx_vtc_reset(crtc->vtc);
93 if (crtc->cresample) {
94 xilinx_cresample_disable(crtc->cresample);
95 xilinx_cresample_reset(crtc->cresample);
98 xilinx_rgb2yuv_disable(crtc->rgb2yuv);
99 xilinx_rgb2yuv_reset(crtc->rgb2yuv);
101 xilinx_drm_plane_dpms(base_crtc->primary, dpms);
102 xilinx_drm_plane_manager_dpms(crtc->plane_manager, dpms);
103 if (crtc->pixel_clock_enabled) {
104 clk_disable_unprepare(crtc->pixel_clock);
105 crtc->pixel_clock_enabled = false;
112 static void xilinx_drm_crtc_prepare(struct drm_crtc *base_crtc)
114 xilinx_drm_crtc_dpms(base_crtc, DRM_MODE_DPMS_OFF);
117 /* apply mode to crtc pipe */
118 static void xilinx_drm_crtc_commit(struct drm_crtc *base_crtc)
120 xilinx_drm_crtc_dpms(base_crtc, DRM_MODE_DPMS_ON);
121 xilinx_drm_plane_commit(base_crtc->primary);
125 static bool xilinx_drm_crtc_mode_fixup(struct drm_crtc *base_crtc,
126 const struct drm_display_mode *mode,
127 struct drm_display_mode *adjusted_mode)
133 /* set new mode in crtc pipe */
134 static int xilinx_drm_crtc_mode_set(struct drm_crtc *base_crtc,
135 struct drm_display_mode *mode,
136 struct drm_display_mode *adjusted_mode,
138 struct drm_framebuffer *old_fb)
140 struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
145 if (crtc->pixel_clock_enabled) {
146 clk_disable_unprepare(crtc->pixel_clock);
147 crtc->pixel_clock_enabled = false;
150 /* set pixel clock */
151 ret = clk_set_rate(crtc->pixel_clock, adjusted_mode->clock * 1000);
153 DRM_ERROR("failed to set a pixel clock\n");
157 diff = clk_get_rate(crtc->pixel_clock) - adjusted_mode->clock * 1000;
158 if (abs(diff) > (adjusted_mode->clock * 1000) / 20)
159 DRM_DEBUG_KMS("actual pixel clock rate(%d) is off by %ld\n",
160 adjusted_mode->clock, diff);
163 /* set video timing */
164 vm.hactive = adjusted_mode->hdisplay;
165 vm.hfront_porch = adjusted_mode->hsync_start -
166 adjusted_mode->hdisplay;
167 vm.hback_porch = adjusted_mode->htotal -
168 adjusted_mode->hsync_end;
169 vm.hsync_len = adjusted_mode->hsync_end -
170 adjusted_mode->hsync_start;
172 vm.vactive = adjusted_mode->vdisplay;
173 vm.vfront_porch = adjusted_mode->vsync_start -
174 adjusted_mode->vdisplay;
175 vm.vback_porch = adjusted_mode->vtotal -
176 adjusted_mode->vsync_end;
177 vm.vsync_len = adjusted_mode->vsync_end -
178 adjusted_mode->vsync_start;
181 if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
182 vm.flags |= DISPLAY_FLAGS_INTERLACED;
183 if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
184 vm.flags |= DISPLAY_FLAGS_HSYNC_LOW;
185 if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
186 vm.flags |= DISPLAY_FLAGS_VSYNC_LOW;
188 xilinx_vtc_config_sig(crtc->vtc, &vm);
191 /* configure cresample and rgb2yuv */
193 xilinx_cresample_configure(crtc->cresample,
194 adjusted_mode->hdisplay,
195 adjusted_mode->vdisplay);
197 xilinx_rgb2yuv_configure(crtc->rgb2yuv,
198 adjusted_mode->hdisplay,
199 adjusted_mode->vdisplay);
201 /* configure a plane: vdma and osd layer */
202 xilinx_drm_plane_manager_mode_set(crtc->plane_manager,
203 adjusted_mode->hdisplay,
204 adjusted_mode->vdisplay);
205 ret = xilinx_drm_plane_mode_set(base_crtc->primary,
206 base_crtc->primary->fb, 0, 0,
207 adjusted_mode->hdisplay,
208 adjusted_mode->vdisplay,
210 adjusted_mode->hdisplay,
211 adjusted_mode->vdisplay);
213 DRM_ERROR("failed to mode set a plane\n");
220 static int _xilinx_drm_crtc_mode_set_base(struct drm_crtc *base_crtc,
221 struct drm_framebuffer *fb,
224 struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
227 /* configure a plane */
228 xilinx_drm_plane_manager_mode_set(crtc->plane_manager,
229 base_crtc->hwmode.hdisplay,
230 base_crtc->hwmode.vdisplay);
231 ret = xilinx_drm_plane_mode_set(base_crtc->primary,
233 base_crtc->hwmode.hdisplay,
234 base_crtc->hwmode.vdisplay,
236 base_crtc->hwmode.hdisplay,
237 base_crtc->hwmode.vdisplay);
239 DRM_ERROR("failed to mode set a plane\n");
243 /* apply the new fb addr */
244 xilinx_drm_crtc_commit(base_crtc);
249 /* update address and information from fb */
250 static int xilinx_drm_crtc_mode_set_base(struct drm_crtc *base_crtc,
252 struct drm_framebuffer *old_fb)
254 /* configure a plane */
255 return _xilinx_drm_crtc_mode_set_base(base_crtc, base_crtc->primary->fb,
259 /* load rgb LUT for crtc */
260 static void xilinx_drm_crtc_load_lut(struct drm_crtc *base_crtc)
265 static struct drm_crtc_helper_funcs xilinx_drm_crtc_helper_funcs = {
266 .dpms = xilinx_drm_crtc_dpms,
267 .prepare = xilinx_drm_crtc_prepare,
268 .commit = xilinx_drm_crtc_commit,
269 .mode_fixup = xilinx_drm_crtc_mode_fixup,
270 .mode_set = xilinx_drm_crtc_mode_set,
271 .mode_set_base = xilinx_drm_crtc_mode_set_base,
272 .load_lut = xilinx_drm_crtc_load_lut,
276 void xilinx_drm_crtc_destroy(struct drm_crtc *base_crtc)
278 struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
280 /* make sure crtc is off */
281 xilinx_drm_crtc_dpms(base_crtc, DRM_MODE_DPMS_OFF);
283 drm_crtc_cleanup(base_crtc);
286 xilinx_drm_dp_sub_put(crtc->dp_sub);
288 if (crtc->pixel_clock_enabled) {
289 clk_disable_unprepare(crtc->pixel_clock);
290 crtc->pixel_clock_enabled = false;
293 xilinx_drm_plane_remove_manager(crtc->plane_manager);
296 /* cancel page flip functions */
297 void xilinx_drm_crtc_cancel_page_flip(struct drm_crtc *base_crtc,
298 struct drm_file *file)
300 struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
301 struct drm_device *drm = base_crtc->dev;
302 struct drm_pending_vblank_event *event;
305 spin_lock_irqsave(&drm->event_lock, flags);
307 if (event && (event->base.file_priv == file)) {
310 drm_crtc_vblank_put(base_crtc);
312 spin_unlock_irqrestore(&drm->event_lock, flags);
315 /* finish page flip functions */
316 static void xilinx_drm_crtc_finish_page_flip(struct drm_crtc *base_crtc)
318 struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
319 struct drm_device *drm = base_crtc->dev;
320 struct drm_pending_vblank_event *event;
323 spin_lock_irqsave(&drm->event_lock, flags);
327 drm_crtc_send_vblank_event(base_crtc, event);
328 drm_crtc_vblank_put(base_crtc);
330 spin_unlock_irqrestore(&drm->event_lock, flags);
333 /* page flip functions */
334 static int xilinx_drm_crtc_page_flip(struct drm_crtc *base_crtc,
335 struct drm_framebuffer *fb,
336 struct drm_pending_vblank_event *event,
337 uint32_t page_flip_flags)
339 struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
340 struct drm_device *drm = base_crtc->dev;
344 spin_lock_irqsave(&drm->event_lock, flags);
346 spin_unlock_irqrestore(&drm->event_lock, flags);
349 spin_unlock_irqrestore(&drm->event_lock, flags);
351 /* configure a plane */
352 ret = _xilinx_drm_crtc_mode_set_base(base_crtc, fb,
353 base_crtc->x, base_crtc->y);
355 DRM_ERROR("failed to mode set a plane\n");
359 base_crtc->primary->fb = fb;
363 drm_crtc_vblank_get(base_crtc);
364 spin_lock_irqsave(&drm->event_lock, flags);
366 spin_unlock_irqrestore(&drm->event_lock, flags);
372 /* vblank interrupt handler */
373 static void xilinx_drm_crtc_vblank_handler(void *data)
375 struct drm_crtc *base_crtc = data;
376 struct drm_device *drm;
381 drm = base_crtc->dev;
383 drm_handle_vblank(drm, 0);
384 xilinx_drm_crtc_finish_page_flip(base_crtc);
387 /* enable vblank interrupt */
388 void xilinx_drm_crtc_enable_vblank(struct drm_crtc *base_crtc)
390 struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
393 xilinx_vtc_enable_vblank_intr(crtc->vtc,
394 xilinx_drm_crtc_vblank_handler,
397 xilinx_drm_dp_sub_enable_vblank(crtc->dp_sub,
398 xilinx_drm_crtc_vblank_handler,
402 /* disable vblank interrupt */
403 void xilinx_drm_crtc_disable_vblank(struct drm_crtc *base_crtc)
405 struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
408 xilinx_drm_dp_sub_disable_vblank(crtc->dp_sub);
410 xilinx_vtc_disable_vblank_intr(crtc->vtc);
414 * xilinx_drm_crtc_restore - Restore the crtc states
415 * @base_crtc: base crtc object
417 * Restore the crtc states to the default ones. The request is propagated
418 * to the plane driver.
420 void xilinx_drm_crtc_restore(struct drm_crtc *base_crtc)
422 struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
424 xilinx_drm_plane_restore(crtc->plane_manager);
427 /* check max width */
428 unsigned int xilinx_drm_crtc_get_max_width(struct drm_crtc *base_crtc)
430 return xilinx_drm_plane_get_max_width(base_crtc->primary);
434 bool xilinx_drm_crtc_check_format(struct drm_crtc *base_crtc, uint32_t fourcc)
436 struct xilinx_drm_crtc *crtc = to_xilinx_crtc(base_crtc);
438 return xilinx_drm_plane_check_format(crtc->plane_manager, fourcc);
442 uint32_t xilinx_drm_crtc_get_format(struct drm_crtc *base_crtc)
444 return xilinx_drm_plane_get_format(base_crtc->primary);
448 * xilinx_drm_crtc_get_align - Get the alignment value for pitch
449 * @base_crtc: Base crtc object
451 * Get the alignment value for pitch from the plane
453 * Return: The alignment value if successful, or the error code.
455 unsigned int xilinx_drm_crtc_get_align(struct drm_crtc *base_crtc)
457 return xilinx_drm_plane_get_align(base_crtc->primary);
460 static struct drm_crtc_funcs xilinx_drm_crtc_funcs = {
461 .destroy = xilinx_drm_crtc_destroy,
462 .set_config = drm_crtc_helper_set_config,
463 .page_flip = xilinx_drm_crtc_page_flip,
467 struct drm_crtc *xilinx_drm_crtc_create(struct drm_device *drm)
469 struct xilinx_drm_crtc *crtc;
470 struct drm_plane *primary_plane;
471 struct device_node *sub_node;
472 int possible_crtcs = 1;
475 crtc = devm_kzalloc(drm->dev, sizeof(*crtc), GFP_KERNEL);
477 return ERR_PTR(-ENOMEM);
479 /* probe chroma resampler and enable */
480 sub_node = of_parse_phandle(drm->dev->of_node, "xlnx,cresample", 0);
482 crtc->cresample = xilinx_cresample_probe(drm->dev, sub_node);
483 of_node_put(sub_node);
484 if (IS_ERR(crtc->cresample)) {
485 DRM_ERROR("failed to probe a cresample\n");
486 return ERR_CAST(crtc->cresample);
490 /* probe color space converter and enable */
491 sub_node = of_parse_phandle(drm->dev->of_node, "xlnx,rgb2yuv", 0);
493 crtc->rgb2yuv = xilinx_rgb2yuv_probe(drm->dev, sub_node);
494 of_node_put(sub_node);
495 if (IS_ERR(crtc->rgb2yuv)) {
496 DRM_ERROR("failed to probe a rgb2yuv\n");
497 return ERR_CAST(crtc->rgb2yuv);
501 /* probe a plane manager */
502 crtc->plane_manager = xilinx_drm_plane_probe_manager(drm);
503 if (IS_ERR(crtc->plane_manager)) {
504 if (PTR_ERR(crtc->plane_manager) != -EPROBE_DEFER)
505 DRM_ERROR("failed to probe a plane manager\n");
506 return ERR_CAST(crtc->plane_manager);
509 /* create a primary plane. there's only one crtc now */
510 primary_plane = xilinx_drm_plane_create_primary(crtc->plane_manager,
512 if (IS_ERR(primary_plane)) {
513 DRM_ERROR("failed to create a primary plane for crtc\n");
514 ret = PTR_ERR(primary_plane);
518 /* create extra planes */
519 xilinx_drm_plane_create_planes(crtc->plane_manager, possible_crtcs);
521 crtc->pixel_clock = devm_clk_get(drm->dev, NULL);
522 if (IS_ERR(crtc->pixel_clock)) {
523 if (PTR_ERR(crtc->pixel_clock) == -EPROBE_DEFER) {
524 ret = PTR_ERR(crtc->pixel_clock);
527 DRM_DEBUG_KMS("failed to get pixel clock\n");
528 crtc->pixel_clock = NULL;
532 ret = clk_prepare_enable(crtc->pixel_clock);
534 DRM_ERROR("failed to enable a pixel clock\n");
535 crtc->pixel_clock_enabled = false;
538 clk_disable_unprepare(crtc->pixel_clock);
540 sub_node = of_parse_phandle(drm->dev->of_node, "xlnx,vtc", 0);
542 crtc->vtc = xilinx_vtc_probe(drm->dev, sub_node);
543 of_node_put(sub_node);
544 if (IS_ERR(crtc->vtc)) {
545 DRM_ERROR("failed to probe video timing controller\n");
546 ret = PTR_ERR(crtc->vtc);
551 crtc->dp_sub = xilinx_drm_dp_sub_of_get(drm->dev->of_node);
552 if (IS_ERR(crtc->dp_sub)) {
553 ret = PTR_ERR(crtc->dp_sub);
554 if (ret != -EPROBE_DEFER)
555 DRM_ERROR("failed to get a dp_sub\n");
559 crtc->dpms = DRM_MODE_DPMS_OFF;
561 /* initialize drm crtc */
562 ret = drm_crtc_init_with_planes(drm, &crtc->base, primary_plane,
563 NULL, &xilinx_drm_crtc_funcs, NULL);
565 DRM_ERROR("failed to initialize crtc\n");
568 drm_crtc_helper_add(&crtc->base, &xilinx_drm_crtc_helper_funcs);
573 if (crtc->pixel_clock_enabled) {
574 clk_disable_unprepare(crtc->pixel_clock);
575 crtc->pixel_clock_enabled = false;
578 xilinx_drm_plane_remove_manager(crtc->plane_manager);