diff options
author | Dave Airlie <airlied@redhat.com> | 2022-09-11 14:46:57 +0300 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2022-09-11 15:03:07 +0300 |
commit | fb34d8a04e5876552cd0d4f9e14400ee13f116fb (patch) | |
tree | 4bdd1c43f67c6c013d2b08b11cecfd576fa1fa4b /drivers/gpu/drm/vc4 | |
parent | 8284bae723f025cb6a8431566757a3854a3c53eb (diff) | |
parent | 5d832b6694e094b176627ed9918a1b21c56fb742 (diff) | |
download | linux-fb34d8a04e5876552cd0d4f9e14400ee13f116fb.tar.xz |
Merge tag 'drm-misc-next-2022-09-09' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v6.1-rc1:
[airlied - fix sun4i_tv build]
UAPI Changes:
- Hide unregistered connectors from GETCONNECTOR ioctl.
- drm/virtio no longer advertises LINEAR modifier, as it doesn't work.
-
Cross-subsystem Changes:
- Fix GPF in udmabuf failure path.
Core Changes:
- Rework TTM placement to use intersect/compatible functions.
- Drop legacy DP-MST support.
- More DP-MST related fixes, and move all state into atomic.
- Make DRM_MIPI_DBI select DRM_KMS_HELPER.
- Add audio_infoframe packing for DP.
- Add logging when some atomic check functions fail.
- Assorted documentation updates and fixes.
Driver Changes:
- Assorted cleanups and fixes in msm, lcdif, nouveau, virtio,
panel/ilitek, bridge/icn6211, tve200, gma500, bridge/*, panfrost, via,
bochs, qxl, sun4i.
- Add add AUO B133UAN02.1, IVO M133NW4J-R3, Innolux N120ACA-EA1 eDP panels.
- Improve DP-MST modeset state handling in amdgpu, nouveau, i915.
- Drop DP-MST from radeon driver, it was broken and only user of legacy
DP-MST.
- Handle unplugging better in vc4.
- Simplify drm cmdparser tests.
- Add DP support to ti-sn65dsi86.
- Add MT8195 DP support to mediatek.
- Support RGB565, XRGB64, and ARGB64 formats in vkms.
- Convert sun4i tv support to atomic.
- Refactor vc4/vec TV Modesetting, and fix timings.
- Use atomic helpers instead of simple display helpers in ssd130x.
Maintainer changes:
- Add Douglas Anderson as reviewer for panel-edp.
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/a489485b-3ebc-c734-0f80-aed963d89efe@linux.intel.com
Diffstat (limited to 'drivers/gpu/drm/vc4')
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_crtc.c | 41 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_hdmi.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_hvs.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_plane.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_vec.c | 127 |
5 files changed, 101 insertions, 98 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 2def6e2ad6f0..0108613e79d5 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -39,6 +39,7 @@ #include <drm/drm_atomic_uapi.h> #include <drm/drm_fb_dma_helper.h> #include <drm/drm_framebuffer.h> +#include <drm/drm_drv.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> #include <drm/drm_vblank.h> @@ -295,10 +296,17 @@ struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc, static void vc4_crtc_pixelvalve_reset(struct drm_crtc *crtc) { struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); + struct drm_device *dev = crtc->dev; + int idx; + + if (!drm_dev_enter(dev, &idx)) + return; /* The PV needs to be disabled before it can be flushed */ CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) & ~PV_CONTROL_EN); CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_FIFO_CLR); + + drm_dev_exit(idx); } static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encoder, @@ -321,6 +329,10 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode u32 format = is_dsi1 ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24; u8 ppc = pv_data->pixels_per_clock; bool debug_dump_regs = false; + int idx; + + if (!drm_dev_enter(dev, &idx)) + return; if (debug_dump_regs) { struct drm_printer p = drm_info_printer(&vc4_crtc->pdev->dev); @@ -410,6 +422,8 @@ static void vc4_crtc_config_pv(struct drm_crtc *crtc, struct drm_encoder *encode drm_crtc_index(crtc)); drm_print_regset32(&p, &vc4_crtc->regset); } + + drm_dev_exit(idx); } static void require_hvs_enabled(struct drm_device *dev) @@ -430,7 +444,10 @@ static int vc4_crtc_disable(struct drm_crtc *crtc, struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); struct drm_device *dev = crtc->dev; struct vc4_dev *vc4 = to_vc4_dev(dev); - int ret; + int idx, ret; + + if (!drm_dev_enter(dev, &idx)) + return -ENODEV; CRTC_WRITE(PV_V_CONTROL, CRTC_READ(PV_V_CONTROL) & ~PV_VCONTROL_VIDEN); @@ -464,6 +481,8 @@ static int vc4_crtc_disable(struct drm_crtc *crtc, if (vc4_encoder && vc4_encoder->post_crtc_powerdown) vc4_encoder->post_crtc_powerdown(encoder, state); + drm_dev_exit(idx); + return 0; } @@ -588,10 +607,14 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc, struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc, new_state); struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); + int idx; drm_dbg(dev, "Enabling CRTC %s (%u) connected to Encoder %s (%u)", crtc->name, crtc->base.id, encoder->name, encoder->base.id); + if (!drm_dev_enter(dev, &idx)) + return; + require_hvs_enabled(dev); /* Enable vblank irq handling before crtc is started otherwise @@ -619,6 +642,8 @@ static void vc4_crtc_atomic_enable(struct drm_crtc *crtc, if (vc4_encoder->post_crtc_enable) vc4_encoder->post_crtc_enable(encoder, state); + + drm_dev_exit(idx); } static enum drm_mode_status vc4_crtc_mode_valid(struct drm_crtc *crtc, @@ -711,17 +736,31 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc, static int vc4_enable_vblank(struct drm_crtc *crtc) { struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); + struct drm_device *dev = crtc->dev; + int idx; + + if (!drm_dev_enter(dev, &idx)) + return -ENODEV; CRTC_WRITE(PV_INTEN, PV_INT_VFP_START); + drm_dev_exit(idx); + return 0; } static void vc4_disable_vblank(struct drm_crtc *crtc) { struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); + struct drm_device *dev = crtc->dev; + int idx; + + if (!drm_dev_enter(dev, &idx)) + return; CRTC_WRITE(PV_INTEN, 0); + + drm_dev_exit(idx); } static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc) diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index fda450185c36..25299fbc083b 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -1425,7 +1425,7 @@ static void vc4_hdmi_encoder_pre_crtc_enable(struct drm_encoder *encoder, mutex_lock(&vc4_hdmi->mutex); if (!drm_dev_enter(drm, &idx)) - return; + goto out; if (vc4_hdmi->variant->csc_setup) vc4_hdmi->variant->csc_setup(vc4_hdmi, conn_state, mode); @@ -1436,6 +1436,7 @@ static void vc4_hdmi_encoder_pre_crtc_enable(struct drm_encoder *encoder, drm_dev_exit(idx); +out: mutex_unlock(&vc4_hdmi->mutex); } @@ -1455,7 +1456,7 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder, mutex_lock(&vc4_hdmi->mutex); if (!drm_dev_enter(drm, &idx)) - return; + goto out; spin_lock_irqsave(&vc4_hdmi->hw_lock, flags); @@ -1516,6 +1517,8 @@ static void vc4_hdmi_encoder_post_crtc_enable(struct drm_encoder *encoder, vc4_hdmi_enable_scrambling(encoder); drm_dev_exit(idx); + +out: mutex_unlock(&vc4_hdmi->mutex); } diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 9e823e0de197..4ac9f5a2d5f9 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -71,11 +71,11 @@ void vc4_hvs_dump_state(struct vc4_hvs *hvs) struct drm_printer p = drm_info_printer(&hvs->pdev->dev); int idx, i; - drm_print_regset32(&p, &hvs->regset); - if (!drm_dev_enter(drm, &idx)) return; + drm_print_regset32(&p, &hvs->regset); + DRM_INFO("HVS ctx:\n"); for (i = 0; i < 64; i += 4) { DRM_INFO("0x%08x (%s): 0x%08x 0x%08x 0x%08x 0x%08x\n", diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index eff9c63adfa7..8b92a45a3c89 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -19,6 +19,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_uapi.h> #include <drm/drm_blend.h> +#include <drm/drm_drv.h> #include <drm/drm_fb_dma_helper.h> #include <drm/drm_fourcc.h> #include <drm/drm_framebuffer.h> @@ -1219,6 +1220,10 @@ u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist) { struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state); int i; + int idx; + + if (!drm_dev_enter(plane->dev, &idx)) + goto out; vc4_state->hw_dlist = dlist; @@ -1226,6 +1231,9 @@ u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist) for (i = 0; i < vc4_state->dlist_count; i++) writel(vc4_state->dlist[i], &dlist[i]); + drm_dev_exit(idx); + +out: return vc4_state->dlist_count; } @@ -1245,6 +1253,10 @@ void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb) struct vc4_plane_state *vc4_state = to_vc4_plane_state(plane->state); struct drm_gem_dma_object *bo = drm_fb_dma_get_gem_obj(fb, 0); uint32_t addr; + int idx; + + if (!drm_dev_enter(plane->dev, &idx)) + return; /* We're skipping the address adjustment for negative origin, * because this is only called on the primary plane. @@ -1263,6 +1275,8 @@ void vc4_plane_async_set_fb(struct drm_plane *plane, struct drm_framebuffer *fb) * also use our updated address. */ vc4_state->dlist[vc4_state->ptr0_offset] = addr; + + drm_dev_exit(idx); } static void vc4_plane_atomic_async_update(struct drm_plane *plane, @@ -1271,6 +1285,10 @@ static void vc4_plane_atomic_async_update(struct drm_plane *plane, struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); struct vc4_plane_state *vc4_state, *new_vc4_state; + int idx; + + if (!drm_dev_enter(plane->dev, &idx)) + return; swap(plane->state->fb, new_plane_state->fb); plane->state->crtc_x = new_plane_state->crtc_x; @@ -1333,6 +1351,8 @@ static void vc4_plane_atomic_async_update(struct drm_plane *plane, &vc4_state->hw_dlist[vc4_state->pos2_offset]); writel(vc4_state->dlist[vc4_state->ptr0_offset], &vc4_state->hw_dlist[vc4_state->ptr0_offset]); + + drm_dev_exit(idx); } static int vc4_plane_atomic_async_check(struct drm_plane *plane, diff --git a/drivers/gpu/drm/vc4/vc4_vec.c b/drivers/gpu/drm/vc4/vc4_vec.c index 4a788c1c9058..0b3333865702 100644 --- a/drivers/gpu/drm/vc4/vc4_vec.c +++ b/drivers/gpu/drm/vc4/vc4_vec.c @@ -171,8 +171,6 @@ struct vc4_vec { struct clk *clock; - const struct vc4_vec_tv_mode *tv_mode; - struct debugfs_regset32 regset; }; @@ -194,7 +192,9 @@ enum vc4_vec_tv_mode_id { struct vc4_vec_tv_mode { const struct drm_display_mode *mode; - void (*mode_set)(struct vc4_vec *vec); + u32 config0; + u32 config1; + u32 custom_freq; }; static const struct debugfs_reg32 vec_regs[] = { @@ -224,95 +224,41 @@ static const struct debugfs_reg32 vec_regs[] = { VC4_REG32(VEC_DAC_MISC), }; -static void vc4_vec_ntsc_mode_set(struct vc4_vec *vec) -{ - struct drm_device *drm = vec->connector.dev; - int idx; - - if (!drm_dev_enter(drm, &idx)) - return; - - VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN); - VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS); - - drm_dev_exit(idx); -} - -static void vc4_vec_ntsc_j_mode_set(struct vc4_vec *vec) -{ - struct drm_device *drm = vec->connector.dev; - int idx; - - if (!drm_dev_enter(drm, &idx)) - return; - - VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_NTSC_STD); - VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS); - - drm_dev_exit(idx); -} - static const struct drm_display_mode ntsc_mode = { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500, 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0, - 480, 480 + 3, 480 + 3 + 3, 480 + 3 + 3 + 16, 0, + 480, 480 + 7, 480 + 7 + 6, 525, 0, DRM_MODE_FLAG_INTERLACE) }; -static void vc4_vec_pal_mode_set(struct vc4_vec *vec) -{ - struct drm_device *drm = vec->connector.dev; - int idx; - - if (!drm_dev_enter(drm, &idx)) - return; - - VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_PAL_BDGHI_STD); - VEC_WRITE(VEC_CONFIG1, VEC_CONFIG1_C_CVBS_CVBS); - - drm_dev_exit(idx); -} - -static void vc4_vec_pal_m_mode_set(struct vc4_vec *vec) -{ - struct drm_device *drm = vec->connector.dev; - int idx; - - if (!drm_dev_enter(drm, &idx)) - return; - - VEC_WRITE(VEC_CONFIG0, VEC_CONFIG0_PAL_BDGHI_STD); - VEC_WRITE(VEC_CONFIG1, - VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ); - VEC_WRITE(VEC_FREQ3_2, 0x223b); - VEC_WRITE(VEC_FREQ1_0, 0x61d1); - - drm_dev_exit(idx); -} - static const struct drm_display_mode pal_mode = { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500, 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0, - 576, 576 + 2, 576 + 2 + 3, 576 + 2 + 3 + 20, 0, + 576, 576 + 4, 576 + 4 + 6, 625, 0, DRM_MODE_FLAG_INTERLACE) }; static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = { [VC4_VEC_TV_MODE_NTSC] = { .mode = &ntsc_mode, - .mode_set = vc4_vec_ntsc_mode_set, + .config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN, + .config1 = VEC_CONFIG1_C_CVBS_CVBS, }, [VC4_VEC_TV_MODE_NTSC_J] = { .mode = &ntsc_mode, - .mode_set = vc4_vec_ntsc_j_mode_set, + .config0 = VEC_CONFIG0_NTSC_STD, + .config1 = VEC_CONFIG1_C_CVBS_CVBS, }, [VC4_VEC_TV_MODE_PAL] = { .mode = &pal_mode, - .mode_set = vc4_vec_pal_mode_set, + .config0 = VEC_CONFIG0_PAL_BDGHI_STD, + .config1 = VEC_CONFIG1_C_CVBS_CVBS, }, [VC4_VEC_TV_MODE_PAL_M] = { .mode = &pal_mode, - .mode_set = vc4_vec_pal_m_mode_set, + .config0 = VEC_CONFIG0_PAL_BDGHI_STD, + .config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ, + .custom_freq = 0x223b61d1, }, }; @@ -368,14 +314,14 @@ static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec) drm_object_attach_property(&connector->base, dev->mode_config.tv_mode_property, VC4_VEC_TV_MODE_NTSC); - vec->tv_mode = &vc4_vec_tv_modes[VC4_VEC_TV_MODE_NTSC]; drm_connector_attach_encoder(connector, &vec->encoder.base); return 0; } -static void vc4_vec_encoder_disable(struct drm_encoder *encoder) +static void vc4_vec_encoder_disable(struct drm_encoder *encoder, + struct drm_atomic_state *state) { struct drm_device *drm = encoder->dev; struct vc4_vec *vec = encoder_to_vc4_vec(encoder); @@ -406,10 +352,16 @@ err_dev_exit: drm_dev_exit(idx); } -static void vc4_vec_encoder_enable(struct drm_encoder *encoder) +static void vc4_vec_encoder_enable(struct drm_encoder *encoder, + struct drm_atomic_state *state) { struct drm_device *drm = encoder->dev; struct vc4_vec *vec = encoder_to_vc4_vec(encoder); + struct drm_connector *connector = &vec->connector; + struct drm_connector_state *conn_state = + drm_atomic_get_new_connector_state(state, connector); + const struct vc4_vec_tv_mode *tv_mode = + &vc4_vec_tv_modes[conn_state->tv.mode]; int idx, ret; if (!drm_dev_enter(drm, &idx)) @@ -468,7 +420,15 @@ static void vc4_vec_encoder_enable(struct drm_encoder *encoder) /* Mask all interrupts. */ VEC_WRITE(VEC_MASK0, 0); - vec->tv_mode->mode_set(vec); + VEC_WRITE(VEC_CONFIG0, tv_mode->config0); + VEC_WRITE(VEC_CONFIG1, tv_mode->config1); + + if (tv_mode->custom_freq) { + VEC_WRITE(VEC_FREQ3_2, + (tv_mode->custom_freq >> 16) & 0xffff); + VEC_WRITE(VEC_FREQ1_0, + tv_mode->custom_freq & 0xffff); + } VEC_WRITE(VEC_DAC_MISC, VEC_DAC_MISC_VID_ACT | VEC_DAC_MISC_DAC_RST_N); @@ -483,23 +443,6 @@ err_dev_exit: drm_dev_exit(idx); } - -static bool vc4_vec_encoder_mode_fixup(struct drm_encoder *encoder, - const struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) -{ - return true; -} - -static void vc4_vec_encoder_atomic_mode_set(struct drm_encoder *encoder, - struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state) -{ - struct vc4_vec *vec = encoder_to_vc4_vec(encoder); - - vec->tv_mode = &vc4_vec_tv_modes[conn_state->tv.mode]; -} - static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) @@ -516,11 +459,9 @@ static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder, } static const struct drm_encoder_helper_funcs vc4_vec_encoder_helper_funcs = { - .disable = vc4_vec_encoder_disable, - .enable = vc4_vec_encoder_enable, - .mode_fixup = vc4_vec_encoder_mode_fixup, .atomic_check = vc4_vec_encoder_atomic_check, - .atomic_mode_set = vc4_vec_encoder_atomic_mode_set, + .atomic_disable = vc4_vec_encoder_disable, + .atomic_enable = vc4_vec_encoder_enable, }; static int vc4_vec_late_register(struct drm_encoder *encoder) |