diff options
Diffstat (limited to 'drivers/gpu/drm/arm')
22 files changed, 222 insertions, 108 deletions
diff --git a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c index 4073a452e24a..55a8cc94808a 100644 --- a/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c +++ b/drivers/gpu/drm/arm/display/komeda/d71/d71_component.c @@ -4,8 +4,6 @@ * Author: James.Qian.Wang <james.qian.wang@arm.com> * */ - -#include <drm/drm_print.h> #include "d71_dev.h" #include "komeda_kms.h" #include "malidp_io.h" @@ -804,7 +802,7 @@ static int d71_downscaling_clk_check(struct komeda_pipeline *pipe, denominator = (mode->htotal - 1) * v_out - 2 * v_in; } - return aclk_rate * denominator >= mode->clock * 1000 * fraction ? + return aclk_rate * denominator >= mode->crtc_clock * 1000 * fraction ? 0 : -EINVAL; } @@ -1032,21 +1030,31 @@ static void d71_timing_ctrlr_update(struct komeda_component *c, struct komeda_component_state *state) { struct drm_crtc_state *crtc_st = state->crtc->state; + struct drm_display_mode *mode = &crtc_st->adjusted_mode; u32 __iomem *reg = c->reg; - struct videomode vm; + u32 hactive, hfront_porch, hback_porch, hsync_len; + u32 vactive, vfront_porch, vback_porch, vsync_len; u32 value; - drm_display_mode_to_videomode(&crtc_st->adjusted_mode, &vm); - - malidp_write32(reg, BS_ACTIVESIZE, HV_SIZE(vm.hactive, vm.vactive)); - malidp_write32(reg, BS_HINTERVALS, BS_H_INTVALS(vm.hfront_porch, - vm.hback_porch)); - malidp_write32(reg, BS_VINTERVALS, BS_V_INTVALS(vm.vfront_porch, - vm.vback_porch)); - - value = BS_SYNC_VSW(vm.vsync_len) | BS_SYNC_HSW(vm.hsync_len); - value |= vm.flags & DISPLAY_FLAGS_VSYNC_HIGH ? BS_SYNC_VSP : 0; - value |= vm.flags & DISPLAY_FLAGS_HSYNC_HIGH ? BS_SYNC_HSP : 0; + hactive = mode->crtc_hdisplay; + hfront_porch = mode->crtc_hsync_start - mode->crtc_hdisplay; + hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start; + hback_porch = mode->crtc_htotal - mode->crtc_hsync_end; + + vactive = mode->crtc_vdisplay; + vfront_porch = mode->crtc_vsync_start - mode->crtc_vdisplay; + vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start; + vback_porch = mode->crtc_vtotal - mode->crtc_vsync_end; + + malidp_write32(reg, BS_ACTIVESIZE, HV_SIZE(hactive, vactive)); + malidp_write32(reg, BS_HINTERVALS, BS_H_INTVALS(hfront_porch, + hback_porch)); + malidp_write32(reg, BS_VINTERVALS, BS_V_INTVALS(vfront_porch, + vback_porch)); + + value = BS_SYNC_VSW(vsync_len) | BS_SYNC_HSW(hsync_len); + value |= mode->flags & DRM_MODE_FLAG_PVSYNC ? BS_SYNC_VSP : 0; + value |= mode->flags & DRM_MODE_FLAG_PHSYNC ? BS_SYNC_HSP : 0; malidp_write32(reg, BS_SYNC, value); malidp_write32(reg, BS_PROG_LINE, D71_DEFAULT_PREPRETCH_LINE - 1); @@ -1054,6 +1062,10 @@ static void d71_timing_ctrlr_update(struct komeda_component *c, /* configure bs control register */ value = BS_CTRL_EN | BS_CTRL_VM; + if (c->pipeline->dual_link) { + malidp_write32(reg, BS_DRIFT_TO, hfront_porch + 16); + value |= BS_CTRL_DL; + } malidp_write32(reg, BLK_CONTROL, value); } diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c index f4400788ab94..624d257da20f 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -27,8 +27,8 @@ static void komeda_crtc_update_clock_ratio(struct komeda_crtc_state *kcrtc_st) return; } - pxlclk = kcrtc_st->base.adjusted_mode.clock * 1000; - aclk = komeda_calc_aclk(kcrtc_st); + pxlclk = kcrtc_st->base.adjusted_mode.crtc_clock * 1000ULL; + aclk = komeda_crtc_get_aclk(kcrtc_st); kcrtc_st->clock_ratio = div64_u64(aclk << 32, pxlclk); } @@ -74,14 +74,6 @@ komeda_crtc_atomic_check(struct drm_crtc *crtc, return 0; } -unsigned long komeda_calc_aclk(struct komeda_crtc_state *kcrtc_st) -{ - struct komeda_dev *mdev = kcrtc_st->base.crtc->dev->dev_private; - unsigned long pxlclk = kcrtc_st->base.adjusted_mode.clock; - - return clk_round_rate(mdev->aclk, pxlclk * 1000); -} - /* For active a crtc, mainly need two parts of preparation * 1. adjust display operation mode. * 2. enable needed clk @@ -92,7 +84,7 @@ komeda_crtc_prepare(struct komeda_crtc *kcrtc) struct komeda_dev *mdev = kcrtc->base.dev->dev_private; struct komeda_pipeline *master = kcrtc->master; struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(kcrtc->base.state); - unsigned long pxlclk_rate = kcrtc_st->base.adjusted_mode.clock * 1000; + struct drm_display_mode *mode = &kcrtc_st->base.adjusted_mode; u32 new_mode; int err; @@ -118,7 +110,7 @@ komeda_crtc_prepare(struct komeda_crtc *kcrtc) * to enable it again. */ if (new_mode != KOMEDA_MODE_DUAL_DISP) { - err = clk_set_rate(mdev->aclk, komeda_calc_aclk(kcrtc_st)); + err = clk_set_rate(mdev->aclk, komeda_crtc_get_aclk(kcrtc_st)); if (err) DRM_ERROR("failed to set aclk.\n"); err = clk_prepare_enable(mdev->aclk); @@ -126,7 +118,7 @@ komeda_crtc_prepare(struct komeda_crtc *kcrtc) DRM_ERROR("failed to enable aclk.\n"); } - err = clk_set_rate(master->pxlclk, pxlclk_rate); + err = clk_set_rate(master->pxlclk, mode->crtc_clock * 1000); if (err) DRM_ERROR("failed to set pxlclk for pipe%d\n", master->id); err = clk_prepare_enable(master->pxlclk); @@ -342,29 +334,58 @@ komeda_crtc_atomic_flush(struct drm_crtc *crtc, komeda_crtc_do_flush(crtc, old); } +/* Returns the minimum frequency of the aclk rate (main engine clock) in Hz */ +static unsigned long +komeda_calc_min_aclk_rate(struct komeda_crtc *kcrtc, + unsigned long pxlclk) +{ + /* Once dual-link one display pipeline drives two display outputs, + * the aclk needs run on the double rate of pxlclk + */ + if (kcrtc->master->dual_link) + return pxlclk * 2; + else + return pxlclk; +} + +/* Get current aclk rate that specified by state */ +unsigned long komeda_crtc_get_aclk(struct komeda_crtc_state *kcrtc_st) +{ + struct drm_crtc *crtc = kcrtc_st->base.crtc; + struct komeda_dev *mdev = crtc->dev->dev_private; + unsigned long pxlclk = kcrtc_st->base.adjusted_mode.crtc_clock * 1000; + unsigned long min_aclk; + + min_aclk = komeda_calc_min_aclk_rate(to_kcrtc(crtc), pxlclk); + + return clk_round_rate(mdev->aclk, min_aclk); +} + static enum drm_mode_status komeda_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *m) { struct komeda_dev *mdev = crtc->dev->dev_private; struct komeda_crtc *kcrtc = to_kcrtc(crtc); struct komeda_pipeline *master = kcrtc->master; - long mode_clk, pxlclk; + unsigned long min_pxlclk, min_aclk; if (m->flags & DRM_MODE_FLAG_INTERLACE) return MODE_NO_INTERLACE; - mode_clk = m->clock * 1000; - pxlclk = clk_round_rate(master->pxlclk, mode_clk); - if (pxlclk != mode_clk) { - DRM_DEBUG_ATOMIC("pxlclk doesn't support %ld Hz\n", mode_clk); + min_pxlclk = m->clock * 1000; + if (master->dual_link) + min_pxlclk /= 2; + + if (min_pxlclk != clk_round_rate(master->pxlclk, min_pxlclk)) { + DRM_DEBUG_ATOMIC("pxlclk doesn't support %lu Hz\n", min_pxlclk); return MODE_NOCLOCK; } - /* main engine clock must be faster than pxlclk*/ - if (clk_round_rate(mdev->aclk, mode_clk) < pxlclk) { - DRM_DEBUG_ATOMIC("engine clk can't satisfy the requirement of %s-clk: %ld.\n", - m->name, pxlclk); + min_aclk = komeda_calc_min_aclk_rate(to_kcrtc(crtc), min_pxlclk); + if (clk_round_rate(mdev->aclk, min_aclk) < min_aclk) { + DRM_DEBUG_ATOMIC("engine clk can't satisfy the requirement of %s-clk: %lu.\n", + m->name, min_pxlclk); return MODE_CLOCK_HIGH; } @@ -377,10 +398,22 @@ static bool komeda_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *adjusted_mode) { struct komeda_crtc *kcrtc = to_kcrtc(crtc); - struct komeda_pipeline *master = kcrtc->master; - long mode_clk = m->clock * 1000; + unsigned long clk_rate; + + drm_mode_set_crtcinfo(adjusted_mode, 0); + /* In dual link half the horizontal settings */ + if (kcrtc->master->dual_link) { + adjusted_mode->crtc_clock /= 2; + adjusted_mode->crtc_hdisplay /= 2; + adjusted_mode->crtc_hsync_start /= 2; + adjusted_mode->crtc_hsync_end /= 2; + adjusted_mode->crtc_htotal /= 2; + } - adjusted_mode->clock = clk_round_rate(master->pxlclk, mode_clk) / 1000; + clk_rate = adjusted_mode->crtc_clock * 1000; + /* crtc_clock will be used as the komeda output pixel clock */ + adjusted_mode->crtc_clock = clk_round_rate(kcrtc->master->pxlclk, + clk_rate) / 1000; return true; } @@ -488,10 +521,8 @@ int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms, else sprintf(str, "None"); - DRM_INFO("crtc%d: master(pipe-%d) slave(%s) output: %s.\n", - kms->n_crtcs, master->id, str, - master->of_output_dev ? - master->of_output_dev->full_name : "None"); + DRM_INFO("CRTC-%d: master(pipe-%d) slave(%s).\n", + kms->n_crtcs, master->id, str); kms->n_crtcs++; } diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c index 5a118984de33..ca64a129c594 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_dev.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_dev.c @@ -8,6 +8,7 @@ #include <linux/iommu.h> #include <linux/of_device.h> #include <linux/of_graph.h> +#include <linux/of_reserved_mem.h> #include <linux/platform_device.h> #include <linux/dma-mapping.h> #ifdef CONFIG_DEBUG_FS @@ -121,12 +122,15 @@ static int komeda_parse_pipe_dt(struct komeda_dev *mdev, struct device_node *np) pipe->pxlclk = clk; /* enum ports */ - pipe->of_output_dev = + pipe->of_output_links[0] = of_graph_get_remote_node(np, KOMEDA_OF_PORT_OUTPUT, 0); + pipe->of_output_links[1] = + of_graph_get_remote_node(np, KOMEDA_OF_PORT_OUTPUT, 1); pipe->of_output_port = of_graph_get_port_by_id(np, KOMEDA_OF_PORT_OUTPUT); - pipe->of_node = np; + pipe->dual_link = pipe->of_output_links[0] && pipe->of_output_links[1]; + pipe->of_node = of_node_get(np); return 0; } @@ -143,6 +147,12 @@ static int komeda_parse_dt(struct device *dev, struct komeda_dev *mdev) return mdev->irq; } + /* Get the optional framebuffer memory resource */ + ret = of_reserved_mem_device_init(dev); + if (ret && ret != -ENODEV) + return ret; + ret = 0; + for_each_available_child_of_node(np, child) { if (of_node_cmp(child->name, "pipeline") == 0) { ret = komeda_parse_pipe_dt(mdev, child); @@ -289,6 +299,8 @@ void komeda_dev_destroy(struct komeda_dev *mdev) mdev->n_pipelines = 0; + of_reserved_mem_device_release(dev); + if (funcs && funcs->cleanup) funcs->cleanup(mdev); diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c index cfa5068d9d1e..69ace6f9055d 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_drv.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_drv.c @@ -83,11 +83,12 @@ static int compare_of(struct device *dev, void *data) static void komeda_add_slave(struct device *master, struct component_match **match, - struct device_node *np, int port) + struct device_node *np, + u32 port, u32 endpoint) { struct device_node *remote; - remote = of_graph_get_remote_node(np, port, 0); + remote = of_graph_get_remote_node(np, port, endpoint); if (remote) { drm_of_component_match_add(master, match, compare_of, remote); of_node_put(remote); @@ -108,7 +109,8 @@ static int komeda_platform_probe(struct platform_device *pdev) continue; /* add connector */ - komeda_add_slave(dev, &match, child, KOMEDA_OF_PORT_OUTPUT); + komeda_add_slave(dev, &match, child, KOMEDA_OF_PORT_OUTPUT, 0); + komeda_add_slave(dev, &match, child, KOMEDA_OF_PORT_OUTPUT, 1); } return component_master_add_with_match(dev, &komeda_master_ops, match); diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.c b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.c index cd4d9f53ddef..c9a1edb9a000 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.c @@ -35,6 +35,25 @@ komeda_get_format_caps(struct komeda_format_caps_table *table, return NULL; } +u32 komeda_get_afbc_format_bpp(const struct drm_format_info *info, u64 modifier) +{ + u32 bpp; + + switch (info->format) { + case DRM_FORMAT_YUV420_8BIT: + bpp = 12; + break; + case DRM_FORMAT_YUV420_10BIT: + bpp = 15; + break; + default: + bpp = info->cpp[0] * 8; + break; + } + + return bpp; +} + /* Two assumptions * 1. RGB always has YTR * 2. Tiled RGB always has SC diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h index 3631910d33b5..32273cf18f7c 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_format_caps.h @@ -97,6 +97,9 @@ const struct komeda_format_caps * komeda_get_format_caps(struct komeda_format_caps_table *table, u32 fourcc, u64 modifier); +u32 komeda_get_afbc_format_bpp(const struct drm_format_info *info, + u64 modifier); + u32 *komeda_get_layer_fourcc_list(struct komeda_format_caps_table *table, u32 layer_type, u32 *n_fmts); diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c index 3b0a70ed6aa0..1b01a625f40e 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c @@ -43,7 +43,7 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb, struct drm_file *file, struct drm_framebuffer *fb = &kfb->base; const struct drm_format_info *info = fb->format; struct drm_gem_object *obj; - u32 alignment_w = 0, alignment_h = 0, alignment_header, n_blocks; + u32 alignment_w = 0, alignment_h = 0, alignment_header, n_blocks, bpp; u64 min_size; obj = drm_gem_object_lookup(file, mode_cmd->handles[0]); @@ -88,8 +88,9 @@ komeda_fb_afbc_size_check(struct komeda_fb *kfb, struct drm_file *file, kfb->offset_payload = ALIGN(n_blocks * AFBC_HEADER_SIZE, alignment_header); + bpp = komeda_get_afbc_format_bpp(info, fb->modifier); kfb->afbc_size = kfb->offset_payload + n_blocks * - ALIGN(info->cpp[0] * AFBC_SUPERBLK_PIXELS, + ALIGN(bpp * AFBC_SUPERBLK_PIXELS / 8, AFBC_SUPERBLK_ALIGNMENT); min_size = kfb->afbc_size + fb->offsets[0]; if (min_size > obj->size) { diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c index 419a8b0e5de8..8820ce15ce37 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.c @@ -14,6 +14,7 @@ #include <drm/drm_gem_cma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_irq.h> +#include <drm/drm_probe_helper.h> #include <drm/drm_vblank.h> #include "komeda_dev.h" @@ -55,16 +56,13 @@ static irqreturn_t komeda_kms_irq_handler(int irq, void *data) } static struct drm_driver komeda_kms_driver = { - .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC | - DRIVER_PRIME | DRIVER_HAVE_IRQ, + .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .lastclose = drm_fb_helper_lastclose, .gem_free_object_unlocked = drm_gem_cma_free_object, .gem_vm_ops = &drm_gem_cma_vm_ops, .dumb_create = komeda_gem_cma_dumb_create, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_export = drm_gem_prime_export, - .gem_prime_import = drm_gem_prime_import, .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, .gem_prime_vmap = drm_gem_cma_prime_vmap, @@ -146,7 +144,6 @@ static int komeda_crtc_normalize_zpos(struct drm_crtc *crtc, struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(crtc_st); struct komeda_plane_state *kplane_st; struct drm_plane_state *plane_st; - struct drm_framebuffer *fb; struct drm_plane *plane; struct list_head zorder_list; int order = 0, err; @@ -172,7 +169,6 @@ static int komeda_crtc_normalize_zpos(struct drm_crtc *crtc, list_for_each_entry(kplane_st, &zorder_list, zlist_node) { plane_st = &kplane_st->base; - fb = plane_st->fb; plane = plane_st->plane; plane_st->normalized_zpos = order++; @@ -205,7 +201,7 @@ static int komeda_kms_check(struct drm_device *dev, struct drm_atomic_state *state) { struct drm_crtc *crtc; - struct drm_crtc_state *old_crtc_st, *new_crtc_st; + struct drm_crtc_state *new_crtc_st; int i, err; err = drm_atomic_helper_check_modeset(dev, state); @@ -216,7 +212,7 @@ static int komeda_kms_check(struct drm_device *dev, * so need to add all affected_planes (even unchanged) to * drm_atomic_state. */ - for_each_oldnew_crtc_in_state(state, crtc, old_crtc_st, new_crtc_st, i) { + for_each_new_crtc_in_state(state, crtc, new_crtc_st, i) { err = drm_atomic_add_affected_planes(state, crtc); if (err) return err; @@ -307,24 +303,33 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev) komeda_kms_irq_handler, IRQF_SHARED, drm->driver->name, drm); if (err) - goto cleanup_mode_config; + goto free_component_binding; err = mdev->funcs->enable_irq(mdev); if (err) - goto cleanup_mode_config; + goto free_component_binding; drm->irq_enabled = true; + drm_kms_helper_poll_init(drm); + err = drm_dev_register(drm, 0); if (err) - goto cleanup_mode_config; + goto free_interrupts; return kms; -cleanup_mode_config: +free_interrupts: + drm_kms_helper_poll_fini(drm); drm->irq_enabled = false; + mdev->funcs->disable_irq(mdev); +free_component_binding: + component_unbind_all(mdev->dev, drm); +cleanup_mode_config: drm_mode_config_cleanup(drm); komeda_kms_cleanup_private_objs(kms); + drm->dev_private = NULL; + drm_dev_put(drm); free_kms: kfree(kms); return ERR_PTR(err); @@ -335,12 +340,14 @@ void komeda_kms_detach(struct komeda_kms_dev *kms) struct drm_device *drm = &kms->base; struct komeda_dev *mdev = drm->dev_private; + drm_dev_unregister(drm); + drm_kms_helper_poll_fini(drm); + drm_atomic_helper_shutdown(drm); drm->irq_enabled = false; mdev->funcs->disable_irq(mdev); - drm_dev_unregister(drm); component_unbind_all(mdev->dev, drm); - komeda_kms_cleanup_private_objs(kms); drm_mode_config_cleanup(drm); + komeda_kms_cleanup_private_objs(kms); drm->dev_private = NULL; drm_dev_put(drm); } diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h index 8c89fc245b83..45c498e15e7a 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_kms.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_kms.h @@ -14,8 +14,6 @@ #include <drm/drm_device.h> #include <drm/drm_writeback.h> #include <drm/drm_print.h> -#include <video/videomode.h> -#include <video/display_timing.h> /** * struct komeda_plane - komeda instance of drm_plane @@ -168,7 +166,7 @@ static inline bool has_flip_h(u32 rot) return !!(rotation & DRM_MODE_REFLECT_X); } -unsigned long komeda_calc_aclk(struct komeda_crtc_state *kcrtc_st); +unsigned long komeda_crtc_get_aclk(struct komeda_crtc_state *kcrtc_st); int komeda_kms_setup_crtcs(struct komeda_kms_dev *kms, struct komeda_dev *mdev); diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c index 78e44d9e1520..452e505a1fd3 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.c @@ -54,7 +54,8 @@ void komeda_pipeline_destroy(struct komeda_dev *mdev, clk_put(pipe->pxlclk); - of_node_put(pipe->of_output_dev); + of_node_put(pipe->of_output_links[0]); + of_node_put(pipe->of_output_links[1]); of_node_put(pipe->of_output_port); of_node_put(pipe->of_node); @@ -246,9 +247,15 @@ static void komeda_pipeline_dump(struct komeda_pipeline *pipe) struct komeda_component *c; int id; - DRM_INFO("Pipeline-%d: n_layers: %d, n_scalers: %d, output: %s\n", + DRM_INFO("Pipeline-%d: n_layers: %d, n_scalers: %d, output: %s.\n", pipe->id, pipe->n_layers, pipe->n_scalers, - pipe->of_output_dev ? pipe->of_output_dev->full_name : "none"); + pipe->dual_link ? "dual-link" : "single-link"); + DRM_INFO(" output_link[0]: %s.\n", + pipe->of_output_links[0] ? + pipe->of_output_links[0]->full_name : "none"); + DRM_INFO(" output_link[1]: %s.\n", + pipe->of_output_links[1] ? + pipe->of_output_links[1]->full_name : "none"); dp_for_each_set_bit(id, pipe->avail_comps) { c = komeda_pipeline_get_component(pipe, id); @@ -305,6 +312,12 @@ static void komeda_pipeline_assemble(struct komeda_pipeline *pipe) layer->right = komeda_get_layer_split_right_layer(pipe, layer); } + + if (pipe->dual_link && !pipe->ctrlr->supports_dual_link) { + pipe->dual_link = false; + DRM_WARN("PIPE-%d doesn't support dual-link, ignore DT dual-link configuration.\n", + pipe->id); + } } /* if pipeline_A accept another pipeline_B's component as input, treat diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h index a90bcbb3cb23..cf5bea578ad9 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h @@ -416,8 +416,10 @@ struct komeda_pipeline { struct device_node *of_node; /** @of_output_port: pipeline output port */ struct device_node *of_output_port; - /** @of_output_dev: output connector device node */ - struct device_node *of_output_dev; + /** @of_output_links: output connector device nodes */ + struct device_node *of_output_links[2]; + /** @dual_link: true if of_output_links[0] and [1] are both valid */ + bool dual_link; }; /** @@ -480,6 +482,7 @@ void komeda_pipeline_dump_register(struct komeda_pipeline *pipe, struct seq_file *sf); /* component APIs */ +extern __printf(10, 11) struct komeda_component * komeda_component_add(struct komeda_pipeline *pipe, size_t comp_sz, u32 id, u32 hw_id, diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c index 950235af1e79..ea26bc9c2d00 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c @@ -473,7 +473,7 @@ komeda_scaler_check_cfg(struct komeda_scaler *scaler, err = pipe->funcs->downscaling_clk_check(pipe, &kcrtc_st->base.adjusted_mode, - komeda_calc_aclk(kcrtc_st), dflow); + komeda_crtc_get_aclk(kcrtc_st), dflow); if (err) { DRM_DEBUG_ATOMIC("aclk can't satisfy the clock requirement of the downscaling\n"); return err; diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c index c095af154216..98e915e325dd 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c @@ -158,7 +158,7 @@ static void komeda_plane_reset(struct drm_plane *plane) static struct drm_plane_state * komeda_plane_atomic_duplicate_state(struct drm_plane *plane) { - struct komeda_plane_state *new, *old; + struct komeda_plane_state *new; if (WARN_ON(!plane->state)) return NULL; @@ -169,8 +169,6 @@ komeda_plane_atomic_duplicate_state(struct drm_plane *plane) __drm_atomic_helper_plane_duplicate_state(plane, &new->base); - old = to_kplane_st(plane->state); - return &new->base; } diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c index 617e1f7b8472..2851cac94d86 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c @@ -148,7 +148,7 @@ static int komeda_wb_connector_add(struct komeda_kms_dev *kms, if (!kcrtc->master->wb_layer) return 0; - kwb_conn = kzalloc(sizeof(*wb_conn), GFP_KERNEL); + kwb_conn = kzalloc(sizeof(*kwb_conn), GFP_KERNEL); if (!kwb_conn) return -ENOMEM; diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c index a3efa28436ea..af67fefed38d 100644 --- a/drivers/gpu/drm/arm/hdlcd_crtc.c +++ b/drivers/gpu/drm/arm/hdlcd_crtc.c @@ -9,7 +9,12 @@ * Implementation of a CRTC class for the HDLCD driver. */ -#include <drm/drmP.h> +#include <linux/clk.h> +#include <linux/of_graph.h> +#include <linux/platform_data/simplefb.h> + +#include <video/videomode.h> + #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> @@ -19,10 +24,7 @@ #include <drm/drm_of.h> #include <drm/drm_plane_helper.h> #include <drm/drm_probe_helper.h> -#include <linux/clk.h> -#include <linux/of_graph.h> -#include <linux/platform_data/simplefb.h> -#include <video/videomode.h> +#include <drm/drm_vblank.h> #include "hdlcd_drv.h" #include "hdlcd_regs.h" diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c index 8fc0b884c428..2e053815b54a 100644 --- a/drivers/gpu/drm/arm/hdlcd_drv.c +++ b/drivers/gpu/drm/arm/hdlcd_drv.c @@ -14,21 +14,26 @@ #include <linux/clk.h> #include <linux/component.h> #include <linux/console.h> +#include <linux/dma-mapping.h> #include <linux/list.h> #include <linux/of_graph.h> #include <linux/of_reserved_mem.h> +#include <linux/platform_device.h> #include <linux/pm_runtime.h> -#include <drm/drmP.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> +#include <drm/drm_debugfs.h> +#include <drm/drm_drv.h> #include <drm/drm_fb_cma_helper.h> #include <drm/drm_fb_helper.h> #include <drm/drm_gem_cma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> +#include <drm/drm_irq.h> #include <drm/drm_modeset_helper.h> #include <drm/drm_of.h> #include <drm/drm_probe_helper.h> +#include <drm/drm_vblank.h> #include "hdlcd_drv.h" #include "hdlcd_regs.h" @@ -229,9 +234,7 @@ static int hdlcd_debugfs_init(struct drm_minor *minor) DEFINE_DRM_GEM_CMA_FOPS(fops); static struct drm_driver hdlcd_driver = { - .driver_features = DRIVER_GEM | - DRIVER_MODESET | DRIVER_PRIME | - DRIVER_ATOMIC, + .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .irq_handler = hdlcd_irq, .irq_preinstall = hdlcd_irq_preinstall, .irq_postinstall = hdlcd_irq_postinstall, @@ -242,8 +245,6 @@ static struct drm_driver hdlcd_driver = { .dumb_create = drm_gem_cma_dumb_create, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_export = drm_gem_prime_export, - .gem_prime_import = drm_gem_prime_import, .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, .gem_prime_vmap = drm_gem_cma_prime_vmap, diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c index db4451260fff..587d94798f5c 100644 --- a/drivers/gpu/drm/arm/malidp_crtc.c +++ b/drivers/gpu/drm/arm/malidp_crtc.c @@ -6,14 +6,17 @@ * ARM Mali DP500/DP550/DP650 driver (crtc operations) */ -#include <drm/drmP.h> +#include <linux/clk.h> +#include <linux/pm_runtime.h> + +#include <video/videomode.h> + #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> +#include <drm/drm_print.h> #include <drm/drm_probe_helper.h> -#include <linux/clk.h> -#include <linux/pm_runtime.h> -#include <video/videomode.h> +#include <drm/drm_vblank.h> #include "malidp_drv.h" #include "malidp_hw.h" diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c index f25ec4382277..333b88a5efb0 100644 --- a/drivers/gpu/drm/arm/malidp_drv.c +++ b/drivers/gpu/drm/arm/malidp_drv.c @@ -15,17 +15,19 @@ #include <linux/pm_runtime.h> #include <linux/debugfs.h> -#include <drm/drmP.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> -#include <drm/drm_probe_helper.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_drv.h> #include <drm/drm_fb_cma_helper.h> +#include <drm/drm_fb_helper.h> +#include <drm/drm_fourcc.h> #include <drm/drm_gem_cma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_modeset_helper.h> #include <drm/drm_of.h> +#include <drm/drm_probe_helper.h> +#include <drm/drm_vblank.h> #include "malidp_drv.h" #include "malidp_mw.h" @@ -561,15 +563,12 @@ static int malidp_debugfs_init(struct drm_minor *minor) #endif //CONFIG_DEBUG_FS static struct drm_driver malidp_driver = { - .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC | - DRIVER_PRIME, + .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .gem_free_object_unlocked = drm_gem_cma_free_object, .gem_vm_ops = &drm_gem_cma_vm_ops, .dumb_create = malidp_dumb_create, .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_export = drm_gem_prime_export, - .gem_prime_import = drm_gem_prime_import, .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table, .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table, .gem_prime_vmap = drm_gem_cma_prime_vmap, diff --git a/drivers/gpu/drm/arm/malidp_drv.h b/drivers/gpu/drm/arm/malidp_drv.h index 0a639af8337e..cdfddfabf2d1 100644 --- a/drivers/gpu/drm/arm/malidp_drv.h +++ b/drivers/gpu/drm/arm/malidp_drv.h @@ -9,12 +9,13 @@ #ifndef __MALIDP_DRV_H__ #define __MALIDP_DRV_H__ -#include <drm/drm_writeback.h> -#include <drm/drm_encoder.h> #include <linux/mutex.h> #include <linux/wait.h> #include <linux/spinlock.h> -#include <drm/drmP.h> + +#include <drm/drm_writeback.h> +#include <drm/drm_encoder.h> + #include "malidp_hw.h" #define MALIDP_CONFIG_VALID_INIT 0 diff --git a/drivers/gpu/drm/arm/malidp_hw.c b/drivers/gpu/drm/arm/malidp_hw.c index 50af399d7f6f..bd8265f02e0b 100644 --- a/drivers/gpu/drm/arm/malidp_hw.c +++ b/drivers/gpu/drm/arm/malidp_hw.c @@ -9,12 +9,17 @@ */ #include <linux/clk.h> +#include <linux/delay.h> #include <linux/types.h> #include <linux/io.h> -#include <drm/drmP.h> + #include <video/videomode.h> #include <video/display_timing.h> +#include <drm/drm_fourcc.h> +#include <drm/drm_vblank.h> +#include <drm/drm_print.h> + #include "malidp_drv.h" #include "malidp_hw.h" #include "malidp_mw.h" @@ -385,6 +390,7 @@ int malidp_format_get_bpp(u32 fmt) switch (fmt) { case DRM_FORMAT_VUY101010: bpp = 30; + break; case DRM_FORMAT_YUV420_10BIT: bpp = 15; break; @@ -1309,7 +1315,7 @@ static irqreturn_t malidp_se_irq(int irq, void *arg) break; case MW_RESTART: drm_writeback_signal_completion(&malidp->mw_connector, 0); - /* fall through to a new start */ + /* fall through - to a new start */ case MW_START: /* writeback started, need to emulate one-shot mode */ hw->disable_memwrite(hwdev); diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c index 2e812525025d..22c0847986df 100644 --- a/drivers/gpu/drm/arm/malidp_mw.c +++ b/drivers/gpu/drm/arm/malidp_mw.c @@ -5,13 +5,14 @@ * * ARM Mali DP Writeback connector implementation */ + #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> -#include <drm/drm_probe_helper.h> #include <drm/drm_fb_cma_helper.h> +#include <drm/drm_fourcc.h> #include <drm/drm_gem_cma_helper.h> -#include <drm/drmP.h> +#include <drm/drm_probe_helper.h> #include <drm/drm_writeback.h> #include "malidp_drv.h" diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index 488375bd133d..3c70a53813bf 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -7,11 +7,13 @@ */ #include <linux/iommu.h> +#include <linux/platform_device.h> -#include <drm/drmP.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> +#include <drm/drm_drv.h> #include <drm/drm_fb_cma_helper.h> +#include <drm/drm_fourcc.h> #include <drm/drm_gem_cma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_plane_helper.h> |