Lines Matching +full:sharkl3 +full:- +full:dpu

1 // SPDX-License-Identifier: GPL-2.0
8 #include <linux/dma-buf.h>
131 static int dpu_wait_stop_done(struct sprd_dpu *dpu) in dpu_wait_stop_done() argument
133 struct dpu_context *ctx = &dpu->ctx; in dpu_wait_stop_done()
136 if (ctx->stopped) in dpu_wait_stop_done()
139 rc = wait_event_interruptible_timeout(ctx->wait_queue, ctx->evt_stop, in dpu_wait_stop_done()
141 ctx->evt_stop = false; in dpu_wait_stop_done()
143 ctx->stopped = true; in dpu_wait_stop_done()
146 drm_err(dpu->drm, "dpu wait for stop done time out!\n"); in dpu_wait_stop_done()
147 return -ETIMEDOUT; in dpu_wait_stop_done()
153 static int dpu_wait_update_done(struct sprd_dpu *dpu) in dpu_wait_update_done() argument
155 struct dpu_context *ctx = &dpu->ctx; in dpu_wait_update_done()
158 ctx->evt_update = false; in dpu_wait_update_done()
160 rc = wait_event_interruptible_timeout(ctx->wait_queue, ctx->evt_update, in dpu_wait_update_done()
164 drm_err(dpu->drm, "dpu wait for reg update done time out!\n"); in dpu_wait_update_done()
165 return -ETIMEDOUT; in dpu_wait_update_done()
175 switch (fb->format->format) { in drm_format_to_dpu()
177 /* BGRA8888 -> ARGB8888 */ in drm_format_to_dpu()
183 /* RGBA8888 -> ABGR8888 */ in drm_format_to_dpu()
208 /* 2-Lane: Yuv420 */ in drm_format_to_dpu()
216 /* 2-Lane: Yuv420 */ in drm_format_to_dpu()
224 /* 2-Lane: Yuv422 */ in drm_format_to_dpu()
232 /* 2-Lane: Yuv422 */ in drm_format_to_dpu()
264 switch (state->rotation) { in drm_rotation_to_dpu()
299 switch (state->pixel_blend_mode) { in drm_blend_to_dpu()
301 /* alpha mode select - combo alpha */ in drm_blend_to_dpu()
307 /* alpha mode select - combo alpha */ in drm_blend_to_dpu()
309 /* Pre-mult mode */ in drm_blend_to_dpu()
315 /* alpha mode select - layer alpha */ in drm_blend_to_dpu()
323 static void sprd_dpu_layer(struct sprd_dpu *dpu, struct drm_plane_state *state) in sprd_dpu_layer() argument
325 struct dpu_context *ctx = &dpu->ctx; in sprd_dpu_layer()
327 struct drm_framebuffer *fb = state->fb; in sprd_dpu_layer()
329 u32 src_x = state->src_x >> 16; in sprd_dpu_layer()
330 u32 src_y = state->src_y >> 16; in sprd_dpu_layer()
331 u32 src_w = state->src_w >> 16; in sprd_dpu_layer()
332 u32 src_h = state->src_h >> 16; in sprd_dpu_layer()
333 u32 dst_x = state->crtc_x; in sprd_dpu_layer()
334 u32 dst_y = state->crtc_y; in sprd_dpu_layer()
335 u32 alpha = state->alpha; in sprd_dpu_layer()
336 u32 index = state->zpos; in sprd_dpu_layer()
342 for (i = 0; i < fb->format->num_planes; i++) { in sprd_dpu_layer()
344 addr = dma_obj->dma_addr + fb->offsets[i]; in sprd_dpu_layer()
354 if (fb->format->num_planes == 3) { in sprd_dpu_layer()
356 pitch = (fb->pitches[0] / fb->format->cpp[0]) | in sprd_dpu_layer()
357 (fb->pitches[0] / fb->format->cpp[0] << 15); in sprd_dpu_layer()
359 pitch = fb->pitches[0] / fb->format->cpp[0]; in sprd_dpu_layer()
380 static void sprd_dpu_flip(struct sprd_dpu *dpu) in sprd_dpu_flip() argument
382 struct dpu_context *ctx = &dpu->ctx; in sprd_dpu_flip()
385 * Make sure the dpu is in stop status. DPU has no shadow in sprd_dpu_flip()
389 if (ctx->if_type == SPRD_DPU_IF_EDPI) in sprd_dpu_flip()
390 dpu_wait_stop_done(dpu); in sprd_dpu_flip()
393 if (ctx->if_type == SPRD_DPU_IF_DPI) { in sprd_dpu_flip()
394 if (!ctx->stopped) { in sprd_dpu_flip()
396 dpu_wait_update_done(dpu); in sprd_dpu_flip()
400 } else if (ctx->if_type == SPRD_DPU_IF_EDPI) { in sprd_dpu_flip()
403 ctx->stopped = false; in sprd_dpu_flip()
407 static void sprd_dpu_init(struct sprd_dpu *dpu) in sprd_dpu_init() argument
409 struct dpu_context *ctx = &dpu->ctx; in sprd_dpu_init()
412 writel(0x00, ctx->base + REG_BG_COLOR); in sprd_dpu_init()
413 writel(0x00, ctx->base + REG_MMU_EN); in sprd_dpu_init()
414 writel(0x00, ctx->base + REG_MMU_PPN1); in sprd_dpu_init()
415 writel(0xffff, ctx->base + REG_MMU_RANGE1); in sprd_dpu_init()
416 writel(0x00, ctx->base + REG_MMU_PPN2); in sprd_dpu_init()
417 writel(0xffff, ctx->base + REG_MMU_RANGE2); in sprd_dpu_init()
418 writel(0x1ffff, ctx->base + REG_MMU_VPN_RANGE); in sprd_dpu_init()
420 if (ctx->if_type == SPRD_DPU_IF_DPI) { in sprd_dpu_init()
428 /* enable dpu update done INT */ in sprd_dpu_init()
430 /* enable dpu done INT */ in sprd_dpu_init()
432 /* enable dpu dpi vsync */ in sprd_dpu_init()
434 /* enable dpu TE INT */ in sprd_dpu_init()
438 } else if (ctx->if_type == SPRD_DPU_IF_EDPI) { in sprd_dpu_init()
452 writel(int_mask, ctx->base + REG_DPU_INT_EN); in sprd_dpu_init()
455 static void sprd_dpu_fini(struct sprd_dpu *dpu) in sprd_dpu_fini() argument
457 struct dpu_context *ctx = &dpu->ctx; in sprd_dpu_fini()
459 writel(0x00, ctx->base + REG_DPU_INT_EN); in sprd_dpu_fini()
460 writel(0xff, ctx->base + REG_DPU_INT_CLR); in sprd_dpu_fini()
463 static void sprd_dpi_init(struct sprd_dpu *dpu) in sprd_dpi_init() argument
465 struct dpu_context *ctx = &dpu->ctx; in sprd_dpi_init()
469 size = (ctx->vm.vactive << 16) | ctx->vm.hactive; in sprd_dpi_init()
470 writel(size, ctx->base + REG_PANEL_SIZE); in sprd_dpi_init()
471 writel(size, ctx->base + REG_BLEND_SIZE); in sprd_dpi_init()
473 if (ctx->if_type == SPRD_DPU_IF_DPI) { in sprd_dpi_init()
475 reg_val = ctx->vm.hsync_len << 0 | in sprd_dpi_init()
476 ctx->vm.hback_porch << 8 | in sprd_dpi_init()
477 ctx->vm.hfront_porch << 20; in sprd_dpi_init()
478 writel(reg_val, ctx->base + REG_DPI_H_TIMING); in sprd_dpi_init()
480 reg_val = ctx->vm.vsync_len << 0 | in sprd_dpi_init()
481 ctx->vm.vback_porch << 8 | in sprd_dpi_init()
482 ctx->vm.vfront_porch << 20; in sprd_dpi_init()
483 writel(reg_val, ctx->base + REG_DPI_V_TIMING); in sprd_dpi_init()
487 void sprd_dpu_run(struct sprd_dpu *dpu) in sprd_dpu_run() argument
489 struct dpu_context *ctx = &dpu->ctx; in sprd_dpu_run()
493 ctx->stopped = false; in sprd_dpu_run()
496 void sprd_dpu_stop(struct sprd_dpu *dpu) in sprd_dpu_stop() argument
498 struct dpu_context *ctx = &dpu->ctx; in sprd_dpu_stop()
500 if (ctx->if_type == SPRD_DPU_IF_DPI) in sprd_dpu_stop()
503 dpu_wait_stop_done(dpu); in sprd_dpu_stop()
514 if (!plane_state->fb || !plane_state->crtc) in sprd_plane_atomic_check()
517 fmt = drm_format_to_dpu(plane_state->fb); in sprd_plane_atomic_check()
519 return -EINVAL; in sprd_plane_atomic_check()
521 crtc_state = drm_atomic_get_crtc_state(plane_state->state, plane_state->crtc); in sprd_plane_atomic_check()
536 struct sprd_dpu *dpu = to_sprd_crtc(new_state->crtc); in sprd_plane_atomic_update() local
538 /* start configure dpu layers */ in sprd_plane_atomic_update()
539 sprd_dpu_layer(dpu, new_state); in sprd_plane_atomic_update()
547 struct sprd_dpu *dpu = to_sprd_crtc(old_state->crtc); in sprd_plane_atomic_disable() local
549 layer_reg_wr(&dpu->ctx, REG_LAY_CTRL, 0x00, old_state->zpos); in sprd_plane_atomic_disable()
559 drm_plane_create_rotation_property(&plane->base, in sprd_plane_create_properties()
565 drm_plane_create_alpha_property(&plane->base); in sprd_plane_create_properties()
568 drm_plane_create_blend_mode_property(&plane->base, supported_modes); in sprd_plane_create_properties()
571 drm_plane_create_zpos_immutable_property(&plane->base, index); in sprd_plane_create_properties()
608 drm_plane_helper_add(&plane->base, &sprd_plane_helper_funcs); in sprd_planes_init()
621 struct sprd_dpu *dpu = to_sprd_crtc(crtc); in sprd_crtc_mode_set_nofb() local
622 struct drm_display_mode *mode = &crtc->state->adjusted_mode; in sprd_crtc_mode_set_nofb()
626 drm_display_mode_to_videomode(mode, &dpu->ctx.vm); in sprd_crtc_mode_set_nofb()
628 drm_for_each_encoder_mask(encoder, crtc->dev, in sprd_crtc_mode_set_nofb()
629 crtc->state->encoder_mask) { in sprd_crtc_mode_set_nofb()
632 if (dsi->slave->mode_flags & MIPI_DSI_MODE_VIDEO) in sprd_crtc_mode_set_nofb()
633 dpu->ctx.if_type = SPRD_DPU_IF_DPI; in sprd_crtc_mode_set_nofb()
635 dpu->ctx.if_type = SPRD_DPU_IF_EDPI; in sprd_crtc_mode_set_nofb()
638 sprd_dpi_init(dpu); in sprd_crtc_mode_set_nofb()
644 struct sprd_dpu *dpu = to_sprd_crtc(crtc); in sprd_crtc_atomic_enable() local
646 sprd_dpu_init(dpu); in sprd_crtc_atomic_enable()
648 drm_crtc_vblank_on(&dpu->base); in sprd_crtc_atomic_enable()
654 struct sprd_dpu *dpu = to_sprd_crtc(crtc); in sprd_crtc_atomic_disable() local
655 struct drm_device *drm = dpu->base.dev; in sprd_crtc_atomic_disable()
657 drm_crtc_vblank_off(&dpu->base); in sprd_crtc_atomic_disable()
659 sprd_dpu_fini(dpu); in sprd_crtc_atomic_disable()
661 spin_lock_irq(&drm->event_lock); in sprd_crtc_atomic_disable()
662 if (crtc->state->event) { in sprd_crtc_atomic_disable()
663 drm_crtc_send_vblank_event(crtc, crtc->state->event); in sprd_crtc_atomic_disable()
664 crtc->state->event = NULL; in sprd_crtc_atomic_disable()
666 spin_unlock_irq(&drm->event_lock); in sprd_crtc_atomic_disable()
673 struct sprd_dpu *dpu = to_sprd_crtc(crtc); in sprd_crtc_atomic_flush() local
674 struct drm_device *drm = dpu->base.dev; in sprd_crtc_atomic_flush()
676 sprd_dpu_flip(dpu); in sprd_crtc_atomic_flush()
678 spin_lock_irq(&drm->event_lock); in sprd_crtc_atomic_flush()
679 if (crtc->state->event) { in sprd_crtc_atomic_flush()
680 drm_crtc_send_vblank_event(crtc, crtc->state->event); in sprd_crtc_atomic_flush()
681 crtc->state->event = NULL; in sprd_crtc_atomic_flush()
683 spin_unlock_irq(&drm->event_lock); in sprd_crtc_atomic_flush()
688 struct sprd_dpu *dpu = to_sprd_crtc(crtc); in sprd_crtc_enable_vblank() local
690 dpu_reg_set(&dpu->ctx, REG_DPU_INT_EN, BIT_DPU_INT_VSYNC); in sprd_crtc_enable_vblank()
697 struct sprd_dpu *dpu = to_sprd_crtc(crtc); in sprd_crtc_disable_vblank() local
699 dpu_reg_clr(&dpu->ctx, REG_DPU_INT_EN, BIT_DPU_INT_VSYNC); in sprd_crtc_disable_vblank()
724 struct sprd_dpu *dpu; in sprd_crtc_init() local
726 dpu = drmm_crtc_alloc_with_planes(drm, struct sprd_dpu, base, in sprd_crtc_init()
729 if (IS_ERR(dpu)) { in sprd_crtc_init()
731 return dpu; in sprd_crtc_init()
733 drm_crtc_helper_add(&dpu->base, &sprd_crtc_helper_funcs); in sprd_crtc_init()
738 port = of_graph_get_port_by_id(dev->of_node, 0); in sprd_crtc_init()
741 dev->of_node->full_name); in sprd_crtc_init()
742 return ERR_PTR(-EINVAL); in sprd_crtc_init()
744 dpu->base.port = port; in sprd_crtc_init()
747 return dpu; in sprd_crtc_init()
752 struct sprd_dpu *dpu = data; in sprd_dpu_isr() local
753 struct dpu_context *ctx = &dpu->ctx; in sprd_dpu_isr()
756 reg_val = readl(ctx->base + REG_DPU_INT_STS); in sprd_dpu_isr()
761 drm_warn(dpu->drm, "Warning: dpu underflow!\n"); in sprd_dpu_isr()
764 /* dpu update done isr */ in sprd_dpu_isr()
766 ctx->evt_update = true; in sprd_dpu_isr()
767 wake_up_interruptible_all(&ctx->wait_queue); in sprd_dpu_isr()
770 /* dpu stop done isr */ in sprd_dpu_isr()
772 ctx->evt_stop = true; in sprd_dpu_isr()
773 wake_up_interruptible_all(&ctx->wait_queue); in sprd_dpu_isr()
777 drm_crtc_handle_vblank(&dpu->base); in sprd_dpu_isr()
779 writel(reg_val, ctx->base + REG_DPU_INT_CLR); in sprd_dpu_isr()
785 static int sprd_dpu_context_init(struct sprd_dpu *dpu, in sprd_dpu_context_init() argument
789 struct dpu_context *ctx = &dpu->ctx; in sprd_dpu_context_init()
796 return -EINVAL; in sprd_dpu_context_init()
799 ctx->base = devm_ioremap(dev, res->start, resource_size(res)); in sprd_dpu_context_init()
800 if (!ctx->base) { in sprd_dpu_context_init()
801 dev_err(dev, "failed to map dpu registers\n"); in sprd_dpu_context_init()
802 return -EFAULT; in sprd_dpu_context_init()
805 ctx->irq = platform_get_irq(pdev, 0); in sprd_dpu_context_init()
806 if (ctx->irq < 0) { in sprd_dpu_context_init()
807 dev_err(dev, "failed to get dpu irq\n"); in sprd_dpu_context_init()
808 return ctx->irq; in sprd_dpu_context_init()
811 /* disable and clear interrupts before register dpu IRQ. */ in sprd_dpu_context_init()
812 writel(0x00, ctx->base + REG_DPU_INT_EN); in sprd_dpu_context_init()
813 writel(0xff, ctx->base + REG_DPU_INT_CLR); in sprd_dpu_context_init()
815 ret = devm_request_irq(dev, ctx->irq, sprd_dpu_isr, in sprd_dpu_context_init()
816 IRQF_TRIGGER_NONE, "DPU", dpu); in sprd_dpu_context_init()
818 dev_err(dev, "failed to register dpu irq handler\n"); in sprd_dpu_context_init()
822 init_waitqueue_head(&ctx->wait_queue); in sprd_dpu_context_init()
830 struct sprd_dpu *dpu; in sprd_dpu_bind() local
838 dpu = sprd_crtc_init(drm, &plane->base, dev); in sprd_dpu_bind()
839 if (IS_ERR(dpu)) in sprd_dpu_bind()
840 return PTR_ERR(dpu); in sprd_dpu_bind()
842 dpu->drm = drm; in sprd_dpu_bind()
843 dev_set_drvdata(dev, dpu); in sprd_dpu_bind()
845 ret = sprd_dpu_context_init(dpu, dev); in sprd_dpu_bind()
857 { .compatible = "sprd,sharkl3-dpu" },
864 return component_add(&pdev->dev, &dpu_component_ops); in sprd_dpu_probe()
869 component_del(&pdev->dev, &dpu_component_ops); in sprd_dpu_remove()
878 .name = "sprd-dpu-drv",