mirror of
https://github.com/torvalds/linux.git
synced 2024-12-24 11:51:27 +00:00
imx-drm: core: handling of DI clock flags to ipu_crtc_mode_set()
We do not need to track the state of the IPU DI's clock flags by having each display bridge calling back into imx-drm-core, and then back out into ipuv3-crtc.c. ipuv3-crtc can instead just scan the list of encoders to retrieve their type, and build up a picture of which types of encoders are attached. We can then use this information to configure the IPU DI clocking mode without any uncertainty - if we have multiple bridges connected to the same DI, if one of them requires a synchronous DI clock, that's what we must use. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
This commit is contained in:
parent
503f1631ae
commit
d50141d807
@ -116,8 +116,7 @@ int imx_drm_panel_format_pins(struct drm_encoder *encoder,
|
||||
helper = &imx_crtc->imx_drm_helper_funcs;
|
||||
if (helper->set_interface_pix_fmt)
|
||||
return helper->set_interface_pix_fmt(encoder->crtc,
|
||||
encoder->encoder_type, interface_pix_fmt,
|
||||
hsync_pin, vsync_pin);
|
||||
interface_pix_fmt, hsync_pin, vsync_pin);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(imx_drm_panel_format_pins);
|
||||
|
@ -17,7 +17,7 @@ int imx_drm_crtc_id(struct imx_drm_crtc *crtc);
|
||||
struct imx_drm_crtc_helper_funcs {
|
||||
int (*enable_vblank)(struct drm_crtc *crtc);
|
||||
void (*disable_vblank)(struct drm_crtc *crtc);
|
||||
int (*set_interface_pix_fmt)(struct drm_crtc *crtc, u32 encoder_type,
|
||||
int (*set_interface_pix_fmt)(struct drm_crtc *crtc,
|
||||
u32 pix_fmt, int hsync_pin, int vsync_pin);
|
||||
const struct drm_crtc_helper_funcs *crtc_helper_funcs;
|
||||
const struct drm_crtc_funcs *crtc_funcs;
|
||||
|
@ -46,7 +46,6 @@ struct ipu_crtc {
|
||||
struct drm_framebuffer *newfb;
|
||||
int irq;
|
||||
u32 interface_pix_fmt;
|
||||
unsigned long di_clkflags;
|
||||
int di_hsync_pin;
|
||||
int di_vsync_pin;
|
||||
};
|
||||
@ -141,22 +140,42 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
|
||||
int x, int y,
|
||||
struct drm_framebuffer *old_fb)
|
||||
{
|
||||
struct drm_device *dev = crtc->dev;
|
||||
struct drm_encoder *encoder;
|
||||
struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
|
||||
int ret;
|
||||
struct ipu_di_signal_cfg sig_cfg = {};
|
||||
unsigned long encoder_types = 0;
|
||||
u32 out_pixel_fmt;
|
||||
int ret;
|
||||
|
||||
dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__,
|
||||
mode->hdisplay);
|
||||
dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__,
|
||||
mode->vdisplay);
|
||||
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
|
||||
if (encoder->crtc == crtc)
|
||||
encoder_types |= BIT(encoder->encoder_type);
|
||||
|
||||
dev_dbg(ipu_crtc->dev, "%s: attached to encoder types 0x%lx\n",
|
||||
__func__, encoder_types);
|
||||
|
||||
/*
|
||||
* If we have DAC, TVDAC or LDB, then we need the IPU DI clock
|
||||
* to be the same as the LDB DI clock.
|
||||
*/
|
||||
if (encoder_types & (BIT(DRM_MODE_ENCODER_DAC) |
|
||||
BIT(DRM_MODE_ENCODER_TVDAC) |
|
||||
BIT(DRM_MODE_ENCODER_LVDS)))
|
||||
sig_cfg.clkflags = IPU_DI_CLKMODE_SYNC | IPU_DI_CLKMODE_EXT;
|
||||
else
|
||||
sig_cfg.clkflags = 0;
|
||||
|
||||
out_pixel_fmt = ipu_crtc->interface_pix_fmt;
|
||||
|
||||
sig_cfg.enable_pol = 1;
|
||||
sig_cfg.clk_pol = 0;
|
||||
sig_cfg.pixel_fmt = out_pixel_fmt;
|
||||
sig_cfg.clkflags = ipu_crtc->di_clkflags;
|
||||
sig_cfg.v_to_h_sync = 0;
|
||||
sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin;
|
||||
sig_cfg.vsync_pin = ipu_crtc->di_vsync_pin;
|
||||
@ -271,7 +290,7 @@ static void ipu_disable_vblank(struct drm_crtc *crtc)
|
||||
ipu_crtc->newfb = NULL;
|
||||
}
|
||||
|
||||
static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type,
|
||||
static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc,
|
||||
u32 pixfmt, int hsync_pin, int vsync_pin)
|
||||
{
|
||||
struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
|
||||
@ -280,19 +299,6 @@ static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type,
|
||||
ipu_crtc->di_hsync_pin = hsync_pin;
|
||||
ipu_crtc->di_vsync_pin = vsync_pin;
|
||||
|
||||
switch (encoder_type) {
|
||||
case DRM_MODE_ENCODER_DAC:
|
||||
case DRM_MODE_ENCODER_TVDAC:
|
||||
case DRM_MODE_ENCODER_LVDS:
|
||||
ipu_crtc->di_clkflags = IPU_DI_CLKMODE_SYNC |
|
||||
IPU_DI_CLKMODE_EXT;
|
||||
break;
|
||||
case DRM_MODE_ENCODER_TMDS:
|
||||
case DRM_MODE_ENCODER_NONE:
|
||||
ipu_crtc->di_clkflags = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user