1
0
Fork 0

staging: drm/imx: Add support for VGA via TVE on i.MX53

This adds display interface timings for the Television Encoder
connected to IPU DI1 on i.MX53 and adds some configuration
glue code to select which IPU signal generators / pins are to
be used for HSYNC/VSYNC signals.

The default configuration is pin2/pin3 for hsync/vsync. The
VGA connector on i.MX53-QSB uses pin7/pin8, and the analog
part of the DVI-I connector on MBa53 connects to pin4/pin6.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
wifi-calibration
Philipp Zabel 2013-04-08 18:04:35 +02:00 committed by Greg Kroah-Hartman
parent db5225d405
commit 2ea42608ba
5 changed files with 111 additions and 11 deletions

View File

@ -112,8 +112,8 @@ static struct imx_drm_crtc *imx_drm_crtc_by_num(struct imx_drm_device *imxdrm,
return NULL;
}
int imx_drm_crtc_panel_format(struct drm_crtc *crtc, u32 encoder_type,
u32 interface_pix_fmt)
int imx_drm_crtc_panel_format_pins(struct drm_crtc *crtc, u32 encoder_type,
u32 interface_pix_fmt, int hsync_pin, int vsync_pin)
{
struct imx_drm_device *imxdrm = crtc->dev->dev_private;
struct imx_drm_crtc *imx_crtc;
@ -134,9 +134,18 @@ found:
helper = &imx_crtc->imx_drm_helper_funcs;
if (helper->set_interface_pix_fmt)
return helper->set_interface_pix_fmt(crtc,
encoder_type, interface_pix_fmt);
encoder_type, interface_pix_fmt,
hsync_pin, vsync_pin);
return 0;
}
EXPORT_SYMBOL_GPL(imx_drm_crtc_panel_format_pins);
int imx_drm_crtc_panel_format(struct drm_crtc *crtc, u32 encoder_type,
u32 interface_pix_fmt)
{
return imx_drm_crtc_panel_format_pins(crtc, encoder_type,
interface_pix_fmt, 0, 0);
}
EXPORT_SYMBOL_GPL(imx_drm_crtc_panel_format);
int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc)

View File

@ -18,7 +18,7 @@ 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,
u32 pix_fmt);
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;
};
@ -54,6 +54,8 @@ struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb);
struct drm_device *imx_drm_device_get(void);
void imx_drm_device_put(void);
int imx_drm_crtc_panel_format_pins(struct drm_crtc *crtc, u32 encoder_type,
u32 interface_pix_fmt, int hsync_pin, int vsync_pin);
int imx_drm_crtc_panel_format(struct drm_crtc *crtc, u32 encoder_type,
u32 interface_pix_fmt);
void imx_drm_fb_helper_set(struct drm_fbdev_cma *fbdev_helper);

View File

