diff options
author | Dave Airlie <airlied@redhat.com> | 2016-11-24 18:03:27 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-11-24 18:03:27 -0500 |
commit | 4d5304d87034fe3f003cffa7ef2350d066ef7f3e (patch) | |
tree | 372222b30b2839382917bf9eece89fe086d5dba4 | |
parent | 43167f6c7d7172e0a6cb1ecaa1771a2f457fd165 (diff) | |
parent | e8e11817e2ff18f35de932cdd2738cad5567cb7c (diff) |
Merge branch 'drm-armada-devel' of git://git.armlinux.org.uk/~rmk/linux-arm into drm-next
Building on top of the MALI change previously merged, these changes:
* add tracing support for overlay updates
* refactor some of the plane support code
* de-midlayer the driver
* cleanups from other folk reviewing the code
* 'drm-armada-devel' of git://git.armlinux.org.uk/~rmk/linux-arm:
drm/armada: fix NULL pointer comparison warning
drm/armada: use DRM_FB_HELPER_DEFAULT_OPS for fb_ops
drm/armada: remove some dead code
drm/armada: mark symbols static where possible
drm/armada: de-midlayer armada
drm/armada: use common helper for plane base address
drm/armada: move setting primary plane position to armada_drm_primary_set()
drm/armada: split out primary plane update
drm/armada: move plane state to struct armada_plane
drm/armada: clean up armada_drm_plane_work_run()
drm/armada: add tracing support
-rw-r--r-- | drivers/gpu/drm/armada/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/armada/armada_crtc.c | 121 | ||||
-rw-r--r-- | drivers/gpu/drm/armada/armada_crtc.h | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/armada/armada_debugfs.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/armada/armada_drm.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/armada/armada_drv.c | 236 | ||||
-rw-r--r-- | drivers/gpu/drm/armada/armada_gem.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/armada/armada_overlay.c | 65 | ||||
-rw-r--r-- | drivers/gpu/drm/armada/armada_trace.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/armada/armada_trace.h | 66 |
10 files changed, 325 insertions, 192 deletions
diff --git a/drivers/gpu/drm/armada/Makefile b/drivers/gpu/drm/armada/Makefile index ffd673615772..a18f156c8b66 100644 --- a/drivers/gpu/drm/armada/Makefile +++ b/drivers/gpu/drm/armada/Makefile | |||
@@ -1,5 +1,5 @@ | |||
1 | armada-y := armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \ | 1 | armada-y := armada_crtc.o armada_drv.o armada_fb.o armada_fbdev.o \ |
2 | armada_gem.o armada_overlay.o | 2 | armada_gem.o armada_overlay.o armada_trace.o |
3 | armada-y += armada_510.o | 3 | armada-y += armada_510.o |
4 | armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o | 4 | armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o |
5 | 5 | ||
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index a51f8cbcfe26..95cb3966b2ca 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include "armada_fb.h" | 18 | #include "armada_fb.h" |
19 | #include "armada_gem.h" | 19 | #include "armada_gem.h" |
20 | #include "armada_hw.h" | 20 | #include "armada_hw.h" |
21 | #include "armada_trace.h" | ||
21 | 22 | ||
22 | struct armada_frame_work { | 23 | struct armada_frame_work { |
23 | struct armada_plane_work work; | 24 | struct armada_plane_work work; |
@@ -164,19 +165,37 @@ static void armada_drm_crtc_update(struct armada_crtc *dcrtc) | |||
164 | } | 165 | } |
165 | } | 166 | } |
166 | 167 | ||
168 | void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb, | ||
169 | int x, int y) | ||
170 | { | ||
171 | u32 addr = drm_fb_obj(fb)->dev_addr; | ||
172 | u32 pixel_format = fb->pixel_format; | ||
173 | int num_planes = drm_format_num_planes(pixel_format); | ||
174 | int i; | ||
175 | |||
176 | if (num_planes > 3) | ||
177 | num_planes = 3; | ||
178 | |||
179 | for (i = 0; i < num_planes; i++) | ||
180 | addrs[i] = addr + fb->offsets[i] + y * fb->pitches[i] + | ||
181 | x * drm_format_plane_cpp(pixel_format, i); | ||
182 | for (; i < 3; i++) | ||
183 | addrs[i] = 0; | ||
184 | } | ||
185 | |||
167 | static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb, | 186 | static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb, |
168 | int x, int y, struct armada_regs *regs, bool interlaced) | 187 | int x, int y, struct armada_regs *regs, bool interlaced) |
169 | { | 188 | { |
170 | struct armada_gem_object *obj = drm_fb_obj(fb); | ||
171 | unsigned pitch = fb->pitches[0]; | 189 | unsigned pitch = fb->pitches[0]; |
172 | unsigned offset = y * pitch + x * fb->bits_per_pixel / 8; | 190 | u32 addrs[3], addr_odd, addr_even; |
173 | uint32_t addr_odd, addr_even; | ||
174 | unsigned i = 0; | 191 | unsigned i = 0; |
175 | 192 | ||
176 | DRM_DEBUG_DRIVER("pitch %u x %d y %d bpp %d\n", | 193 | DRM_DEBUG_DRIVER("pitch %u x %d y %d bpp %d\n", |
177 | pitch, x, y, fb->bits_per_pixel); | 194 | pitch, x, y, fb->bits_per_pixel); |
178 | 195 | ||
179 | addr_odd = addr_even = obj->dev_addr + offset; | 196 | armada_drm_plane_calc_addrs(addrs, fb, x, y); |
197 | |||
198 | addr_odd = addr_even = addrs[0]; | ||
180 | 199 | ||
181 | if (interlaced) { | 200 | if (interlaced) { |
182 | addr_even += pitch; | 201 | addr_even += pitch; |
@@ -192,17 +211,18 @@ static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb, | |||
192 | } | 211 | } |
193 | 212 | ||
194 | static void armada_drm_plane_work_run(struct armada_crtc *dcrtc, | 213 | static void armada_drm_plane_work_run(struct armada_crtc *dcrtc, |
195 | struct armada_plane *plane) | 214 | struct drm_plane *plane) |
196 | { | 215 | { |
197 | struct armada_plane_work *work = xchg(&plane->work, NULL); | 216 | struct armada_plane *dplane = drm_to_armada_plane(plane); |
217 | struct armada_plane_work *work = xchg(&dplane->work, NULL); | ||
198 | 218 | ||
199 | /* Handle any pending frame work. */ | 219 | /* Handle any pending frame work. */ |
200 | if (work) { | 220 | if (work) { |
201 | work->fn(dcrtc, plane, work); | 221 | work->fn(dcrtc, dplane, work); |
202 | drm_crtc_vblank_put(&dcrtc->crtc); | 222 | drm_crtc_vblank_put(&dcrtc->crtc); |
203 | } | 223 | } |
204 | 224 | ||
205 | wake_up(&plane->frame_wait); | 225 | wake_up(&dplane->frame_wait); |
206 | } | 226 | } |
207 | 227 | ||
208 | int armada_drm_plane_work_queue(struct armada_crtc *dcrtc, | 228 | int armada_drm_plane_work_queue(struct armada_crtc *dcrtc, |
@@ -307,14 +327,12 @@ static void armada_drm_crtc_finish_fb(struct armada_crtc *dcrtc, | |||
307 | 327 | ||
308 | static void armada_drm_vblank_off(struct armada_crtc *dcrtc) | 328 | static void armada_drm_vblank_off(struct armada_crtc *dcrtc) |
309 | { | 329 | { |
310 | struct armada_plane *plane = drm_to_armada_plane(dcrtc->crtc.primary); | ||
311 | |||
312 | /* | 330 | /* |
313 | * Tell the DRM core that vblank IRQs aren't going to happen for | 331 | * Tell the DRM core that vblank IRQs aren't going to happen for |
314 | * a while. This cleans up any pending vblank events for us. | 332 | * a while. This cleans up any pending vblank events for us. |
315 | */ | 333 | */ |
316 | drm_crtc_vblank_off(&dcrtc->crtc); | 334 | drm_crtc_vblank_off(&dcrtc->crtc); |
317 | armada_drm_plane_work_run(dcrtc, plane); | 335 | armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary); |
318 | } | 336 | } |
319 | 337 | ||
320 | void armada_drm_crtc_gamma_set(struct drm_crtc *crtc, u16 r, u16 g, u16 b, | 338 | void armada_drm_crtc_gamma_set(struct drm_crtc *crtc, u16 r, u16 g, u16 b, |
@@ -416,10 +434,8 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat) | |||
416 | 434 | ||
417 | spin_lock(&dcrtc->irq_lock); | 435 | spin_lock(&dcrtc->irq_lock); |
418 | ovl_plane = dcrtc->plane; | 436 | ovl_plane = dcrtc->plane; |
419 | if (ovl_plane) { | 437 | if (ovl_plane) |
420 | struct armada_plane *plane = drm_to_armada_plane(ovl_plane); | 438 | armada_drm_plane_work_run(dcrtc, ovl_plane); |
421 | armada_drm_plane_work_run(dcrtc, plane); | ||
422 | } | ||
423 | 439 | ||
424 | if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) { | 440 | if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) { |
425 | int i = stat & GRA_FRAME_IRQ0 ? 0 : 1; | 441 | int i = stat & GRA_FRAME_IRQ0 ? 0 : 1; |
@@ -449,10 +465,8 @@ static void armada_drm_crtc_irq(struct armada_crtc *dcrtc, u32 stat) | |||
449 | 465 | ||
450 | spin_unlock(&dcrtc->irq_lock); | 466 | spin_unlock(&dcrtc->irq_lock); |
451 | 467 | ||
452 | if (stat & GRA_FRAME_IRQ) { | 468 | if (stat & GRA_FRAME_IRQ) |
453 | struct armada_plane *plane = drm_to_armada_plane(dcrtc->crtc.primary); | 469 | armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary); |
454 | armada_drm_plane_work_run(dcrtc, plane); | ||
455 | } | ||
456 | } | 470 | } |
457 | 471 | ||
458 | static irqreturn_t armada_drm_irq(int irq, void *arg) | 472 | static irqreturn_t armada_drm_irq(int irq, void *arg) |
@@ -466,6 +480,8 @@ static irqreturn_t armada_drm_irq(int irq, void *arg) | |||
466 | */ | 480 | */ |
467 | writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR); | 481 | writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR); |
468 | 482 | ||
483 | trace_armada_drm_irq(&dcrtc->crtc, stat); | ||
484 | |||
469 | /* Mask out those interrupts we haven't enabled */ | 485 | /* Mask out those interrupts we haven't enabled */ |
470 | v = stat & dcrtc->irq_ena; | 486 | v = stat & dcrtc->irq_ena; |
471 | 487 | ||
@@ -531,6 +547,35 @@ static uint32_t armada_drm_crtc_calculate_csc(struct armada_crtc *dcrtc) | |||
531 | return val; | 547 | return val; |
532 | } | 548 | } |
533 | 549 | ||
550 | static void armada_drm_primary_set(struct drm_crtc *crtc, | ||
551 | struct drm_plane *plane, int x, int y) | ||
552 | { | ||
553 | struct armada_plane_state *state = &drm_to_armada_plane(plane)->state; | ||
554 | struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); | ||
555 | struct armada_regs regs[8]; | ||
556 | bool interlaced = dcrtc->interlaced; | ||
557 | unsigned i; | ||
558 | u32 ctrl0; | ||
559 | |||
560 | i = armada_drm_crtc_calc_fb(plane->fb, x, y, regs, interlaced); | ||
561 | |||
562 | armada_reg_queue_set(regs, i, state->dst_yx, LCD_SPU_GRA_OVSA_HPXL_VLN); | ||
563 | armada_reg_queue_set(regs, i, state->src_hw, LCD_SPU_GRA_HPXL_VLN); | ||
564 | armada_reg_queue_set(regs, i, state->dst_hw, LCD_SPU_GZM_HPXL_VLN); | ||
565 | |||
566 | ctrl0 = state->ctrl0; | ||
567 | if (interlaced) | ||
568 | ctrl0 |= CFG_GRA_FTOGGLE; | ||
569 | |||
570 | armada_reg_queue_mod(regs, i, ctrl0, CFG_GRAFORMAT | | ||
571 | CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV | | ||
572 | CFG_SWAPYU | CFG_YUV2RGB) | | ||
573 | CFG_PALETTE_ENA | CFG_GRA_FTOGGLE, | ||
574 | LCD_SPU_DMA_CTRL0); | ||
575 | armada_reg_queue_end(regs, i); | ||
576 | armada_drm_crtc_update_regs(dcrtc, regs); | ||
577 | } | ||
578 | |||
534 | /* The mode_config.mutex will be held for this call */ | 579 | /* The mode_config.mutex will be held for this call */ |
535 | static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, | 580 | static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, |
536 | struct drm_display_mode *mode, struct drm_display_mode *adj, | 581 | struct drm_display_mode *mode, struct drm_display_mode *adj, |
@@ -547,9 +592,20 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, | |||
547 | 592 | ||
548 | interlaced = !!(adj->flags & DRM_MODE_FLAG_INTERLACE); | 593 | interlaced = !!(adj->flags & DRM_MODE_FLAG_INTERLACE); |
549 | 594 | ||
550 | i = armada_drm_crtc_calc_fb(dcrtc->crtc.primary->fb, | 595 | val = CFG_GRA_ENA | CFG_GRA_HSMOOTH; |
551 | x, y, regs, interlaced); | 596 | val |= CFG_GRA_FMT(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt); |
597 | val |= CFG_GRA_MOD(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->mod); | ||
598 | |||
599 | if (drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt > CFG_420) | ||
600 | val |= CFG_PALETTE_ENA; | ||
601 | |||
602 | drm_to_armada_plane(crtc->primary)->state.ctrl0 = val; | ||
603 | drm_to_armada_plane(crtc->primary)->state.src_hw = | ||
604 | drm_to_armada_plane(crtc->primary)->state.dst_hw = | ||
605 | adj->crtc_vdisplay << 16 | adj->crtc_hdisplay; | ||
606 | drm_to_armada_plane(crtc->primary)->state.dst_yx = 0; | ||
552 | 607 | ||
608 | i = 0; | ||
553 | rm = adj->crtc_hsync_start - adj->crtc_hdisplay; | 609 | rm = adj->crtc_hsync_start - adj->crtc_hdisplay; |
554 | lm = adj->crtc_htotal - adj->crtc_hsync_end; | 610 | lm = adj->crtc_htotal - adj->crtc_hsync_end; |
555 | bm = adj->crtc_vsync_start - adj->crtc_vdisplay; | 611 | bm = adj->crtc_vsync_start - adj->crtc_vdisplay; |
@@ -625,8 +681,6 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, | |||
625 | val = adj->crtc_vdisplay << 16 | adj->crtc_hdisplay; | 681 | val = adj->crtc_vdisplay << 16 | adj->crtc_hdisplay; |
626 | 682 | ||
627 | armada_reg_queue_set(regs, i, val, LCD_SPU_V_H_ACTIVE); | 683 | armada_reg_queue_set(regs, i, val, LCD_SPU_V_H_ACTIVE); |
628 | armada_reg_queue_set(regs, i, val, LCD_SPU_GRA_HPXL_VLN); | ||
629 | armada_reg_queue_set(regs, i, val, LCD_SPU_GZM_HPXL_VLN); | ||
630 | armada_reg_queue_set(regs, i, (lm << 16) | rm, LCD_SPU_H_PORCH); | 684 | armada_reg_queue_set(regs, i, (lm << 16) | rm, LCD_SPU_H_PORCH); |
631 | armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_porch, LCD_SPU_V_PORCH); | 685 | armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_porch, LCD_SPU_V_PORCH); |
632 | armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_h_total, | 686 | armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_h_total, |
@@ -638,22 +692,6 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, | |||
638 | ADV_VSYNCOFFEN, LCD_SPU_ADV_REG); | 692 | ADV_VSYNCOFFEN, LCD_SPU_ADV_REG); |
639 | } | 693 | } |
640 | 694 | ||
641 | val = CFG_GRA_ENA | CFG_GRA_HSMOOTH; | ||
642 | val |= CFG_GRA_FMT(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt); | ||
643 | val |= CFG_GRA_MOD(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->mod); | ||
644 | |||
645 | if (drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt > CFG_420) | ||
646 | val |= CFG_PALETTE_ENA; | ||
647 | |||
648 | if (interlaced) | ||
649 | val |= CFG_GRA_FTOGGLE; | ||
650 | |||
651 | armada_reg_queue_mod(regs, i, val, CFG_GRAFORMAT | | ||
652 | CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV | | ||
653 | CFG_SWAPYU | CFG_YUV2RGB) | | ||
654 | CFG_PALETTE_ENA | CFG_GRA_FTOGGLE, | ||
655 | LCD_SPU_DMA_CTRL0); | ||
656 | |||
657 | val = adj->flags & DRM_MODE_FLAG_NVSYNC ? CFG_VSYNC_INV : 0; | 695 | val = adj->flags & DRM_MODE_FLAG_NVSYNC ? CFG_VSYNC_INV : 0; |
658 | armada_reg_queue_mod(regs, i, val, CFG_VSYNC_INV, LCD_SPU_DMA_CTRL1); | 696 | armada_reg_queue_mod(regs, i, val, CFG_VSYNC_INV, LCD_SPU_DMA_CTRL1); |
659 | 697 | ||
@@ -662,6 +700,8 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, | |||
662 | armada_reg_queue_end(regs, i); | 700 | armada_reg_queue_end(regs, i); |
663 | 701 | ||
664 | armada_drm_crtc_update_regs(dcrtc, regs); | 702 | armada_drm_crtc_update_regs(dcrtc, regs); |
703 | |||
704 | armada_drm_primary_set(crtc, crtc->primary, x, y); | ||
665 | spin_unlock_irqrestore(&dcrtc->irq_lock, flags); | 705 | spin_unlock_irqrestore(&dcrtc->irq_lock, flags); |
666 | 706 | ||
667 | armada_drm_crtc_update(dcrtc); | 707 | armada_drm_crtc_update(dcrtc); |
@@ -1038,7 +1078,7 @@ static int armada_drm_crtc_page_flip(struct drm_crtc *crtc, | |||
1038 | * interrupt, so complete it now. | 1078 | * interrupt, so complete it now. |
1039 | */ | 1079 | */ |
1040 | if (dpms_blanked(dcrtc->dpms)) | 1080 | if (dpms_blanked(dcrtc->dpms)) |
1041 | armada_drm_plane_work_run(dcrtc, drm_to_armada_plane(dcrtc->crtc.primary)); | 1081 | armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary); |
1042 | 1082 | ||
1043 | return 0; | 1083 | return 0; |
1044 | } | 1084 | } |
@@ -1172,7 +1212,6 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, | |||
1172 | CFG_PDWN32x32 | CFG_PDWN16x66 | CFG_PDWN32x66 | | 1212 | CFG_PDWN32x32 | CFG_PDWN16x66 | CFG_PDWN32x66 | |
1173 | CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1); | 1213 | CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1); |
1174 | writel_relaxed(0x2032ff81, dcrtc->base + LCD_SPU_DMA_CTRL1); | 1214 | writel_relaxed(0x2032ff81, dcrtc->base + LCD_SPU_DMA_CTRL1); |
1175 | writel_relaxed(0x00000000, dcrtc->base + LCD_SPU_GRA_OVSA_HPXL_VLN); | ||
1176 | writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA); | 1215 | writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA); |
1177 | writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR); | 1216 | writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR); |
1178 | 1217 | ||
diff --git a/drivers/gpu/drm/armada/armada_crtc.h b/drivers/gpu/drm/armada/armada_crtc.h index 04fdd22d483b..b08043e8cc3b 100644 --- a/drivers/gpu/drm/armada/armada_crtc.h +++ b/drivers/gpu/drm/armada/armada_crtc.h | |||
@@ -41,10 +41,18 @@ struct armada_plane_work { | |||
41 | struct armada_plane_work *); | 41 | struct armada_plane_work *); |
42 | }; | 42 | }; |
43 | 43 | ||
44 | struct armada_plane_state { | ||
45 | u32 src_hw; | ||
46 | u32 dst_hw; | ||
47 | u32 dst_yx; | ||
48 | u32 ctrl0; | ||
49 | }; | ||
50 | |||
44 | struct armada_plane { | 51 | struct armada_plane { |
45 | struct drm_plane base; | 52 | struct drm_plane base; |
46 | wait_queue_head_t frame_wait; | 53 | wait_queue_head_t frame_wait; |
47 | struct armada_plane_work *work; | 54 | struct armada_plane_work *work; |
55 | struct armada_plane_state state; | ||
48 | }; | 56 | }; |
49 | #define drm_to_armada_plane(p) container_of(p, struct armada_plane, base) | 57 | #define drm_to_armada_plane(p) container_of(p, struct armada_plane, base) |
50 | 58 | ||
@@ -54,6 +62,8 @@ int armada_drm_plane_work_queue(struct armada_crtc *dcrtc, | |||
54 | int armada_drm_plane_work_wait(struct armada_plane *plane, long timeout); | 62 | int armada_drm_plane_work_wait(struct armada_plane *plane, long timeout); |
55 | struct armada_plane_work *armada_drm_plane_work_cancel( | 63 | struct armada_plane_work *armada_drm_plane_work_cancel( |
56 | struct armada_crtc *dcrtc, struct armada_plane *plane); | 64 | struct armada_crtc *dcrtc, struct armada_plane *plane); |
65 | void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb, | ||
66 | int x, int y); | ||
57 | 67 | ||
58 | struct armada_crtc { | 68 | struct armada_crtc { |
59 | struct drm_crtc crtc; | 69 | struct drm_crtc crtc; |
diff --git a/drivers/gpu/drm/armada/armada_debugfs.c b/drivers/gpu/drm/armada/armada_debugfs.c index d4f7ab0a30d4..90222e60d2d6 100644 --- a/drivers/gpu/drm/armada/armada_debugfs.c +++ b/drivers/gpu/drm/armada/armada_debugfs.c | |||
@@ -113,7 +113,7 @@ static int drm_add_fake_info_node(struct drm_minor *minor, struct dentry *ent, | |||
113 | struct drm_info_node *node; | 113 | struct drm_info_node *node; |
114 | 114 | ||
115 | node = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL); | 115 | node = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL); |
116 | if (node == NULL) { | 116 | if (!node) { |
117 | debugfs_remove(ent); | 117 | debugfs_remove(ent); |
118 | return -ENOMEM; | 118 | return -ENOMEM; |
119 | } | 119 | } |
diff --git a/drivers/gpu/drm/armada/armada_drm.h b/drivers/gpu/drm/armada/armada_drm.h index 3b2bb6128d40..77952d559a3c 100644 --- a/drivers/gpu/drm/armada/armada_drm.h +++ b/drivers/gpu/drm/armada/armada_drm.h | |||
@@ -53,6 +53,7 @@ struct armada_variant { | |||
53 | extern const struct armada_variant armada510_ops; | 53 | extern const struct armada_variant armada510_ops; |
54 | 54 | ||
55 | struct armada_private { | 55 | struct armada_private { |
56 | struct drm_device drm; | ||
56 | struct work_struct fb_unref_work; | 57 | struct work_struct fb_unref_work; |
57 | DECLARE_KFIFO(fb_unref, struct drm_framebuffer *, 8); | 58 | DECLARE_KFIFO(fb_unref, struct drm_framebuffer *, 8); |
58 | struct drm_fb_helper *fbdev; | 59 | struct drm_fb_helper *fbdev; |
diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c index 94e46da9a758..07086b427c22 100644 --- a/drivers/gpu/drm/armada/armada_drv.c +++ b/drivers/gpu/drm/armada/armada_drv.c | |||
@@ -49,106 +49,6 @@ void armada_drm_queue_unref_work(struct drm_device *dev, | |||
49 | spin_unlock_irqrestore(&dev->event_lock, flags); | 49 | spin_unlock_irqrestore(&dev->event_lock, flags); |
50 | } | 50 | } |
51 | 51 | ||
52 | static int armada_drm_load(struct drm_device *dev, unsigned long flags) | ||
53 | { | ||
54 | struct armada_private *priv; | ||
55 | struct resource *mem = NULL; | ||
56 | int ret, n; | ||
57 | |||
58 | for (n = 0; ; n++) { | ||
59 | struct resource *r = platform_get_resource(dev->platformdev, | ||
60 | IORESOURCE_MEM, n); | ||
61 | if (!r) | ||
62 | break; | ||
63 | |||
64 | /* Resources above 64K are graphics memory */ | ||
65 | if (resource_size(r) > SZ_64K) | ||
66 | mem = r; | ||
67 | else | ||
68 | return -EINVAL; | ||
69 | } | ||
70 | |||
71 | if (!mem) | ||
72 | return -ENXIO; | ||
73 | |||
74 | if (!devm_request_mem_region(dev->dev, mem->start, | ||
75 | resource_size(mem), "armada-drm")) | ||
76 | return -EBUSY; | ||
77 | |||
78 | priv = devm_kzalloc(dev->dev, sizeof(*priv), GFP_KERNEL); | ||
79 | if (!priv) { | ||
80 | DRM_ERROR("failed to allocate private\n"); | ||
81 | return -ENOMEM; | ||
82 | } | ||
83 | |||
84 | platform_set_drvdata(dev->platformdev, dev); | ||
85 | dev->dev_private = priv; | ||
86 | |||
87 | INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work); | ||
88 | INIT_KFIFO(priv->fb_unref); | ||
89 | |||
90 | /* Mode setting support */ | ||
91 | drm_mode_config_init(dev); | ||
92 | dev->mode_config.min_width = 320; | ||
93 | dev->mode_config.min_height = 200; | ||
94 | |||
95 | /* | ||
96 | * With vscale enabled, the maximum width is 1920 due to the | ||
97 | * 1920 by 3 lines RAM | ||
98 | */ | ||
99 | dev->mode_config.max_width = 1920; | ||
100 | dev->mode_config.max_height = 2048; | ||
101 | |||
102 | dev->mode_config.preferred_depth = 24; | ||
103 | dev->mode_config.funcs = &armada_drm_mode_config_funcs; | ||
104 | drm_mm_init(&priv->linear, mem->start, resource_size(mem)); | ||
105 | mutex_init(&priv->linear_lock); | ||
106 | |||
107 | ret = component_bind_all(dev->dev, dev); | ||
108 | if (ret) | ||
109 | goto err_kms; | ||
110 | |||
111 | ret = drm_vblank_init(dev, dev->mode_config.num_crtc); | ||
112 | if (ret) | ||
113 | goto err_comp; | ||
114 | |||
115 | dev->irq_enabled = true; | ||
116 | |||
117 | ret = armada_fbdev_init(dev); | ||
118 | if (ret) | ||
119 | goto err_comp; | ||
120 | |||
121 | drm_kms_helper_poll_init(dev); | ||
122 | |||
123 | return 0; | ||
124 | |||
125 | err_comp: | ||
126 | component_unbind_all(dev->dev, dev); | ||
127 | err_kms: | ||
128 | drm_mode_config_cleanup(dev); | ||
129 | drm_mm_takedown(&priv->linear); | ||
130 | flush_work(&priv->fb_unref_work); | ||
131 | |||
132 | return ret; | ||
133 | } | ||
134 | |||
135 | static int armada_drm_unload(struct drm_device *dev) | ||
136 | { | ||
137 | struct armada_private *priv = dev->dev_private; | ||
138 | |||
139 | drm_kms_helper_poll_fini(dev); | ||
140 | armada_fbdev_fini(dev); | ||
141 | |||
142 | component_unbind_all(dev->dev, dev); | ||
143 | |||
144 | drm_mode_config_cleanup(dev); | ||
145 | drm_mm_takedown(&priv->linear); | ||
146 | flush_work(&priv->fb_unref_work); | ||
147 | dev->dev_private = NULL; | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | /* These are called under the vbl_lock. */ | 52 | /* These are called under the vbl_lock. */ |
153 | static int armada_drm_enable_vblank(struct drm_device *dev, unsigned int pipe) | 53 | static int armada_drm_enable_vblank(struct drm_device *dev, unsigned int pipe) |
154 | { | 54 | { |
@@ -186,16 +86,10 @@ static const struct file_operations armada_drm_fops = { | |||
186 | }; | 86 | }; |
187 | 87 | ||
188 | static struct drm_driver armada_drm_driver = { | 88 | static struct drm_driver armada_drm_driver = { |
189 | .load = armada_drm_load, | ||
190 | .lastclose = armada_drm_lastclose, | 89 | .lastclose = armada_drm_lastclose, |
191 | .unload = armada_drm_unload, | ||
192 | .get_vblank_counter = drm_vblank_no_hw_counter, | 90 | .get_vblank_counter = drm_vblank_no_hw_counter, |
193 | .enable_vblank = armada_drm_enable_vblank, | 91 | .enable_vblank = armada_drm_enable_vblank, |
194 | .disable_vblank = armada_drm_disable_vblank, | 92 | .disable_vblank = armada_drm_disable_vblank, |
195 | #ifdef CONFIG_DEBUG_FS | ||
196 | .debugfs_init = armada_drm_debugfs_init, | ||
197 | .debugfs_cleanup = armada_drm_debugfs_cleanup, | ||
198 | #endif | ||
199 | .gem_free_object_unlocked = armada_gem_free_object, | 93 | .gem_free_object_unlocked = armada_gem_free_object, |
200 | .prime_handle_to_fd = drm_gem_prime_handle_to_fd, | 94 | .prime_handle_to_fd = drm_gem_prime_handle_to_fd, |
201 | .prime_fd_to_handle = drm_gem_prime_fd_to_handle, | 95 | .prime_fd_to_handle = drm_gem_prime_fd_to_handle, |
@@ -218,12 +112,138 @@ static struct drm_driver armada_drm_driver = { | |||
218 | 112 | ||
219 | static int armada_drm_bind(struct device *dev) | 113 | static int armada_drm_bind(struct device *dev) |
220 | { | 114 | { |
221 | return drm_platform_init(&armada_drm_driver, to_platform_device(dev)); | 115 | struct armada_private *priv; |
116 | struct resource *mem = NULL; | ||
117 | int ret, n; | ||
118 | |||
119 | for (n = 0; ; n++) { | ||
120 | struct resource *r = platform_get_resource(to_platform_device(dev), | ||
121 | IORESOURCE_MEM, n); | ||
122 | if (!r) | ||
123 | break; | ||
124 | |||
125 | /* Resources above 64K are graphics memory */ | ||
126 | if (resource_size(r) > SZ_64K) | ||
127 | mem = r; | ||
128 | else | ||
129 | return -EINVAL; | ||
130 | } | ||
131 | |||
132 | if (!mem) | ||
133 | return -ENXIO; | ||
134 | |||
135 | if (!devm_request_mem_region(dev, mem->start, resource_size(mem), | ||
136 | "armada-drm")) | ||
137 | return -EBUSY; | ||
138 | |||
139 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
140 | if (!priv) | ||
141 | return -ENOMEM; | ||
142 | |||
143 | /* | ||
144 | * The drm_device structure must be at the start of | ||
145 | * armada_private for drm_dev_unref() to work correctly. | ||
146 | */ | ||
147 | BUILD_BUG_ON(offsetof(struct armada_private, drm) != 0); | ||
148 | |||
149 | ret = drm_dev_init(&priv->drm, &armada_drm_driver, dev); | ||
150 | if (ret) { | ||
151 | dev_err(dev, "[" DRM_NAME ":%s] drm_dev_init failed: %d\n", | ||
152 | __func__, ret); | ||
153 | kfree(priv); | ||
154 | return ret; | ||
155 | } | ||
156 | |||
157 | priv->drm.platformdev = to_platform_device(dev); | ||
158 | priv->drm.dev_private = priv; | ||
159 | |||
160 | platform_set_drvdata(priv->drm.platformdev, &priv->drm); | ||
161 | |||
162 | INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work); | ||
163 | INIT_KFIFO(priv->fb_unref); | ||
164 | |||
165 | /* Mode setting support */ | ||
166 | drm_mode_config_init(&priv->drm); | ||
167 | priv->drm.mode_config.min_width = 320; | ||
168 | priv->drm.mode_config.min_height = 200; | ||
169 | |||
170 | /* | ||
171 | * With vscale enabled, the maximum width is 1920 due to the | ||
172 | * 1920 by 3 lines RAM | ||
173 | */ | ||
174 | priv->drm.mode_config.max_width = 1920; | ||
175 | priv->drm.mode_config.max_height = 2048; | ||
176 | |||
177 | priv->drm.mode_config.preferred_depth = 24; | ||
178 | priv->drm.mode_config.funcs = &armada_drm_mode_config_funcs; | ||
179 | drm_mm_init(&priv->linear, mem->start, resource_size(mem)); | ||
180 | mutex_init(&priv->linear_lock); | ||
181 | |||
182 | ret = component_bind_all(dev, &priv->drm); | ||
183 | if (ret) | ||
184 | goto err_kms; | ||
185 | |||
186 | ret = drm_vblank_init(&priv->drm, priv->drm.mode_config.num_crtc); | ||
187 | if (ret) | ||
188 | goto err_comp; | ||
189 | |||
190 | priv->drm.irq_enabled = true; | ||
191 | |||
192 | ret = armada_fbdev_init(&priv->drm); | ||
193 | if (ret) | ||
194 | goto err_comp; | ||
195 | |||
196 | drm_kms_helper_poll_init(&priv->drm); | ||
197 | |||
198 | ret = drm_dev_register(&priv->drm, 0); | ||
199 | if (ret) | ||
200 | goto err_poll; | ||
201 | |||
202 | #ifdef CONFIG_DEBUG_FS | ||
203 | armada_drm_debugfs_init(priv->drm.primary); | ||
204 | #endif | ||
205 | |||
206 | DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", | ||
207 | armada_drm_driver.name, armada_drm_driver.major, | ||
208 | armada_drm_driver.minor, armada_drm_driver.patchlevel, | ||
209 | armada_drm_driver.date, dev_name(dev), | ||
210 | priv->drm.primary->index); | ||
211 | |||
212 | return 0; | ||
213 | |||
214 | err_poll: | ||
215 | drm_kms_helper_poll_fini(&priv->drm); | ||
216 | armada_fbdev_fini(&priv->drm); | ||
217 | err_comp: | ||
218 | component_unbind_all(dev, &priv->drm); | ||
219 | err_kms: | ||
220 | drm_mode_config_cleanup(&priv->drm); | ||
221 | drm_mm_takedown(&priv->linear); | ||
222 | flush_work(&priv->fb_unref_work); | ||
223 | drm_dev_unref(&priv->drm); | ||
224 | return ret; | ||
222 | } | 225 | } |
223 | 226 | ||
224 | static void armada_drm_unbind(struct device *dev) | 227 | static void armada_drm_unbind(struct device *dev) |
225 | { | 228 | { |
226 | drm_put_dev(dev_get_drvdata(dev)); | 229 | struct drm_device *drm = dev_get_drvdata(dev); |
230 | struct armada_private *priv = drm->dev_private; | ||
231 | |||
232 | drm_kms_helper_poll_fini(&priv->drm); | ||
233 | armada_fbdev_fini(&priv->drm); | ||
234 | |||
235 | #ifdef CONFIG_DEBUG_FS | ||
236 | armada_drm_debugfs_cleanup(priv->drm.primary); | ||
237 | #endif | ||
238 | drm_dev_unregister(&priv->drm); | ||
239 | |||
240 | component_unbind_all(dev, &priv->drm); | ||
241 | |||
242 | drm_mode_config_cleanup(&priv->drm); | ||
243 | drm_mm_takedown(&priv->linear); | ||
244 | flush_work(&priv->fb_unref_work); | ||
245 | |||
246 | drm_dev_unref(&priv->drm); | ||
227 | } | 247 | } |
228 | 248 | ||
229 | static int compare_of(struct device *dev, void *data) | 249 | static int compare_of(struct device *dev, void *data) |
diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index 806791897304..768087ddb046 100644 --- a/drivers/gpu/drm/armada/armada_gem.c +++ b/drivers/gpu/drm/armada/armada_gem.c | |||
@@ -212,7 +212,7 @@ armada_gem_alloc_private_object(struct drm_device *dev, size_t size) | |||
212 | return obj; | 212 | return obj; |
213 | } | 213 | } |
214 | 214 | ||
215 | struct armada_gem_object *armada_gem_alloc_object(struct drm_device *dev, | 215 | static struct armada_gem_object *armada_gem_alloc_object(struct drm_device *dev, |
216 | size_t size) | 216 | size_t size) |
217 | { | 217 | { |
218 | struct armada_gem_object *obj; | 218 | struct armada_gem_object *obj; |
@@ -419,7 +419,7 @@ int armada_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
419 | } | 419 | } |
420 | 420 | ||
421 | /* Prime support */ | 421 | /* Prime support */ |
422 | struct sg_table * | 422 | static struct sg_table * |
423 | armada_gem_prime_map_dma_buf(struct dma_buf_attachment *attach, | 423 | armada_gem_prime_map_dma_buf(struct dma_buf_attachment *attach, |
424 | enum dma_data_direction dir) | 424 | enum dma_data_direction dir) |
425 | { | 425 | { |
@@ -594,11 +594,7 @@ int armada_gem_map_import(struct armada_gem_object *dobj) | |||
594 | int ret; | 594 | int ret; |
595 | 595 | ||
596 | dobj->sgt = dma_buf_map_attachment(dobj->obj.import_attach, | 596 | dobj->sgt = dma_buf_map_attachment(dobj->obj.import_attach, |
597 | DMA_TO_DEVICE); | 597 | DMA_TO_DEVICE); |
598 | if (!dobj->sgt) { | ||
599 | DRM_ERROR("dma_buf_map_attachment() returned NULL\n"); | ||
600 | return -EINVAL; | ||
601 | } | ||
602 | if (IS_ERR(dobj->sgt)) { | 598 | if (IS_ERR(dobj->sgt)) { |
603 | ret = PTR_ERR(dobj->sgt); | 599 | ret = PTR_ERR(dobj->sgt); |
604 | dobj->sgt = NULL; | 600 | dobj->sgt = NULL; |
diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c index 152b4e716269..6743615232f5 100644 --- a/drivers/gpu/drm/armada/armada_overlay.c +++ b/drivers/gpu/drm/armada/armada_overlay.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include "armada_hw.h" | 15 | #include "armada_hw.h" |
16 | #include <drm/armada_drm.h> | 16 | #include <drm/armada_drm.h> |
17 | #include "armada_ioctlP.h" | 17 | #include "armada_ioctlP.h" |
18 | #include "armada_trace.h" | ||
18 | 19 | ||
19 | struct armada_ovl_plane_properties { | 20 | struct armada_ovl_plane_properties { |
20 | uint32_t colorkey_yr; | 21 | uint32_t colorkey_yr; |
@@ -32,10 +33,6 @@ struct armada_ovl_plane_properties { | |||
32 | struct armada_ovl_plane { | 33 | struct armada_ovl_plane { |
33 | struct armada_plane base; | 34 | struct armada_plane base; |
34 | struct drm_framebuffer *old_fb; | 35 | struct drm_framebuffer *old_fb; |
35 | uint32_t src_hw; | ||
36 | uint32_t dst_hw; | ||
37 | uint32_t dst_yx; | ||
38 | uint32_t ctrl0; | ||
39 | struct { | 36 | struct { |
40 | struct armada_plane_work work; | 37 | struct armada_plane_work work; |
41 | struct armada_regs regs[13]; | 38 | struct armada_regs regs[13]; |
@@ -87,6 +84,8 @@ static void armada_ovl_plane_work(struct armada_crtc *dcrtc, | |||
87 | { | 84 | { |
88 | struct armada_ovl_plane *dplane = container_of(plane, struct armada_ovl_plane, base); | 85 | struct armada_ovl_plane *dplane = container_of(plane, struct armada_ovl_plane, base); |
89 | 86 | ||
87 | trace_armada_ovl_plane_work(&dcrtc->crtc, &plane->base); | ||
88 | |||
90 | armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs); | 89 | armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs); |
91 | armada_ovl_retire_fb(dplane, NULL); | 90 | armada_ovl_retire_fb(dplane, NULL); |
92 | } | 91 | } |
@@ -120,6 +119,10 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
120 | bool visible; | 119 | bool visible; |
121 | int ret; | 120 | int ret; |
122 | 121 | ||
122 | trace_armada_ovl_plane_update(plane, crtc, fb, | ||
123 | crtc_x, crtc_y, crtc_w, crtc_h, | ||
124 | src_x, src_y, src_w, src_h); | ||
125 | |||
123 | ret = drm_plane_helper_check_update(plane, crtc, fb, &src, &dest, &clip, | 126 | ret = drm_plane_helper_check_update(plane, crtc, fb, &src, &dest, &clip, |
124 | DRM_ROTATE_0, | 127 | DRM_ROTATE_0, |
125 | 0, INT_MAX, true, false, &visible); | 128 | 0, INT_MAX, true, false, &visible); |
@@ -141,22 +144,22 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
141 | 144 | ||
142 | /* FIXME: overlay on an interlaced display */ | 145 | /* FIXME: overlay on an interlaced display */ |
143 | /* Just updating the position/size? */ | 146 | /* Just updating the position/size? */ |
144 | if (plane->fb == fb && dplane->ctrl0 == ctrl0) { | 147 | if (plane->fb == fb && dplane->base.state.ctrl0 == ctrl0) { |
145 | val = (drm_rect_height(&src) & 0xffff0000) | | 148 | val = (drm_rect_height(&src) & 0xffff0000) | |
146 | drm_rect_width(&src) >> 16; | 149 | drm_rect_width(&src) >> 16; |
147 | dplane->src_hw = val; | 150 | dplane->base.state.src_hw = val; |
148 | writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_HPXL_VLN); | 151 | writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_HPXL_VLN); |
149 | 152 | ||
150 | val = drm_rect_height(&dest) << 16 | drm_rect_width(&dest); | 153 | val = drm_rect_height(&dest) << 16 | drm_rect_width(&dest); |
151 | dplane->dst_hw = val; | 154 | dplane->base.state.dst_hw = val; |
152 | writel_relaxed(val, dcrtc->base + LCD_SPU_DZM_HPXL_VLN); | 155 | writel_relaxed(val, dcrtc->base + LCD_SPU_DZM_HPXL_VLN); |
153 | 156 | ||
154 | val = dest.y1 << 16 | dest.x1; | 157 | val = dest.y1 << 16 | dest.x1; |
155 | dplane->dst_yx = val; | 158 | dplane->base.state.dst_yx = val; |
156 | writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_OVSA_HPXL_VLN); | 159 | writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_OVSA_HPXL_VLN); |
157 | 160 | ||
158 | return 0; | 161 | return 0; |
159 | } else if (~dplane->ctrl0 & ctrl0 & CFG_DMA_ENA) { | 162 | } else if (~dplane->base.state.ctrl0 & ctrl0 & CFG_DMA_ENA) { |
160 | /* Power up the Y/U/V FIFOs on ENA 0->1 transitions */ | 163 | /* Power up the Y/U/V FIFOs on ENA 0->1 transitions */ |
161 | armada_updatel(0, CFG_PDWN16x66 | CFG_PDWN32x66, | 164 | armada_updatel(0, CFG_PDWN16x66 | CFG_PDWN32x66, |
162 | dcrtc->base + LCD_SPU_SRAM_PARA1); | 165 | dcrtc->base + LCD_SPU_SRAM_PARA1); |
@@ -166,9 +169,8 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
166 | armada_drm_plane_work_cancel(dcrtc, &dplane->base); | 169 | armada_drm_plane_work_cancel(dcrtc, &dplane->base); |
167 | 170 | ||
168 | if (plane->fb != fb) { | 171 | if (plane->fb != fb) { |
169 | struct armada_gem_object *obj = drm_fb_obj(fb); | 172 | u32 addrs[3], pixel_format; |
170 | uint32_t addr[3], pixel_format; | 173 | int num_planes, hsub; |
171 | int i, num_planes, hsub; | ||
172 | 174 | ||
173 | /* | 175 | /* |
174 | * Take a reference on the new framebuffer - we want to | 176 | * Take a reference on the new framebuffer - we want to |
@@ -182,6 +184,8 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
182 | src_y = src.y1 >> 16; | 184 | src_y = src.y1 >> 16; |
183 | src_x = src.x1 >> 16; | 185 | src_x = src.x1 >> 16; |
184 | 186 | ||
187 | armada_drm_plane_calc_addrs(addrs, fb, src_x, src_y); | ||
188 | |||
185 | pixel_format = fb->pixel_format; | 189 | pixel_format = fb->pixel_format; |
186 | hsub = drm_format_horz_chroma_subsampling(pixel_format); | 190 | hsub = drm_format_horz_chroma_subsampling(pixel_format); |
187 | num_planes = drm_format_num_planes(pixel_format); | 191 | num_planes = drm_format_num_planes(pixel_format); |
@@ -194,24 +198,17 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
194 | if (src_x & (hsub - 1) && num_planes == 1) | 198 | if (src_x & (hsub - 1) && num_planes == 1) |
195 | ctrl0 ^= CFG_DMA_MOD(CFG_SWAPUV); | 199 | ctrl0 ^= CFG_DMA_MOD(CFG_SWAPUV); |
196 | 200 | ||
197 | for (i = 0; i < num_planes; i++) | 201 | armada_reg_queue_set(dplane->vbl.regs, idx, addrs[0], |
198 | addr[i] = obj->dev_addr + fb->offsets[i] + | ||
199 | src_y * fb->pitches[i] + | ||
200 | src_x * drm_format_plane_cpp(pixel_format, i); | ||
201 | for (; i < ARRAY_SIZE(addr); i++) | ||
202 | addr[i] = 0; | ||
203 | |||
204 | armada_reg_queue_set(dplane->vbl.regs, idx, addr[0], | ||
205 | LCD_SPU_DMA_START_ADDR_Y0); | 202 | LCD_SPU_DMA_START_ADDR_Y0); |
206 | armada_reg_queue_set(dplane->vbl.regs, idx, addr[1], | 203 | armada_reg_queue_set(dplane->vbl.regs, idx, addrs[1], |
207 | LCD_SPU_DMA_START_ADDR_U0); | 204 | LCD_SPU_DMA_START_ADDR_U0); |
208 | armada_reg_queue_set(dplane->vbl.regs, idx, addr[2], | 205 | armada_reg_queue_set(dplane->vbl.regs, idx, addrs[2], |
209 | LCD_SPU_DMA_START_ADDR_V0); | 206 | LCD_SPU_DMA_START_ADDR_V0); |
210 | armada_reg_queue_set(dplane->vbl.regs, idx, addr[0], | 207 | armada_reg_queue_set(dplane->vbl.regs, idx, addrs[0], |
211 | LCD_SPU_DMA_START_ADDR_Y1); | 208 | LCD_SPU_DMA_START_ADDR_Y1); |
212 | armada_reg_queue_set(dplane->vbl.regs, idx, addr[1], | 209 | armada_reg_queue_set(dplane->vbl.regs, idx, addrs[1], |
213 | LCD_SPU_DMA_START_ADDR_U1); | 210 | LCD_SPU_DMA_START_ADDR_U1); |
214 | armada_reg_queue_set(dplane->vbl.regs, idx, addr[2], | 211 | armada_reg_queue_set(dplane->vbl.regs, idx, addrs[2], |
215 | LCD_SPU_DMA_START_ADDR_V1); | 212 | LCD_SPU_DMA_START_ADDR_V1); |
216 | 213 | ||
217 | val = fb->pitches[0] << 16 | fb->pitches[0]; | 214 | val = fb->pitches[0] << 16 | fb->pitches[0]; |
@@ -223,28 +220,28 @@ armada_ovl_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, | |||
223 | } | 220 | } |
224 | 221 | ||
225 | val = (drm_rect_height(&src) & 0xffff0000) | drm_rect_width(&src) >> 16; | 222 | val = (drm_rect_height(&src) & 0xffff0000) | drm_rect_width(&src) >> 16; |
226 | if (dplane->src_hw != val) { | 223 | if (dplane->base.state.src_hw != val) { |
227 | dplane->src_hw = val; | 224 | dplane->base.state.src_hw = val; |
228 | armada_reg_queue_set(dplane->vbl.regs, idx, val, | 225 | armada_reg_queue_set(dplane->vbl.regs, idx, val, |
229 | LCD_SPU_DMA_HPXL_VLN); | 226 | LCD_SPU_DMA_HPXL_VLN); |
230 | } | 227 | } |
231 | 228 | ||
232 | val = drm_rect_height(&dest) << 16 | drm_rect_width(&dest); | 229 | val = drm_rect_height(&dest) << 16 | drm_rect_width(&dest); |
233 | if (dplane->dst_hw != val) { | 230 | if (dplane->base.state.dst_hw != val) { |
234 | dplane->dst_hw = val; | 231 | dplane->base.state.dst_hw = val; |
235 | armada_reg_queue_set(dplane->vbl.regs, idx, val, | 232 | armada_reg_queue_set(dplane->vbl.regs, idx, val, |
236 | LCD_SPU_DZM_HPXL_VLN); | 233 | LCD_SPU_DZM_HPXL_VLN); |
237 | } | 234 | } |
238 | 235 | ||
239 | val = dest.y1 << 16 | dest.x1; | 236 | val = dest.y1 << 16 | dest.x1; |
240 | if (dplane->dst_yx != val) { | 237 | if (dplane->base.state.dst_yx != val) { |
241 | dplane->dst_yx = val; | 238 | dplane->base.state.dst_yx = val; |
242 | armada_reg_queue_set(dplane->vbl.regs, idx, val, | 239 | armada_reg_queue_set(dplane->vbl.regs, idx, val, |
243 | LCD_SPU_DMA_OVSA_HPXL_VLN); | 240 | LCD_SPU_DMA_OVSA_HPXL_VLN); |
244 | } | 241 | } |
245 | 242 | ||
246 | if (dplane->ctrl0 != ctrl0) { | 243 | if (dplane->base.state.ctrl0 != ctrl0) { |
247 | dplane->ctrl0 = ctrl0; | 244 | dplane->base.state.ctrl0 = ctrl0; |
248 | armada_reg_queue_mod(dplane->vbl.regs, idx, ctrl0, | 245 | armada_reg_queue_mod(dplane->vbl.regs, idx, ctrl0, |
249 | CFG_CBSH_ENA | CFG_DMAFORMAT | CFG_DMA_FTOGGLE | | 246 | CFG_CBSH_ENA | CFG_DMAFORMAT | CFG_DMA_FTOGGLE | |
250 | CFG_DMA_HSMOOTH | CFG_DMA_TSTMODE | | 247 | CFG_DMA_HSMOOTH | CFG_DMA_TSTMODE | |
@@ -275,7 +272,7 @@ static int armada_ovl_plane_disable(struct drm_plane *plane) | |||
275 | armada_drm_crtc_plane_disable(dcrtc, plane); | 272 | armada_drm_crtc_plane_disable(dcrtc, plane); |
276 | 273 | ||
277 | dcrtc->plane = NULL; | 274 | dcrtc->plane = NULL; |
278 | dplane->ctrl0 = 0; | 275 | dplane->base.state.ctrl0 = 0; |
279 | 276 | ||
280 | fb = xchg(&dplane->old_fb, NULL); | 277 | fb = xchg(&dplane->old_fb, NULL); |
281 | if (fb) | 278 | if (fb) |
diff --git a/drivers/gpu/drm/armada/armada_trace.c b/drivers/gpu/drm/armada/armada_trace.c new file mode 100644 index 000000000000..068b336ba75f --- /dev/null +++ b/drivers/gpu/drm/armada/armada_trace.c | |||
@@ -0,0 +1,4 @@ | |||
1 | #ifndef __CHECKER__ | ||
2 | #define CREATE_TRACE_POINTS | ||
3 | #include "armada_trace.h" | ||
4 | #endif | ||
diff --git a/drivers/gpu/drm/armada/armada_trace.h b/drivers/gpu/drm/armada/armada_trace.h new file mode 100644 index 000000000000..dc0cba70fd1a --- /dev/null +++ b/drivers/gpu/drm/armada/armada_trace.h | |||
@@ -0,0 +1,66 @@ | |||
1 | #if !defined(ARMADA_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) | ||
2 | #define ARMADA_TRACE_H | ||
3 | |||
4 | #include <linux/tracepoint.h> | ||
5 | #include <drm/drmP.h> | ||
6 | |||
7 | #undef TRACE_SYSTEM | ||
8 | #define TRACE_SYSTEM armada | ||
9 | #define TRACE_INCLUDE_FILE armada_trace | ||
10 | |||
11 | TRACE_EVENT(armada_drm_irq, | ||
12 | TP_PROTO(struct drm_crtc *crtc, u32 stat), | ||
13 | TP_ARGS(crtc, stat), | ||
14 | TP_STRUCT__entry( | ||
15 | __field(struct drm_crtc *, crtc) | ||
16 | __field(u32, stat) | ||
17 | ), | ||
18 | TP_fast_assign( | ||
19 | __entry->crtc = crtc; | ||
20 | __entry->stat = stat; | ||
21 | ), | ||
22 | TP_printk("crtc %p stat 0x%08x", | ||
23 | __entry->crtc, __entry->stat) | ||
24 | ); | ||
25 | |||
26 | TRACE_EVENT(armada_ovl_plane_update, | ||
27 | TP_PROTO(struct drm_plane *plane, struct drm_crtc *crtc, | ||
28 | struct drm_framebuffer *fb, | ||
29 | int crtc_x, int crtc_y, unsigned crtc_w, unsigned crtc_h, | ||
30 | uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h), | ||
31 | TP_ARGS(plane, crtc, fb, crtc_x, crtc_y, crtc_w, crtc_h, src_x, src_y, src_w, src_h), | ||
32 | TP_STRUCT__entry( | ||
33 | __field(struct drm_plane *, plane) | ||
34 | __field(struct drm_crtc *, crtc) | ||
35 | __field(struct drm_framebuffer *, fb) | ||
36 | ), | ||
37 | TP_fast_assign( | ||
38 | __entry->plane = plane; | ||
39 | __entry->crtc = crtc; | ||
40 | __entry->fb = fb; | ||
41 | ), | ||
42 | TP_printk("plane %p crtc %p fb %p", | ||
43 | __entry->plane, __entry->crtc, __entry->fb) | ||
44 | ); | ||
45 | |||
46 | TRACE_EVENT(armada_ovl_plane_work, | ||
47 | TP_PROTO(struct drm_crtc *crtc, struct drm_plane *plane), | ||
48 | TP_ARGS(crtc, plane), | ||
49 | TP_STRUCT__entry( | ||
50 | __field(struct drm_plane *, plane) | ||
51 | __field(struct drm_crtc *, crtc) | ||
52 | ), | ||
53 | TP_fast_assign( | ||
54 | __entry->plane = plane; | ||
55 | __entry->crtc = crtc; | ||
56 | ), | ||
57 | TP_printk("plane %p crtc %p", | ||
58 | __entry->plane, __entry->crtc) | ||
59 | ); | ||
60 | |||
61 | #endif | ||
62 | |||
63 | /* This part must be outside protection */ | ||
64 | #undef TRACE_INCLUDE_PATH | ||
65 | #define TRACE_INCLUDE_PATH . | ||
66 | #include <trace/define_trace.h> | ||