Message ID | 20220728-rpi-analog-tv-properties-v1-14-3d53ae722097@cerno.tech (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm: Analog TV Improvements | expand |
Hi Maxime, I'm pretty sure that PAL-60 and SECAM-60 should be tied to the 480i mode. Those are non-standard "norms" that use 60 Hz sync (which is largely synonymous with 480i in the analog TV world) with PAL/SECAM color encoding. Best regards, Mateusz Kwiatkowski W dniu 29.07.2022 o 18:34, Maxime Ripard pisze: > The analog TV connector drivers share some atomic_check logic, and the new > TV standard property have created a bunch of new constraints that needs to > be shared across drivers too. > > Let's create an atomic_check helper for those use cases. > > Signed-off-by: Maxime Ripard <maxime@cerno.tech> > > diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c > index 6d14cb0c64b1..fce5569bd66a 100644 > --- a/drivers/gpu/drm/drm_atomic_state_helper.c > +++ b/drivers/gpu/drm/drm_atomic_state_helper.c > @@ -552,6 +552,93 @@ void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector) > } > EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset); > > +/** > + * @drm_atomic_helper_connector_tv_check: Validate an analog TV connector state > + * @connector: DRM Connector > + * @state: the DRM State object > + * > + * Checks the state object to see if the requested state is valid for an > + * analog TV connector. > + * > + * Returns: > + * Zero for success, a negative error code on error. > + */ > +int drm_atomic_helper_connector_tv_check(struct drm_connector *connector, > + struct drm_atomic_state *state) > +{ > + struct drm_connector_state *old_conn_state = > + drm_atomic_get_old_connector_state(state, connector); > + struct drm_connector_state *new_conn_state = > + drm_atomic_get_new_connector_state(state, connector); > + const struct drm_display_mode *mode; > + struct drm_crtc_state *crtc_state; > + struct drm_crtc *crtc; > + > + crtc = new_conn_state->crtc; > + if (!crtc) > + return 0; > + > + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); > + if (!crtc_state) > + return -EINVAL; > + > + switch (new_conn_state->tv.norm) { > + case DRM_MODE_TV_NORM_NTSC_443: > + fallthrough; > + case DRM_MODE_TV_NORM_NTSC_J: > + fallthrough; > + case DRM_MODE_TV_NORM_NTSC_M: > + fallthrough; > + case DRM_MODE_TV_NORM_PAL_M: > + mode = &drm_mode_480i; > + break; > + > + case DRM_MODE_TV_NORM_PAL_60: > + fallthrough; > + case DRM_MODE_TV_NORM_PAL_B: > + fallthrough; > + case DRM_MODE_TV_NORM_PAL_D: > + fallthrough; > + case DRM_MODE_TV_NORM_PAL_G: > + fallthrough; > + case DRM_MODE_TV_NORM_PAL_H: > + fallthrough; > + case DRM_MODE_TV_NORM_PAL_I: > + fallthrough; > + case DRM_MODE_TV_NORM_PAL_N: > + fallthrough; > + case DRM_MODE_TV_NORM_PAL_NC: > + fallthrough; > + case DRM_MODE_TV_NORM_SECAM_60: > + fallthrough; > + case DRM_MODE_TV_NORM_SECAM_B: > + fallthrough; > + case DRM_MODE_TV_NORM_SECAM_D: > + fallthrough; > + case DRM_MODE_TV_NORM_SECAM_G: > + fallthrough; > + case DRM_MODE_TV_NORM_SECAM_K: > + fallthrough; > + case DRM_MODE_TV_NORM_SECAM_K1: > + fallthrough; > + case DRM_MODE_TV_NORM_SECAM_L: > + mode = &drm_mode_576i; > + break; > + > + default: > + return -EINVAL; > + } > + > + if (!drm_mode_equal(mode, &crtc_state->mode)) > + return -EINVAL; > + > + if (old_conn_state->tv.norm != new_conn_state->tv.norm) > + crtc_state->mode_changed = true; > + > + return 0; > +} > +EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check); > + > /** > * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state > * @connector: connector object > diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h > index c8fbce795ee7..b9740edb2658 100644 > --- a/include/drm/drm_atomic_state_helper.h > +++ b/include/drm/drm_atomic_state_helper.h > @@ -26,6 +26,7 @@ > > #include <linux/types.h> > > +struct drm_atomic_state; > struct drm_bridge; > struct drm_bridge_state; > struct drm_crtc; > @@ -71,6 +72,8 @@ void __drm_atomic_helper_connector_reset(struct drm_connector *connector, > struct drm_connector_state *conn_state); > void drm_atomic_helper_connector_reset(struct drm_connector *connector); > void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector); > +int drm_atomic_helper_connector_tv_check(struct drm_connector *connector, > + struct drm_atomic_state *state); > void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connector); > void > __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector, >
Hi, On Fri, Jul 29, 2022 at 07:16:31PM +0200, Mateusz Kwiatkowski wrote: > I'm pretty sure that PAL-60 and SECAM-60 should be tied to the 480i mode. > Those are non-standard "norms" that use 60 Hz sync (which is largely > synonymous with 480i in the analog TV world) with PAL/SECAM color encoding. Understood, I've changed it. Maxime
diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index 6d14cb0c64b1..fce5569bd66a 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -552,6 +552,93 @@ void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector) } EXPORT_SYMBOL(drm_atomic_helper_connector_tv_reset); +/** + * @drm_atomic_helper_connector_tv_check: Validate an analog TV connector state + * @connector: DRM Connector + * @state: the DRM State object + * + * Checks the state object to see if the requested state is valid for an + * analog TV connector. + * + * Returns: + * Zero for success, a negative error code on error. + */ +int drm_atomic_helper_connector_tv_check(struct drm_connector *connector, + struct drm_atomic_state *state) +{ + struct drm_connector_state *old_conn_state = + drm_atomic_get_old_connector_state(state, connector); + struct drm_connector_state *new_conn_state = + drm_atomic_get_new_connector_state(state, connector); + const struct drm_display_mode *mode; + struct drm_crtc_state *crtc_state; + struct drm_crtc *crtc; + + crtc = new_conn_state->crtc; + if (!crtc) + return 0; + + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + if (!crtc_state) + return -EINVAL; + + switch (new_conn_state->tv.norm) { + case DRM_MODE_TV_NORM_NTSC_443: + fallthrough; + case DRM_MODE_TV_NORM_NTSC_J: + fallthrough; + case DRM_MODE_TV_NORM_NTSC_M: + fallthrough; + case DRM_MODE_TV_NORM_PAL_M: + mode = &drm_mode_480i; + break; + + case DRM_MODE_TV_NORM_PAL_60: + fallthrough; + case DRM_MODE_TV_NORM_PAL_B: + fallthrough; + case DRM_MODE_TV_NORM_PAL_D: + fallthrough; + case DRM_MODE_TV_NORM_PAL_G: + fallthrough; + case DRM_MODE_TV_NORM_PAL_H: + fallthrough; + case DRM_MODE_TV_NORM_PAL_I: + fallthrough; + case DRM_MODE_TV_NORM_PAL_N: + fallthrough; + case DRM_MODE_TV_NORM_PAL_NC: + fallthrough; + case DRM_MODE_TV_NORM_SECAM_60: + fallthrough; + case DRM_MODE_TV_NORM_SECAM_B: + fallthrough; + case DRM_MODE_TV_NORM_SECAM_D: + fallthrough; + case DRM_MODE_TV_NORM_SECAM_G: + fallthrough; + case DRM_MODE_TV_NORM_SECAM_K: + fallthrough; + case DRM_MODE_TV_NORM_SECAM_K1: + fallthrough; + case DRM_MODE_TV_NORM_SECAM_L: + mode = &drm_mode_576i; + break; + + default: + return -EINVAL; + } + + if (!drm_mode_equal(mode, &crtc_state->mode)) + return -EINVAL; + + if (old_conn_state->tv.norm != new_conn_state->tv.norm) + crtc_state->mode_changed = true; + + return 0; +} +EXPORT_SYMBOL(drm_atomic_helper_connector_tv_check); + /** * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state * @connector: connector object diff --git a/include/drm/drm_atomic_state_helper.h b/include/drm/drm_atomic_state_helper.h index c8fbce795ee7..b9740edb2658 100644 --- a/include/drm/drm_atomic_state_helper.h +++ b/include/drm/drm_atomic_state_helper.h @@ -26,6 +26,7 @@ #include <linux/types.h> +struct drm_atomic_state; struct drm_bridge; struct drm_bridge_state; struct drm_crtc; @@ -71,6 +72,8 @@ void __drm_atomic_helper_connector_reset(struct drm_connector *connector, struct drm_connector_state *conn_state); void drm_atomic_helper_connector_reset(struct drm_connector *connector); void drm_atomic_helper_connector_tv_reset(struct drm_connector *connector); +int drm_atomic_helper_connector_tv_check(struct drm_connector *connector, + struct drm_atomic_state *state); void drm_atomic_helper_connector_tv_margins_reset(struct drm_connector *connector); void __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
The analog TV connector drivers share some atomic_check logic, and the new TV standard property have created a bunch of new constraints that needs to be shared across drivers too. Let's create an atomic_check helper for those use cases. Signed-off-by: Maxime Ripard <maxime@cerno.tech>