@ -54,6 +54,9 @@ struct ipu_di_signal_cfg {
#define IPU_DI_CLKMODE_SYNC (1 << 0)
#define IPU_DI_CLKMODE_EXT (1 << 1)
unsigned long clkflags;
u8 hsync_pin;
u8 vsync_pin;
};
enum ipu_color_space {

View File

@ -440,7 +440,7 @@ static void ipu_di_sync_config_noninterlaced(struct ipu_di *di,
.repeat_count = sig->height,
.cnt_clr_src = DI_SYNC_VSYNC,
} , {
/* 5: DE, referenced by DC */
/* 5: Pixel Active, referenced by DC */
.run_src = DI_SYNC_CLK,
.offset_count = sig->h_sync_width + sig->h_start_width,
.offset_src = DI_SYNC_CLK,
@ -454,13 +454,78 @@ static void ipu_di_sync_config_noninterlaced(struct ipu_di *di,
/* unused */
} , {
/* unused */
},
};
/* can't use #7 and #8 for line active and pixel active counters */
struct di_sync_config cfg_vga[] = {
{
/* 1: INT_HSYNC */
.run_count = h_total - 1,
.run_src = DI_SYNC_CLK,
} , {
/* 2: VSYNC */
.run_count = v_total - 1,
.run_src = DI_SYNC_INT_HSYNC,
} , {
/* 3: Line Active */
.run_src = DI_SYNC_INT_HSYNC,
.offset_count = sig->v_sync_width + sig->v_start_width,
.offset_src = DI_SYNC_INT_HSYNC,
.repeat_count = sig->height,
.cnt_clr_src = 3 /* VSYNC */,
} , {
/* PIN4: HSYNC for VGA via TVEv2 on TQ MBa53 */
.run_count = h_total - 1,
.run_src = DI_SYNC_CLK,
.offset_count = div * sig->v_to_h_sync + 18, /* magic value from Freescale TVE driver */
.offset_src = DI_SYNC_CLK,
.cnt_polarity_gen_en = 1,
.cnt_polarity_trigger_src = DI_SYNC_CLK,
.cnt_down = sig->h_sync_width * 2,
} , {
/* 5: Pixel Active signal to DC */
.run_src = DI_SYNC_CLK,
.offset_count = sig->h_sync_width + sig->h_start_width,
.offset_src = DI_SYNC_CLK,
.repeat_count = sig->width,
.cnt_clr_src = 4, /* Line Active */
} , {
/* PIN6: VSYNC for VGA via TVEv2 on TQ MBa53 */
.run_count = v_total - 1,
.run_src = DI_SYNC_INT_HSYNC,
.offset_count = 1, /* magic value from Freescale TVE driver */
.offset_src = DI_SYNC_INT_HSYNC,
.cnt_polarity_gen_en = 1,
.cnt_polarity_trigger_src = DI_SYNC_INT_HSYNC,
.cnt_down = sig->v_sync_width * 2,
} , {
/* PIN4: HSYNC for VGA via TVEv2 on i.MX53-QSB */
.run_count = h_total - 1,
.run_src = DI_SYNC_CLK,
.offset_count = div * sig->v_to_h_sync + 18, /* magic value from Freescale TVE driver */
.offset_src = DI_SYNC_CLK,
.cnt_polarity_gen_en = 1,
.cnt_polarity_trigger_src = DI_SYNC_CLK,
.cnt_down = sig->h_sync_width * 2,
} , {
/* PIN6: VSYNC for VGA via TVEv2 on i.MX53-QSB */
.run_count = v_total - 1,
.run_src = DI_SYNC_INT_HSYNC,
.offset_count = 1, /* magic value from Freescale TVE driver */
.offset_src = DI_SYNC_INT_HSYNC,
.cnt_polarity_gen_en = 1,
.cnt_polarity_trigger_src = DI_SYNC_INT_HSYNC,
.cnt_down = sig->v_sync_width * 2,
} , {
/* unused */
},
};
ipu_di_write(di, v_total - 1, DI_SCR_CONF);
ipu_di_sync_config(di, cfg, 0, ARRAY_SIZE(cfg));
if (sig->hsync_pin == 2 && sig->vsync_pin == 3)
ipu_di_sync_config(di, cfg, 0, ARRAY_SIZE(cfg));
else
ipu_di_sync_config(di, cfg_vga, 0, ARRAY_SIZE(cfg_vga));
}
int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
@ -537,11 +602,25 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig)
ipu_di_sync_config_noninterlaced(di, sig, div);
vsync_cnt = 3;
if (di->id == 1)
vsync_cnt = 6;
if (sig->Hsync_pol)
di_gen |= DI_GEN_POLARITY_2;
if (sig->Vsync_pol)
di_gen |= DI_GEN_POLARITY_3;
if (sig->Hsync_pol) {
if (sig->hsync_pin == 2)
di_gen |= DI_GEN_POLARITY_2;
else if (sig->hsync_pin == 4)
di_gen |= DI_GEN_POLARITY_4;
else if (sig->hsync_pin == 7)
di_gen |= DI_GEN_POLARITY_7;
}
if (sig->Vsync_pol) {
if (sig->hsync_pin == 3)
di_gen |= DI_GEN_POLARITY_3;
else if (sig->hsync_pin == 6)
di_gen |= DI_GEN_POLARITY_6;
else if (sig->hsync_pin == 8)
di_gen |= DI_GEN_POLARITY_8;
}
}
if (!sig->clk_pol)

View File

@ -60,6 +60,8 @@ struct ipu_crtc {
int irq;
u32 interface_pix_fmt;
unsigned long di_clkflags;
int di_hsync_pin;
int di_vsync_pin;
};
#define to_ipu_crtc(x) container_of(x, struct ipu_crtc, base)
@ -255,6 +257,9 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
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;
if (ipu_crtc->dp) {
ret = ipu_dp_setup_channel(ipu_crtc->dp, IPUV3_COLORSPACE_RGB,
IPUV3_COLORSPACE_RGB);
@ -406,11 +411,13 @@ static void ipu_disable_vblank(struct drm_crtc *crtc)
}
static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, u32 encoder_type,
u32 pixfmt)
u32 pixfmt, int hsync_pin, int vsync_pin)
{
struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
ipu_crtc->interface_pix_fmt = pixfmt;
ipu_crtc->di_hsync_pin = hsync_pin;
ipu_crtc->di_vsync_pin = vsync_pin;
switch (encoder_type) {
case DRM_MODE_ENCODER_DAC: