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

1 // SPDX-License-Identifier: GPL-2.0
8 #include <linux/dma-buf.h>
128 static int dpu_wait_stop_done(struct sprd_dpu *dpu) in dpu_wait_stop_done() argument
130 struct dpu_context *ctx = &dpu->ctx; in dpu_wait_stop_done()
133 if (ctx->stopped) in dpu_wait_stop_done()
136 rc = wait_event_interruptible_timeout(ctx->wait_queue, ctx->evt_stop, in dpu_wait_stop_done()
138 ctx->evt_stop = false; in dpu_wait_stop_done()
140 ctx->stopped = true; in dpu_wait_stop_done()
143 drm_err(dpu->drm, "dpu wait for stop done time out!\n"); in dpu_wait_stop_done()
144 return -ETIMEDOUT; in dpu_wait_stop_done()
150 static int dpu_wait_update_done(struct sprd_dpu *dpu) in dpu_wait_update_done() argument
152 struct dpu_context *ctx = &dpu->ctx; in dpu_wait_update_done()
155 ctx->evt_update = false; in dpu_wait_update_done()
157 rc = wait_event_interruptible_timeout(ctx->wait_queue, ctx->evt_update, in dpu_wait_update_done()
161 drm_err(dpu->drm, "dpu wait for reg update done time out!\n"); in dpu_wait_update_done()
162 return -ETIMEDOUT; in dpu_wait_update_done()
172 switch (fb->format->format) { in drm_format_to_dpu()
174 /* BGRA8888 -> ARGB8888 */ in drm_format_to_dpu()
180 /* RGBA8888 -> ABGR8888 */ in drm_format_to_dpu()
205 /* 2-Lane: Yuv420 */ in drm_format_to_dpu()
213 /* 2-Lane: Yuv420 */ in drm_format_to_dpu()
221 /* 2-Lane: Yuv422 */ in drm_format_to_dpu()
229 /* 2-Lane: Yuv422 */ in drm_format_to_dpu()
261 switch (state->rotation) { in drm_rotation_to_dpu()
296 switch (state->pixel_blend_mode) { in drm_blend_to_dpu()
298 /* alpha mode select - combo alpha */ in drm_blend_to_dpu()
304 /* alpha mode select - combo alpha */ in drm_blend_to_dpu()
306 /* Pre-mult mode */ in drm_blend_to_dpu()
312 /* alpha mode select - layer alpha */ in drm_blend_to_dpu()
320 static void sprd_dpu_layer(struct sprd_dpu *dpu, struct drm_plane_state *state) in sprd_dpu_layer() argument
322 struct dpu_context *ctx = &dpu->ctx; in sprd_dpu_layer()
324 struct drm_framebuffer *fb = state->fb; in sprd_dpu_layer()
326 u32 src_x = state->src_x >> 16; in sprd_dpu_layer()
327 u32 src_y = state->src_y >> 16; in sprd_dpu_layer()
328 u32 src_w = state->src_w >> 16; in sprd_dpu_layer()
329 u32 src_h = state->src_h >> 16; in sprd_dpu_layer()
330 u32 dst_x = state->crtc_x; in sprd_dpu_layer()
331 u32 dst_y = state->crtc_y; in sprd_dpu_layer()
332 u32 alpha = state->alpha; in sprd_dpu_layer()
333 u32 index = state->zpos; in sprd_dpu_layer()
339 for (i = 0; i < fb->format->num_planes; i++) { in sprd_dpu_layer()
341 addr = dma_obj->dma_addr + fb->offsets[i]; in sprd_dpu_layer()
351 if (fb->format->num_planes == 3) { in sprd_dpu_layer()
353 pitch = (fb->pitches[0] / fb->format->cpp[0]) | in sprd_dpu_layer()
354 (fb->pitches[0] / fb->format->cpp[0] << 15); in sprd_dpu_layer()
356 pitch = fb->pitches[0] / fb->format->cpp[0]; in sprd_dpu_layer()
377 static void sprd_dpu_flip(struct sprd_dpu *dpu) in sprd_dpu_flip() argument
379 struct dpu_context *ctx = &dpu->ctx; in sprd_dpu_flip()
382 * Make sure the dpu is in stop status. DPU has no shadow in sprd_dpu_flip()
386 if (ctx->if_type == SPRD_DPU_IF_EDPI) in sprd_dpu_flip()
387 dpu_wait_stop_done(dpu); in sprd_dpu_flip()
390 if (ctx->if_type == SPRD_DPU_IF_DPI) { in sprd_dpu_flip()
391 if (!ctx->stopped) { in sprd_dpu_flip()
393 dpu_wait_update_done(dpu); in sprd_dpu_flip()
397 } else if (ctx->if_type == SPRD_DPU_IF_EDPI) { in sprd_dpu_flip()
400 ctx->stopped = false; in sprd_dpu_flip()
404 static void sprd_dpu_init(struct sprd_dpu *dpu) in sprd_dpu_init() argument
406 struct dpu_context *ctx = &dpu->ctx; in sprd_dpu_init()
409 writel(0x00, ctx->base + REG_BG_COLOR); in sprd_dpu_init()
410 writel(0x00, ctx->base + REG_MMU_EN); in sprd_dpu_init()
411 writel(0x00, ctx->base + REG_MMU_PPN1); in sprd_dpu_init()
412 writel(0xffff, ctx->base + REG_MMU_RANGE1); in sprd_dpu_init()
413 writel(0x00, ctx->base + REG_MMU_PPN2); in sprd_dpu_init()
414 writel(0xffff, ctx->base + REG_MMU_RANGE2); in sprd_dpu_init()
415 writel(0x1ffff, ctx->base + REG_MMU_VPN_RANGE); in sprd_dpu_init()
417 if (ctx->if_type == SPRD_DPU_IF_DPI) { in sprd_dpu_init()
425 /* enable dpu update done INT */ in sprd_dpu_init()
427 /* enable dpu done INT */ in sprd_dpu_init()
429 /* enable dpu dpi vsync */ in sprd_dpu_init()
431 /* enable dpu TE INT */ in sprd_dpu_init()
435 } else if (ctx->if_type == SPRD_DPU_IF_EDPI) { in sprd_dpu_init()
449 writel(int_mask, ctx->base + REG_DPU_INT_EN); in sprd_dpu_init()
452 static void sprd_dpu_fini(struct sprd_dpu *dpu) in sprd_dpu_fini() argument
454 struct dpu_context *ctx = &dpu->ctx; in sprd_dpu_fini()
456 writel(0x00, ctx->base + REG_DPU_INT_EN); in sprd_dpu_fini()
457 writel(0xff, ctx->base + REG_DPU_INT_CLR); in sprd_dpu_fini()
460 static void sprd_dpi_init(struct sprd_dpu *dpu) in sprd_dpi_init() argument
462 struct dpu_context *ctx = &dpu->ctx; in sprd_dpi_init()
466 size = (ctx->vm.vactive << 16) | ctx->vm.hactive; in sprd_dpi_init()
467 writel(size, ctx->base + REG_PANEL_SIZE); in sprd_dpi_init()
468 writel(size, ctx->base + REG_BLEND_SIZE); in sprd_dpi_init()
470 if (ctx->if_type == SPRD_DPU_IF_DPI) { in sprd_dpi_init()
472 reg_val = ctx->vm.hsync_len << 0 | in sprd_dpi_init()
473 ctx->vm.hback_porch << 8 | in sprd_dpi_init()
474 ctx->vm.hfront_porch << 20; in sprd_dpi_init()
475 writel(reg_val, ctx->base + REG_DPI_H_TIMING); in sprd_dpi_init()
477 reg_val = ctx->vm.vsync_len << 0 | in sprd_dpi_init()
478 ctx->vm.vback_porch << 8 | in sprd_dpi_init()
479 ctx->vm.vfront_porch << 20; in sprd_dpi_init()
480 writel(reg_val, ctx->base + REG_DPI_V_TIMING); in sprd_dpi_init()
484 void sprd_dpu_run(struct sprd_dpu *dpu) in sprd_dpu_run() argument
486 struct dpu_context *ctx = &dpu->ctx; in sprd_dpu_run()
490 ctx->stopped = false; in sprd_dpu_run()
493 void sprd_dpu_stop(struct sprd_dpu *dpu) in sprd_dpu_stop() argument
495 struct dpu_context *ctx = &dpu->ctx; in sprd_dpu_stop()
497 if (ctx->if_type == SPRD_DPU_IF_DPI) in sprd_dpu_stop()
500 dpu_wait_stop_done(dpu); in sprd_dpu_stop()
511 if (!plane_state->fb || !plane_state->crtc) in sprd_plane_atomic_check()
514 fmt = drm_format_to_dpu(plane_state->fb); in sprd_plane_atomic_check()
516 return -EINVAL; in sprd_plane_atomic_check()
518 crtc_state = drm_atomic_get_crtc_state(plane_state->state, plane_state->crtc); in sprd_plane_atomic_check()
533 struct sprd_dpu *dpu = to_sprd_crtc(new_state->crtc); in sprd_plane_atomic_update() local
535 /* start configure dpu layers */ in sprd_plane_atomic_update()
536 sprd_dpu_layer(dpu, new_state); in sprd_plane_atomic_update()
544 struct sprd_dpu *dpu = to_sprd_crtc(old_state->crtc); in sprd_plane_atomic_disable() local
546 layer_reg_wr(&dpu->ctx, REG_LAY_CTRL, 0x00, old_state->zpos); in sprd_plane_atomic_disable()
556 drm_plane_create_rotation_property(&plane->base, in sprd_plane_create_properties()
562 drm_plane_create_alpha_property(&plane->base); in sprd_plane_create_properties()
565 drm_plane_create_blend_mode_property(&plane->base, supported_modes); in sprd_plane_create_properties()
568 drm_plane_create_zpos_immutable_property(&plane->base, index); in sprd_plane_create_properties()
605 drm_plane_helper_add(&plane->base, &sprd_plane_helper_funcs); in sprd_planes_init()
618 struct sprd_dpu *dpu = to_sprd_crtc(crtc); in sprd_crtc_mode_set_nofb() local
619 struct drm_display_mode *mode = &crtc->state->adjusted_mode; in sprd_crtc_mode_set_nofb()
623 drm_display_mode_to_videomode(mode, &dpu->ctx.vm); in sprd_crtc_mode_set_nofb()
625 drm_for_each_encoder_mask(encoder, crtc->dev, in sprd_crtc_mode_set_nofb()
626 crtc->state->encoder_mask) { in sprd_crtc_mode_set_nofb()
629 if (dsi->slave->mode_flags & MIPI_DSI_MODE_VIDEO) in sprd_crtc_mode_set_nofb()
630 dpu->ctx.if_type = SPRD_DPU_IF_DPI; in sprd_crtc_mode_set_nofb()
632 dpu->ctx.if_type = SPRD_DPU_IF_EDPI; in sprd_crtc_mode_set_nofb()
635 sprd_dpi_init(dpu); in sprd_crtc_mode_set_nofb()
641 struct sprd_dpu *dpu = to_sprd_crtc(crtc); in sprd_crtc_atomic_enable() local
643 sprd_dpu_init(dpu); in sprd_crtc_atomic_enable()
645 drm_crtc_vblank_on(&dpu->base); in sprd_crtc_atomic_enable()
651 struct sprd_dpu *dpu = to_sprd_crtc(crtc); in sprd_crtc_atomic_disable() local
652 struct drm_device *drm = dpu->base.dev; in sprd_crtc_atomic_disable()
654 drm_crtc_vblank_off(&dpu->base); in sprd_crtc_atomic_disable()
656 sprd_dpu_fini(dpu); in sprd_crtc_atomic_disable()
658 spin_lock_irq(&drm->event_lock); in sprd_crtc_atomic_disable()
659 if (crtc->state->event) { in sprd_crtc_atomic_disable()
660 drm_crtc_send_vblank_event(crtc, crtc->state->event); in sprd_crtc_atomic_disable()
661 crtc->state->event = NULL; in sprd_crtc_atomic_disable()
663 spin_unlock_irq(&drm->event_lock); in sprd_crtc_atomic_disable()
670 struct sprd_dpu *dpu = to_sprd_crtc(crtc); in sprd_crtc_atomic_flush() local
671 struct drm_device *drm = dpu->base.dev; in sprd_crtc_atomic_flush()
673 sprd_dpu_flip(dpu); in sprd_crtc_atomic_flush()
675 spin_lock_irq(&drm->event_lock); in sprd_crtc_atomic_flush()
676 if (crtc->state->event) { in sprd_crtc_atomic_flush()
677 drm_crtc_send_vblank_event(crtc, crtc->state->event); in sprd_crtc_atomic_flush()
678 crtc->state->event = NULL; in sprd_crtc_atomic_flush()
680 spin_unlock_irq(&drm->event_lock); in sprd_crtc_atomic_flush()
685 struct sprd_dpu *dpu = to_sprd_crtc(crtc); in sprd_crtc_enable_vblank() local
687 dpu_reg_set(&dpu->ctx, REG_DPU_INT_EN, BIT_DPU_INT_VSYNC); in sprd_crtc_enable_vblank()
694 struct sprd_dpu *dpu = to_sprd_crtc(crtc); in sprd_crtc_disable_vblank() local
696 dpu_reg_clr(&dpu->ctx, REG_DPU_INT_EN, BIT_DPU_INT_VSYNC); in sprd_crtc_disable_vblank()
721 struct sprd_dpu *dpu; in sprd_crtc_init() local
723 dpu = drmm_crtc_alloc_with_planes(drm, struct sprd_dpu, base, in sprd_crtc_init()
726 if (IS_ERR(dpu)) { in sprd_crtc_init()
728 return dpu; in sprd_crtc_init()
730 drm_crtc_helper_add(&dpu->base, &sprd_crtc_helper_funcs); in sprd_crtc_init()
735 port = of_graph_get_port_by_id(dev->of_node, 0); in sprd_crtc_init()
738 dev->of_node->full_name); in sprd_crtc_init()
739 return ERR_PTR(-EINVAL); in sprd_crtc_init()
741 dpu->base.port = port; in sprd_crtc_init()
744 return dpu; in sprd_crtc_init()
749 struct sprd_dpu *dpu = data; in sprd_dpu_isr() local
750 struct dpu_context *ctx = &dpu->ctx; in sprd_dpu_isr()
753 reg_val = readl(ctx->base + REG_DPU_INT_STS); in sprd_dpu_isr()
758 drm_warn(dpu->drm, "Warning: dpu underflow!\n"); in sprd_dpu_isr()
761 /* dpu update done isr */ in sprd_dpu_isr()
763 ctx->evt_update = true; in sprd_dpu_isr()
764 wake_up_interruptible_all(&ctx->wait_queue); in sprd_dpu_isr()
767 /* dpu stop done isr */ in sprd_dpu_isr()
769 ctx->evt_stop = true; in sprd_dpu_isr()
770 wake_up_interruptible_all(&ctx->wait_queue); in sprd_dpu_isr()
774 drm_crtc_handle_vblank(&dpu->base); in sprd_dpu_isr()
776 writel(reg_val, ctx->base + REG_DPU_INT_CLR); in sprd_dpu_isr()
782 static int sprd_dpu_context_init(struct sprd_dpu *dpu, in sprd_dpu_context_init() argument
786 struct dpu_context *ctx = &dpu->ctx; in sprd_dpu_context_init()
793 return -EINVAL; in sprd_dpu_context_init()
796 ctx->base = devm_ioremap(dev, res->start, resource_size(res)); in sprd_dpu_context_init()
797 if (!ctx->base) { in sprd_dpu_context_init()
798 dev_err(dev, "failed to map dpu registers\n"); in sprd_dpu_context_init()
799 return -EFAULT; in sprd_dpu_context_init()
802 ctx->irq = platform_get_irq(pdev, 0); in sprd_dpu_context_init()
803 if (ctx->irq < 0) in sprd_dpu_context_init()
804 return ctx->irq; in sprd_dpu_context_init()
806 /* disable and clear interrupts before register dpu IRQ. */ in sprd_dpu_context_init()
807 writel(0x00, ctx->base + REG_DPU_INT_EN); in sprd_dpu_context_init()
808 writel(0xff, ctx->base + REG_DPU_INT_CLR); in sprd_dpu_context_init()
810 ret = devm_request_irq(dev, ctx->irq, sprd_dpu_isr, in sprd_dpu_context_init()
811 IRQF_TRIGGER_NONE, "DPU", dpu); in sprd_dpu_context_init()
813 dev_err(dev, "failed to register dpu irq handler\n"); in sprd_dpu_context_init()
817 init_waitqueue_head(&ctx->wait_queue); in sprd_dpu_context_init()
825 struct sprd_dpu *dpu; in sprd_dpu_bind() local
833 dpu = sprd_crtc_init(drm, &plane->base, dev); in sprd_dpu_bind()
834 if (IS_ERR(dpu)) in sprd_dpu_bind()
835 return PTR_ERR(dpu); in sprd_dpu_bind()
837 dpu->drm = drm; in sprd_dpu_bind()
838 dev_set_drvdata(dev, dpu); in sprd_dpu_bind()
840 ret = sprd_dpu_context_init(dpu, dev); in sprd_dpu_bind()
852 { .compatible = "sprd,sharkl3-dpu" },
859 return component_add(&pdev->dev, &dpu_component_ops); in sprd_dpu_probe()
864 component_del(&pdev->dev, &dpu_component_ops); in sprd_dpu_remove()
871 .name = "sprd-dpu-drv",