Mateusz Kwiatkowski
2022-Oct-16 18:52 UTC
[Nouveau] [PATCH v5 20/22] drm/vc4: vec: Convert to the new TV mode property
Hi Maxime,> static int vc4_vec_connector_get_modes(struct drm_connector *connector) > { > - struct drm_connector_state *state = connector->state; > struct drm_display_mode *mode; > > - mode = drm_mode_duplicate(connector->dev, > - vc4_vec_tv_modes[state->tv.legacy_mode].mode); > + mode = drm_mode_analog_ntsc_480i(connector->dev); > if (!mode) { > DRM_ERROR("Failed to create a new display mode\n"); > return -ENOMEM; > } > > + mode->type |= DRM_MODE_TYPE_PREFERRED; > drm_mode_probed_add(connector, mode); > > - return 1; > + mode = drm_mode_analog_pal_576i(connector->dev); > + if (!mode) { > + DRM_ERROR("Failed to create a new display mode\n"); > + return -ENOMEM; > + } > + > + drm_mode_probed_add(connector, mode); > + > + return 2; > +}Referencing those previous discussions: - https://lore.kernel.org/dri-devel/0255f7c6-0484-6456-350d-cf24f3fee5d6 at tronnes.org/ - https://lore.kernel.org/dri-devel/c8f8015a-75da-afa8-ca7f-b2b134cacd16 at gmail.com/ Unconditionally setting the 480i mode as DRM_MODE_TYPE_PREFERRED causes Xorg (at least on current Raspberry Pi OS) to display garbage when video=Composite1:PAL is specified on the command line, so I'm afraid this won't do. As I see it, there are three viable solutions for this issue: a) Somehow query the video= command line option from this function, and set DRM_MODE_TYPE_PREFERRED appropriately. This would break the abstraction provided by global DRM code, but should work fine. b) Modify drm_helper_probe_add_cmdline_mode() so that it sets DRM_MODE_TYPE_PREFERRED in addition to DRM_MODE_TYPE_USERDEF. This seems pretty robust, but affects the entire DRM subsystem, which may break userspace in different ways. - Maybe this could be mitigated by adding some additional conditions, e.g. setting the PREFERRED flag only if no modes are already flagged as such and/or only if the cmdline mode is a named one (~= analog TV mode) c) Forcing userspace (Xorg / Raspberry Pi OS) to get fixed and honor the USERDEF flag. Either way, hardcoding 480i as PREFERRED does not seem right. Note: this also applies to the sun4i version (patch 22/22).> @@ -366,13 +472,16 @@ static void vc4_vec_encoder_enable(struct drm_encoder *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.legacy_mode]; > + const struct vc4_vec_tv_mode *tv_mode; > int idx, ret; > > if (!drm_dev_enter(drm, &idx)) > return; > > + tv_mode = vc4_vec_tv_mode_lookup(conn_state->tv.mode); > + if (!tv_mode) > + goto err_dev_exit; > + > ret = pm_runtime_get_sync(&vec->pdev->dev); > if (ret < 0) { > DRM_ERROR("Failed to retain power domain: %d\n", ret);If this (!tv_mode) condition is somehow triggered, the power management goes somewhat crazy. vc4_vec_encoder_enable() cannot return an error, so when vc4_vec_encoder_disable() is eventually called after a failed enable, it hangs in pm_runtime_put() for quite a bit. At least I think that's what's happening. Anyway, to solve this, I'd propose this thing below: Best regards, Mateusz Kwiatkowski
Mateusz Kwiatkowski
2022-Oct-16 18:56 UTC
[Nouveau] [PATCH v5 20/22] drm/vc4: vec: Convert to the new TV mode property
Hi Maxime, Urgh. I cannot send e-mails apparently today, as I removed the second half of the previous message. Here goes:> @@ -454,13 +563,6 @@ static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder, > struct drm_connector_state *conn_state) > { > const struct drm_display_mode *mode = &crtc_state->adjusted_mode;You could add here something like: + const struct vc4_vec_tv_mode *tv_mode + vc4_vec_tv_mode_lookup(conn_state->tv.mode); + + if (!tv_mode) + return -EINVAL; This should explicitly make it impossible to enter the equivalent condition in vc4_vec_encoder_enable() that causes the problem mentioned in the previous e-mail. This is probably basically impossible already, but I triggered that when testing a follow-up change I'd like to post shortly.> - const struct vc4_vec_tv_mode *vec_mode; > - > - vec_mode = &vc4_vec_tv_modes[conn_state->tv.legacy_mode]; > - > - if (conn_state->crtc && > - !drm_mode_equal(vec_mode->mode, &crtc_state->adjusted_mode)) > - return -EINVAL;If you're removing the reference mode, then I think you should at least add checks that the crtc_clock is set to 13.5 MHz (it's otherwise ignored) and that crtc_htotal is either 858 or 864 (using a switch over reference_mode->htotal as I proposed in my comment to patch 19/22 would double as such check), as all other values causes VEC to output garbage. Best regards, Mateusz Kwiatkowski
Noralf Trønnes
2022-Oct-17 10:31 UTC
[Nouveau] [PATCH v5 20/22] drm/vc4: vec: Convert to the new TV mode property
Den 16.10.2022 20.52, skrev Mateusz Kwiatkowski:> Hi Maxime, > >> static int vc4_vec_connector_get_modes(struct drm_connector *connector) >> { >> - struct drm_connector_state *state = connector->state; >> struct drm_display_mode *mode; >> >> - mode = drm_mode_duplicate(connector->dev, >> - vc4_vec_tv_modes[state->tv.legacy_mode].mode); >> + mode = drm_mode_analog_ntsc_480i(connector->dev); >> if (!mode) { >> DRM_ERROR("Failed to create a new display mode\n"); >> return -ENOMEM; >> } >> >> + mode->type |= DRM_MODE_TYPE_PREFERRED; >> drm_mode_probed_add(connector, mode); >> >> - return 1; >> + mode = drm_mode_analog_pal_576i(connector->dev); >> + if (!mode) { >> + DRM_ERROR("Failed to create a new display mode\n"); >> + return -ENOMEM; >> + } >> + >> + drm_mode_probed_add(connector, mode); >> + >> + return 2; >> +} > > Referencing those previous discussions: > - https://lore.kernel.org/dri-devel/0255f7c6-0484-6456-350d-cf24f3fee5d6 at tronnes.org/ > - https://lore.kernel.org/dri-devel/c8f8015a-75da-afa8-ca7f-b2b134cacd16 at gmail.com/ > > Unconditionally setting the 480i mode as DRM_MODE_TYPE_PREFERRED causes Xorg > (at least on current Raspberry Pi OS) to display garbage when > video=Composite1:PAL is specified on the command line, so I'm afraid this won't > do. > > As I see it, there are three viable solutions for this issue: > > a) Somehow query the video= command line option from this function, and set > DRM_MODE_TYPE_PREFERRED appropriately. This would break the abstraction > provided by global DRM code, but should work fine. > > b) Modify drm_helper_probe_add_cmdline_mode() so that it sets > DRM_MODE_TYPE_PREFERRED in addition to DRM_MODE_TYPE_USERDEF. This seems > pretty robust, but affects the entire DRM subsystem, which may break > userspace in different ways. > > - Maybe this could be mitigated by adding some additional conditions, e.g. > setting the PREFERRED flag only if no modes are already flagged as such > and/or only if the cmdline mode is a named one (~= analog TV mode) > > c) Forcing userspace (Xorg / Raspberry Pi OS) to get fixed and honor the USERDEF > flag. > > Either way, hardcoding 480i as PREFERRED does not seem right. >My solution for this is to look at tv.mode to know which mode to mark as preferred. Maxime didn't like this since it changes things behind userspace's back. I don't see how that can cause any problems for userspace. If userspace uses atomic and sets tv_mode, it has to know which mode to use before hand, so it doesn't look at the preferreded flag. If it uses legacy and sets tv_mode, it can end up with a stale preferred flag, but no worse than not having the flag or that ntsc is always preferred. If it doesn't change tv_mode, there's no problem, the preferred flag doesn't change. Noralf.