Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+325 -192
+1 -1
drivers/gpu/drm/armada/Makefile
··· 1 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 3 armada-y += armada_510.o 4 4 armada-$(CONFIG_DEBUG_FS) += armada_debugfs.o 5 5
+80 -41
drivers/gpu/drm/armada/armada_crtc.c
··· 18 18 #include "armada_fb.h" 19 19 #include "armada_gem.h" 20 20 #include "armada_hw.h" 21 + #include "armada_trace.h" 21 22 22 23 struct armada_frame_work { 23 24 struct armada_plane_work work; ··· 165 164 } 166 165 } 167 166 167 + void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb, 168 + int x, int y) 169 + { 170 + u32 addr = drm_fb_obj(fb)->dev_addr; 171 + u32 pixel_format = fb->pixel_format; 172 + int num_planes = drm_format_num_planes(pixel_format); 173 + int i; 174 + 175 + if (num_planes > 3) 176 + num_planes = 3; 177 + 178 + for (i = 0; i < num_planes; i++) 179 + addrs[i] = addr + fb->offsets[i] + y * fb->pitches[i] + 180 + x * drm_format_plane_cpp(pixel_format, i); 181 + for (; i < 3; i++) 182 + addrs[i] = 0; 183 + } 184 + 168 185 static unsigned armada_drm_crtc_calc_fb(struct drm_framebuffer *fb, 169 186 int x, int y, struct armada_regs *regs, bool interlaced) 170 187 { 171 - struct armada_gem_object *obj = drm_fb_obj(fb); 172 188 unsigned pitch = fb->pitches[0]; 173 - unsigned offset = y * pitch + x * fb->bits_per_pixel / 8; 174 - uint32_t addr_odd, addr_even; 189 + u32 addrs[3], addr_odd, addr_even; 175 190 unsigned i = 0; 176 191 177 192 DRM_DEBUG_DRIVER("pitch %u x %d y %d bpp %d\n", 178 193 pitch, x, y, fb->bits_per_pixel); 179 194 180 - addr_odd = addr_even = obj->dev_addr + offset; 195 + armada_drm_plane_calc_addrs(addrs, fb, x, y); 196 + 197 + addr_odd = addr_even = addrs[0]; 181 198 182 199 if (interlaced) { 183 200 addr_even += pitch; ··· 211 192 } 212 193 213 194 static void armada_drm_plane_work_run(struct armada_crtc *dcrtc, 214 - struct armada_plane *plane) 195 + struct drm_plane *plane) 215 196 { 216 - struct armada_plane_work *work = xchg(&plane->work, NULL); 197 + struct armada_plane *dplane = drm_to_armada_plane(plane); 198 + struct armada_plane_work *work = xchg(&dplane->work, NULL); 217 199 218 200 /* Handle any pending frame work. */ 219 201 if (work) { 220 - work->fn(dcrtc, plane, work); 202 + work->fn(dcrtc, dplane, work); 221 203 drm_crtc_vblank_put(&dcrtc->crtc); 222 204 } 223 205 224 - wake_up(&plane->frame_wait); 206 + wake_up(&dplane->frame_wait); 225 207 } 226 208 227 209 int armada_drm_plane_work_queue(struct armada_crtc *dcrtc, ··· 327 307 328 308 static void armada_drm_vblank_off(struct armada_crtc *dcrtc) 329 309 { 330 - struct armada_plane *plane = drm_to_armada_plane(dcrtc->crtc.primary); 331 - 332 310 /* 333 311 * Tell the DRM core that vblank IRQs aren't going to happen for 334 312 * a while. This cleans up any pending vblank events for us. 335 313 */ 336 314 drm_crtc_vblank_off(&dcrtc->crtc); 337 - armada_drm_plane_work_run(dcrtc, plane); 315 + armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary); 338 316 } 339 317 340 318 void armada_drm_crtc_gamma_set(struct drm_crtc *crtc, u16 r, u16 g, u16 b, ··· 434 416 435 417 spin_lock(&dcrtc->irq_lock); 436 418 ovl_plane = dcrtc->plane; 437 - if (ovl_plane) { 438 - struct armada_plane *plane = drm_to_armada_plane(ovl_plane); 439 - armada_drm_plane_work_run(dcrtc, plane); 440 - } 419 + if (ovl_plane) 420 + armada_drm_plane_work_run(dcrtc, ovl_plane); 441 421 442 422 if (stat & GRA_FRAME_IRQ && dcrtc->interlaced) { 443 423 int i = stat & GRA_FRAME_IRQ0 ? 0 : 1; ··· 465 449 466 450 spin_unlock(&dcrtc->irq_lock); 467 451 468 - if (stat & GRA_FRAME_IRQ) { 469 - struct armada_plane *plane = drm_to_armada_plane(dcrtc->crtc.primary); 470 - armada_drm_plane_work_run(dcrtc, plane); 471 - } 452 + if (stat & GRA_FRAME_IRQ) 453 + armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary); 472 454 } 473 455 474 456 static irqreturn_t armada_drm_irq(int irq, void *arg) ··· 479 465 * have to set the actual status register value. This is racy. 480 466 */ 481 467 writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR); 468 + 469 + trace_armada_drm_irq(&dcrtc->crtc, stat); 482 470 483 471 /* Mask out those interrupts we haven't enabled */ 484 472 v = stat & dcrtc->irq_ena; ··· 547 531 return val; 548 532 } 549 533 534 + static void armada_drm_primary_set(struct drm_crtc *crtc, 535 + struct drm_plane *plane, int x, int y) 536 + { 537 + struct armada_plane_state *state = &drm_to_armada_plane(plane)->state; 538 + struct armada_crtc *dcrtc = drm_to_armada_crtc(crtc); 539 + struct armada_regs regs[8]; 540 + bool interlaced = dcrtc->interlaced; 541 + unsigned i; 542 + u32 ctrl0; 543 + 544 + i = armada_drm_crtc_calc_fb(plane->fb, x, y, regs, interlaced); 545 + 546 + armada_reg_queue_set(regs, i, state->dst_yx, LCD_SPU_GRA_OVSA_HPXL_VLN); 547 + armada_reg_queue_set(regs, i, state->src_hw, LCD_SPU_GRA_HPXL_VLN); 548 + armada_reg_queue_set(regs, i, state->dst_hw, LCD_SPU_GZM_HPXL_VLN); 549 + 550 + ctrl0 = state->ctrl0; 551 + if (interlaced) 552 + ctrl0 |= CFG_GRA_FTOGGLE; 553 + 554 + armada_reg_queue_mod(regs, i, ctrl0, CFG_GRAFORMAT | 555 + CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV | 556 + CFG_SWAPYU | CFG_YUV2RGB) | 557 + CFG_PALETTE_ENA | CFG_GRA_FTOGGLE, 558 + LCD_SPU_DMA_CTRL0); 559 + armada_reg_queue_end(regs, i); 560 + armada_drm_crtc_update_regs(dcrtc, regs); 561 + } 562 + 550 563 /* The mode_config.mutex will be held for this call */ 551 564 static int armada_drm_crtc_mode_set(struct drm_crtc *crtc, 552 565 struct drm_display_mode *mode, struct drm_display_mode *adj, ··· 592 547 593 548 interlaced = !!(adj->flags & DRM_MODE_FLAG_INTERLACE); 594 549 595 - i = armada_drm_crtc_calc_fb(dcrtc->crtc.primary->fb, 596 - x, y, regs, interlaced); 550 + val = CFG_GRA_ENA | CFG_GRA_HSMOOTH; 551 + val |= CFG_GRA_FMT(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt); 552 + val |= CFG_GRA_MOD(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->mod); 597 553 554 + if (drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt > CFG_420) 555 + val |= CFG_PALETTE_ENA; 556 + 557 + drm_to_armada_plane(crtc->primary)->state.ctrl0 = val; 558 + drm_to_armada_plane(crtc->primary)->state.src_hw = 559 + drm_to_armada_plane(crtc->primary)->state.dst_hw = 560 + adj->crtc_vdisplay << 16 | adj->crtc_hdisplay; 561 + drm_to_armada_plane(crtc->primary)->state.dst_yx = 0; 562 + 563 + i = 0; 598 564 rm = adj->crtc_hsync_start - adj->crtc_hdisplay; 599 565 lm = adj->crtc_htotal - adj->crtc_hsync_end; 600 566 bm = adj->crtc_vsync_start - adj->crtc_vdisplay; ··· 681 625 val = adj->crtc_vdisplay << 16 | adj->crtc_hdisplay; 682 626 683 627 armada_reg_queue_set(regs, i, val, LCD_SPU_V_H_ACTIVE); 684 - armada_reg_queue_set(regs, i, val, LCD_SPU_GRA_HPXL_VLN); 685 - armada_reg_queue_set(regs, i, val, LCD_SPU_GZM_HPXL_VLN); 686 628 armada_reg_queue_set(regs, i, (lm << 16) | rm, LCD_SPU_H_PORCH); 687 629 armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_porch, LCD_SPU_V_PORCH); 688 630 armada_reg_queue_set(regs, i, dcrtc->v[0].spu_v_h_total, ··· 692 638 ADV_VSYNCOFFEN, LCD_SPU_ADV_REG); 693 639 } 694 640 695 - val = CFG_GRA_ENA | CFG_GRA_HSMOOTH; 696 - val |= CFG_GRA_FMT(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt); 697 - val |= CFG_GRA_MOD(drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->mod); 698 - 699 - if (drm_fb_to_armada_fb(dcrtc->crtc.primary->fb)->fmt > CFG_420) 700 - val |= CFG_PALETTE_ENA; 701 - 702 - if (interlaced) 703 - val |= CFG_GRA_FTOGGLE; 704 - 705 - armada_reg_queue_mod(regs, i, val, CFG_GRAFORMAT | 706 - CFG_GRA_MOD(CFG_SWAPRB | CFG_SWAPUV | 707 - CFG_SWAPYU | CFG_YUV2RGB) | 708 - CFG_PALETTE_ENA | CFG_GRA_FTOGGLE, 709 - LCD_SPU_DMA_CTRL0); 710 - 711 641 val = adj->flags & DRM_MODE_FLAG_NVSYNC ? CFG_VSYNC_INV : 0; 712 642 armada_reg_queue_mod(regs, i, val, CFG_VSYNC_INV, LCD_SPU_DMA_CTRL1); 713 643 ··· 700 662 armada_reg_queue_end(regs, i); 701 663 702 664 armada_drm_crtc_update_regs(dcrtc, regs); 665 + 666 + armada_drm_primary_set(crtc, crtc->primary, x, y); 703 667 spin_unlock_irqrestore(&dcrtc->irq_lock, flags); 704 668 705 669 armada_drm_crtc_update(dcrtc); ··· 1078 1038 * interrupt, so complete it now. 1079 1039 */ 1080 1040 if (dpms_blanked(dcrtc->dpms)) 1081 - armada_drm_plane_work_run(dcrtc, drm_to_armada_plane(dcrtc->crtc.primary)); 1041 + armada_drm_plane_work_run(dcrtc, dcrtc->crtc.primary); 1082 1042 1083 1043 return 0; 1084 1044 } ··· 1212 1172 CFG_PDWN32x32 | CFG_PDWN16x66 | CFG_PDWN32x66 | 1213 1173 CFG_PDWN64x66, dcrtc->base + LCD_SPU_SRAM_PARA1); 1214 1174 writel_relaxed(0x2032ff81, dcrtc->base + LCD_SPU_DMA_CTRL1); 1215 - writel_relaxed(0x00000000, dcrtc->base + LCD_SPU_GRA_OVSA_HPXL_VLN); 1216 1175 writel_relaxed(dcrtc->irq_ena, dcrtc->base + LCD_SPU_IRQ_ENA); 1217 1176 writel_relaxed(0, dcrtc->base + LCD_SPU_IRQ_ISR); 1218 1177
+10
drivers/gpu/drm/armada/armada_crtc.h
··· 41 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 51 struct armada_plane { 45 52 struct drm_plane base; 46 53 wait_queue_head_t frame_wait; 47 54 struct armada_plane_work *work; 55 + struct armada_plane_state state; 48 56 }; 49 57 #define drm_to_armada_plane(p) container_of(p, struct armada_plane, base) 50 58 ··· 62 54 int armada_drm_plane_work_wait(struct armada_plane *plane, long timeout); 63 55 struct armada_plane_work *armada_drm_plane_work_cancel( 64 56 struct armada_crtc *dcrtc, struct armada_plane *plane); 57 + void armada_drm_plane_calc_addrs(u32 *addrs, struct drm_framebuffer *fb, 58 + int x, int y); 65 59 66 60 struct armada_crtc { 67 61 struct drm_crtc crtc;
+1 -1
drivers/gpu/drm/armada/armada_debugfs.c
··· 113 113 struct drm_info_node *node; 114 114 115 115 node = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL); 116 - if (node == NULL) { 116 + if (!node) { 117 117 debugfs_remove(ent); 118 118 return -ENOMEM; 119 119 }
+1
drivers/gpu/drm/armada/armada_drm.h
··· 53 53 extern const struct armada_variant armada510_ops; 54 54 55 55 struct armada_private { 56 + struct drm_device drm; 56 57 struct work_struct fb_unref_work; 57 58 DECLARE_KFIFO(fb_unref, struct drm_framebuffer *, 8); 58 59 struct drm_fb_helper *fbdev;
+128 -108
drivers/gpu/drm/armada/armada_drv.c
··· 49 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 52 /* These are called under the vbl_lock. */ 153 53 static int armada_drm_enable_vblank(struct drm_device *dev, unsigned int pipe) 154 54 { ··· 86 186 }; 87 187 88 188 static struct drm_driver armada_drm_driver = { 89 - .load = armada_drm_load, 90 189 .lastclose = armada_drm_lastclose, 91 - .unload = armada_drm_unload, 92 190 .get_vblank_counter = drm_vblank_no_hw_counter, 93 191 .enable_vblank = armada_drm_enable_vblank, 94 192 .disable_vblank = armada_drm_disable_vblank, 95 - #ifdef CONFIG_DEBUG_FS 96 - .debugfs_init = armada_drm_debugfs_init, 97 - .debugfs_cleanup = armada_drm_debugfs_cleanup, 98 - #endif 99 193 .gem_free_object_unlocked = armada_gem_free_object, 100 194 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 101 195 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, ··· 112 218 113 219 static int armada_drm_bind(struct device *dev) 114 220 { 115 - return drm_platform_init(&armada_drm_driver, to_platform_device(dev)); 221 + struct armada_private *priv; 222 + struct resource *mem = NULL; 223 + int ret, n; 224 + 225 + for (n = 0; ; n++) { 226 + struct resource *r = platform_get_resource(to_platform_device(dev), 227 + IORESOURCE_MEM, n); 228 + if (!r) 229 + break; 230 + 231 + /* Resources above 64K are graphics memory */ 232 + if (resource_size(r) > SZ_64K) 233 + mem = r; 234 + else 235 + return -EINVAL; 236 + } 237 + 238 + if (!mem) 239 + return -ENXIO; 240 + 241 + if (!devm_request_mem_region(dev, mem->start, resource_size(mem), 242 + "armada-drm")) 243 + return -EBUSY; 244 + 245 + priv = kzalloc(sizeof(*priv), GFP_KERNEL); 246 + if (!priv) 247 + return -ENOMEM; 248 + 249 + /* 250 + * The drm_device structure must be at the start of 251 + * armada_private for drm_dev_unref() to work correctly. 252 + */ 253 + BUILD_BUG_ON(offsetof(struct armada_private, drm) != 0); 254 + 255 + ret = drm_dev_init(&priv->drm, &armada_drm_driver, dev); 256 + if (ret) { 257 + dev_err(dev, "[" DRM_NAME ":%s] drm_dev_init failed: %d\n", 258 + __func__, ret); 259 + kfree(priv); 260 + return ret; 261 + } 262 + 263 + priv->drm.platformdev = to_platform_device(dev); 264 + priv->drm.dev_private = priv; 265 + 266 + platform_set_drvdata(priv->drm.platformdev, &priv->drm); 267 + 268 + INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work); 269 + INIT_KFIFO(priv->fb_unref); 270 + 271 + /* Mode setting support */ 272 + drm_mode_config_init(&priv->drm); 273 + priv->drm.mode_config.min_width = 320; 274 + priv->drm.mode_config.min_height = 200; 275 + 276 + /* 277 + * With vscale enabled, the maximum width is 1920 due to the 278 + * 1920 by 3 lines RAM 279 + */ 280 + priv->drm.mode_config.max_width = 1920; 281 + priv->drm.mode_config.max_height = 2048; 282 + 283 + priv->drm.mode_config.preferred_depth = 24; 284 + priv->drm.mode_config.funcs = &armada_drm_mode_config_funcs; 285 + drm_mm_init(&priv->linear, mem->start, resource_size(mem)); 286 + mutex_init(&priv->linear_lock); 287 + 288 + ret = component_bind_all(dev, &priv->drm); 289 + if (ret) 290 + goto err_kms; 291 + 292 + ret = drm_vblank_init(&priv->drm, priv->drm.mode_config.num_crtc); 293 + if (ret) 294 + goto err_comp; 295 + 296 + priv->drm.irq_enabled = true; 297 + 298 + ret = armada_fbdev_init(&priv->drm); 299 + if (ret) 300 + goto err_comp; 301 + 302 + drm_kms_helper_poll_init(&priv->drm); 303 + 304 + ret = drm_dev_register(&priv->drm, 0); 305 + if (ret) 306 + goto err_poll; 307 + 308 + #ifdef CONFIG_DEBUG_FS 309 + armada_drm_debugfs_init(priv->drm.primary); 310 + #endif 311 + 312 + DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", 313 + armada_drm_driver.name, armada_drm_driver.major, 314 + armada_drm_driver.minor, armada_drm_driver.patchlevel, 315 + armada_drm_driver.date, dev_name(dev), 316 + priv->drm.primary->index); 317 + 318 + return 0; 319 + 320 + err_poll: 321 + drm_kms_helper_poll_fini(&priv->drm); 322 + armada_fbdev_fini(&priv->drm); 323 + err_comp: 324 + component_unbind_all(dev, &priv->drm); 325 + err_kms: 326 + drm_mode_config_cleanup(&priv->drm); 327 + drm_mm_takedown(&priv->linear); 328 + flush_work(&priv->fb_unref_work); 329 + drm_dev_unref(&priv->drm); 330 + return ret; 116 331 } 117 332 118 333 static void armada_drm_unbind(struct device *dev) 119 334 { 120 - drm_put_dev(dev_get_drvdata(dev)); 335 + struct drm_device *drm = dev_get_drvdata(dev); 336 + struct armada_private *priv = drm->dev_private; 337 + 338 + drm_kms_helper_poll_fini(&priv->drm); 339 + armada_fbdev_fini(&priv->drm); 340 + 341 + #ifdef CONFIG_DEBUG_FS 342 + armada_drm_debugfs_cleanup(priv->drm.primary); 343 + #endif 344 + drm_dev_unregister(&priv->drm); 345 + 346 + component_unbind_all(dev, &priv->drm); 347 + 348 + drm_mode_config_cleanup(&priv->drm); 349 + drm_mm_takedown(&priv->linear); 350 + flush_work(&priv->fb_unref_work); 351 + 352 + drm_dev_unref(&priv->drm); 121 353 } 122 354 123 355 static int compare_of(struct device *dev, void *data)
+3 -7
drivers/gpu/drm/armada/armada_gem.c
··· 212 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 216 size_t size) 217 217 { 218 218 struct armada_gem_object *obj; ··· 419 419 } 420 420 421 421 /* Prime support */ 422 - struct sg_table * 422 + static struct sg_table * 423 423 armada_gem_prime_map_dma_buf(struct dma_buf_attachment *attach, 424 424 enum dma_data_direction dir) 425 425 { ··· 594 594 int ret; 595 595 596 596 dobj->sgt = dma_buf_map_attachment(dobj->obj.import_attach, 597 - DMA_TO_DEVICE); 598 - if (!dobj->sgt) { 599 - DRM_ERROR("dma_buf_map_attachment() returned NULL\n"); 600 - return -EINVAL; 601 - } 597 + DMA_TO_DEVICE); 602 598 if (IS_ERR(dobj->sgt)) { 603 599 ret = PTR_ERR(dobj->sgt); 604 600 dobj->sgt = NULL;
+31 -34
drivers/gpu/drm/armada/armada_overlay.c
··· 15 15 #include "armada_hw.h" 16 16 #include <drm/armada_drm.h> 17 17 #include "armada_ioctlP.h" 18 + #include "armada_trace.h" 18 19 19 20 struct armada_ovl_plane_properties { 20 21 uint32_t colorkey_yr; ··· 33 32 struct armada_ovl_plane { 34 33 struct armada_plane base; 35 34 struct drm_framebuffer *old_fb; 36 - uint32_t src_hw; 37 - uint32_t dst_hw; 38 - uint32_t dst_yx; 39 - uint32_t ctrl0; 40 35 struct { 41 36 struct armada_plane_work work; 42 37 struct armada_regs regs[13]; ··· 84 87 { 85 88 struct armada_ovl_plane *dplane = container_of(plane, struct armada_ovl_plane, base); 86 89 90 + trace_armada_ovl_plane_work(&dcrtc->crtc, &plane->base); 91 + 87 92 armada_drm_crtc_update_regs(dcrtc, dplane->vbl.regs); 88 93 armada_ovl_retire_fb(dplane, NULL); 89 94 } ··· 119 120 bool visible; 120 121 int ret; 121 122 123 + trace_armada_ovl_plane_update(plane, crtc, fb, 124 + crtc_x, crtc_y, crtc_w, crtc_h, 125 + src_x, src_y, src_w, src_h); 126 + 122 127 ret = drm_plane_helper_check_update(plane, crtc, fb, &src, &dest, &clip, 123 128 DRM_ROTATE_0, 124 129 0, INT_MAX, true, false, &visible); ··· 144 141 145 142 /* FIXME: overlay on an interlaced display */ 146 143 /* Just updating the position/size? */ 147 - if (plane->fb == fb && dplane->ctrl0 == ctrl0) { 144 + if (plane->fb == fb && dplane->base.state.ctrl0 == ctrl0) { 148 145 val = (drm_rect_height(&src) & 0xffff0000) | 149 146 drm_rect_width(&src) >> 16; 150 - dplane->src_hw = val; 147 + dplane->base.state.src_hw = val; 151 148 writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_HPXL_VLN); 152 149 153 150 val = drm_rect_height(&dest) << 16 | drm_rect_width(&dest); 154 - dplane->dst_hw = val; 151 + dplane->base.state.dst_hw = val; 155 152 writel_relaxed(val, dcrtc->base + LCD_SPU_DZM_HPXL_VLN); 156 153 157 154 val = dest.y1 << 16 | dest.x1; 158 - dplane->dst_yx = val; 155 + dplane->base.state.dst_yx = val; 159 156 writel_relaxed(val, dcrtc->base + LCD_SPU_DMA_OVSA_HPXL_VLN); 160 157 161 158 return 0; 162 - } else if (~dplane->ctrl0 & ctrl0 & CFG_DMA_ENA) { 159 + } else if (~dplane->base.state.ctrl0 & ctrl0 & CFG_DMA_ENA) { 163 160 /* Power up the Y/U/V FIFOs on ENA 0->1 transitions */ 164 161 armada_updatel(0, CFG_PDWN16x66 | CFG_PDWN32x66, 165 162 dcrtc->base + LCD_SPU_SRAM_PARA1); ··· 169 166 armada_drm_plane_work_cancel(dcrtc, &dplane->base); 170 167 171 168 if (plane->fb != fb) { 172 - struct armada_gem_object *obj = drm_fb_obj(fb); 173 - uint32_t addr[3], pixel_format; 174 - int i, num_planes, hsub; 169 + u32 addrs[3], pixel_format; 170 + int num_planes, hsub; 175 171 176 172 /* 177 173 * Take a reference on the new framebuffer - we want to ··· 184 182 src_y = src.y1 >> 16; 185 183 src_x = src.x1 >> 16; 186 184 185 + armada_drm_plane_calc_addrs(addrs, fb, src_x, src_y); 186 + 187 187 pixel_format = fb->pixel_format; 188 188 hsub = drm_format_horz_chroma_subsampling(pixel_format); 189 189 num_planes = drm_format_num_planes(pixel_format); ··· 198 194 if (src_x & (hsub - 1) && num_planes == 1) 199 195 ctrl0 ^= CFG_DMA_MOD(CFG_SWAPUV); 200 196 201 - for (i = 0; i < num_planes; i++) 202 - addr[i] = obj->dev_addr + fb->offsets[i] + 203 - src_y * fb->pitches[i] + 204 - src_x * drm_format_plane_cpp(pixel_format, i); 205 - for (; i < ARRAY_SIZE(addr); i++) 206 - addr[i] = 0; 207 - 208 - armada_reg_queue_set(dplane->vbl.regs, idx, addr[0], 197 + armada_reg_queue_set(dplane->vbl.regs, idx, addrs[0], 209 198 LCD_SPU_DMA_START_ADDR_Y0); 210 - armada_reg_queue_set(dplane->vbl.regs, idx, addr[1], 199 + armada_reg_queue_set(dplane->vbl.regs, idx, addrs[1], 211 200 LCD_SPU_DMA_START_ADDR_U0); 212 - armada_reg_queue_set(dplane->vbl.regs, idx, addr[2], 201 + armada_reg_queue_set(dplane->vbl.regs, idx, addrs[2], 213 202 LCD_SPU_DMA_START_ADDR_V0); 214 - armada_reg_queue_set(dplane->vbl.regs, idx, addr[0], 203 + armada_reg_queue_set(dplane->vbl.regs, idx, addrs[0], 215 204 LCD_SPU_DMA_START_ADDR_Y1); 216 - armada_reg_queue_set(dplane->vbl.regs, idx, addr[1], 205 + armada_reg_queue_set(dplane->vbl.regs, idx, addrs[1], 217 206 LCD_SPU_DMA_START_ADDR_U1); 218 - armada_reg_queue_set(dplane->vbl.regs, idx, addr[2], 207 + armada_reg_queue_set(dplane->vbl.regs, idx, addrs[2], 219 208 LCD_SPU_DMA_START_ADDR_V1); 220 209 221 210 val = fb->pitches[0] << 16 | fb->pitches[0]; ··· 220 223 } 221 224 222 225 val = (drm_rect_height(&src) & 0xffff0000) | drm_rect_width(&src) >> 16; 223 - if (dplane->src_hw != val) { 224 - dplane->src_hw = val; 226 + if (dplane->base.state.src_hw != val) { 227 + dplane->base.state.src_hw = val; 225 228 armada_reg_queue_set(dplane->vbl.regs, idx, val, 226 229 LCD_SPU_DMA_HPXL_VLN); 227 230 } 228 231 229 232 val = drm_rect_height(&dest) << 16 | drm_rect_width(&dest); 230 - if (dplane->dst_hw != val) { 231 - dplane->dst_hw = val; 233 + if (dplane->base.state.dst_hw != val) { 234 + dplane->base.state.dst_hw = val; 232 235 armada_reg_queue_set(dplane->vbl.regs, idx, val, 233 236 LCD_SPU_DZM_HPXL_VLN); 234 237 } 235 238 236 239 val = dest.y1 << 16 | dest.x1; 237 - if (dplane->dst_yx != val) { 238 - dplane->dst_yx = val; 240 + if (dplane->base.state.dst_yx != val) { 241 + dplane->base.state.dst_yx = val; 239 242 armada_reg_queue_set(dplane->vbl.regs, idx, val, 240 243 LCD_SPU_DMA_OVSA_HPXL_VLN); 241 244 } 242 245 243 - if (dplane->ctrl0 != ctrl0) { 244 - dplane->ctrl0 = ctrl0; 246 + if (dplane->base.state.ctrl0 != ctrl0) { 247 + dplane->base.state.ctrl0 = ctrl0; 245 248 armada_reg_queue_mod(dplane->vbl.regs, idx, ctrl0, 246 249 CFG_CBSH_ENA | CFG_DMAFORMAT | CFG_DMA_FTOGGLE | 247 250 CFG_DMA_HSMOOTH | CFG_DMA_TSTMODE | ··· 272 275 armada_drm_crtc_plane_disable(dcrtc, plane); 273 276 274 277 dcrtc->plane = NULL; 275 - dplane->ctrl0 = 0; 278 + dplane->base.state.ctrl0 = 0; 276 279 277 280 fb = xchg(&dplane->old_fb, NULL); 278 281 if (fb)
+4
drivers/gpu/drm/armada/armada_trace.c
··· 1 + #ifndef __CHECKER__ 2 + #define CREATE_TRACE_POINTS 3 + #include "armada_trace.h" 4 + #endif
+66
drivers/gpu/drm/armada/armada_trace.h
··· 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>