ARM: Davinci: HD FrameBuffer 1080i(1920*1080) driver support

parent 68b4855a
......@@ -286,10 +286,209 @@ int ths8200_set_720p_mode(void)
/* take ths8200 out of reset and in normal operation mode */
ths8200_write_value(CHIP_CTL_REG, CHIP_SOFTWARE_OUT_OF_RESET);
printk(KERN_INFO "THS8200 set DAC mode as 720p\n");
printk(KERN_INFO "THS8200 set video mode as 720p\n");
return 0;
}
int ths8200_set_1080i_mode(void)
{
FN_IN;
/* place ths8200 in reset state */
ths8200_write_value(CHIP_CTL_REG,CHIP_SOFTWARE_RESET |
CHIP_LOW_FREQUENCY);
/* take ths8200 out of reset and in normal operation mode */
ths8200_write_value(CHIP_CTL_REG, CHIP_SOFTWARE_OUT_OF_RESET |
CHIP_LOW_FREQUENCY);
/* place color space conversion control in reset state */
ths8200_write_value(CSC_R11_REG, 0x00);
ths8200_write_value(CSC_R21_REG, 0x00);
ths8200_write_value(CSC_R31_REG, 0x00);
ths8200_write_value(CSC_G11_REG, 0x00);
ths8200_write_value(CSC_G21_REG, 0x00);
ths8200_write_value(CSC_G31_REG, 0x00);
ths8200_write_value(CSC_B11_REG, 0x00);
ths8200_write_value(CSC_B21_REG, 0x00);
ths8200_write_value(CSC_B31_REG, 0x00);
ths8200_write_value(CSC_OFFS1_REG, 0x00);
ths8200_write_value(CSC_OFFS12_REG, 0x00);
ths8200_write_value(CSC_OFFS23_REG, 0x00);
ths8200_write_value(CSC_OFFS3_REG,
CSC_BYPASSED |
CSC_PROTECTION_ON);
/* Turn off THS8200 Test Modes */
ths8200_write_value(TST_CNTL1_REG, 0x00);
ths8200_write_value(TST_CNTL2_REG, 0x00);
/* Turn CSM Off */
ths8200_write_value(CSM_GY_CNTL_MULT_MSB_REG, 0x00);
/* set YCx20 External Sync */
ths8200_write_value(DTG2_CNTL_REG, HS_IN_POSITIVE_POLARITY |
VS_IN_POSITIVE_POLARITY |
HS_OUT_POSITIVE_POLARITY |
VS_OUT_POSITIVE_POLARITY |
FID_POLARITY);
/* select the format for the input data manager */
ths8200_write_value(DATA_CNTL_REG, DATA_20BIT_YCBCR_MODE);
/* set the amplitude of the blanking level for the Y channel */
ths8200_write_value(DTG1_Y_SYNC1_LSB_REG, 0xFF);
/* set the amplitude of the negative sync and
equalization/serration/broad pulses for the Y channel */
ths8200_write_value(DTG1_Y_SYNC2_LSB_REG, 0x49);
/* set the amplitude of the positive sync for the Y channel */
ths8200_write_value(DTG1_Y_SYNC3_LSB_REG, 0xB6);
/* set the amplitude of the blanking level for the Cb and Cr channels */
ths8200_write_value(DTG1_CBCR_SYNC1_LSB_REG, 0xFF);
/* set the amplitude of the negative sync and
equalization/serration/broad pulses for the
Cb and Cr channels */
ths8200_write_value(DTG1_CBCR_SYNC2_LSB_REG, 0xFF);
/* set the amplitude of the positive sync for the Cb and Cr channels */
ths8200_write_value(DTG1_CBCR_SYNC3_LSB_REG, 0xFF);
/* set msb for sync1 sync2 and sync3 */
ths8200_write_value(DTG1_Y_SYNC_MSB_REG, 0x13);
/* set msb for sync1 sync2 and sync3 */
ths8200_write_value(DTG1_CBCR_SYNC_MSB_REG, 0x15);
/* set negative hsync width (half of total width) */
ths8200_write_value(DTG1_SPEC_A_REG, 0x2C);
/* set end of active video to start of negative sync */
ths8200_write_value(DTG1_SPEC_B_REG, 0x58);
/* set positive hsync width (half of total width) */
ths8200_write_value(DTG1_SPEC_C_REG, 0x2C);
/* set LSBs of sync to broad pulse */
ths8200_write_value(DTG1_SPEC_D_LSB_REG, 0x84);
/* set distance from equalization pulse at center
of line to active video*/
ths8200_write_value(DTG1_SPEC_D1_REG, 0x00);
/* set LSBs of sync to active video */
ths8200_write_value(DTG1_SPEC_E_LSB_REG, 0xC0);
/* set MSB bit of sync to active video width[6]/sync to broad pulse [7] */
ths8200_write_value(DTG1_SPEC_DEH_MSB_REG, 0x00);
/* set broad pulse duration for SDTV (NA) */
ths8200_write_value(DTG1_SPEC_H_LSB_REG, 0x00);
/* set end of active video to sync LSBs [7:0] */
ths8200_write_value(DTG1_SPEC_K_LSB_REG, 0x58);
/* set end of active video to sync MSBs [2:0] */
ths8200_write_value(DTG1_SPEC_K_MSB_REG, 0x00);
/* set LSB bit of half the line length */
ths8200_write_value(DTG1_SPEC_G_LSB_REG, 0x58);
/* set MSB bit of half the line length */
ths8200_write_value(DTG1_SPEC_G_MSB_REG, 0x00);
/* set MSB bit of total number of pixels per line */
ths8200_write_value(DTG1_TOTAL_PIXELS_MSB_REG, 0x08);
/* set LSB bit of total number of pixels per line */
ths8200_write_value(DTG1_TOTAL_PIXELS_LSB_REG, 0x98);
/* set MSB and LSB bit of the starting line number
for the DTG when Vsync input or V-bit is
asserted(vertical display control) */
ths8200_write_value(DTG1_FIELDFLIP_LINECNT_MSB_REG, 0x00);
ths8200_write_value(DTG1_FIELDFLIP_LINECNT_LSB_REG, 0x01);
/* set DTG on and set DTG operation mode to
ATSC mode 1080I(SMPTE274M Interlaced)*/
ths8200_write_value(DTG1_MODE_REG, DTG_ON | ATSC_MODE_1080I);
/* set MSB bit of number of lines per frame and
number of lines in field 1when in generic mode */
ths8200_write_value(DTG1_FRAME_FILED_SIZE_MSB_REG, 0x42);
/* set LSB bit of number of lines per frame when in generic mode */
ths8200_write_value(DTG1_FRAMESIZE_LSB_REG, 0x65);
/* set LSB bit of number of lines in field 1 when in generic mode */
ths8200_write_value(DTG1_FIELDSIZE_LSB_REG, 0x33);
/* set LSB bit of vlength */
ths8200_write_value(DTG2_HLENGTH_LSB_REG, 0x58);
/* set MSB bit of pixel value that the HS_OUT signal is asserted on */
ths8200_write_value(DTG2_HLENGTH_LSB_HDLY_MSB, 0x00);
/* set LSB bit of pixel value that the HS_OUT signal is asserted on */
ths8200_write_value(DTG2_HDLY_LSB, 0x00);
/* set LSB bit of the duration of the VS_OUT output signal during
progressive scan video modes or during the vertical blank interval
of field 1 in interlaced video modes. */
ths8200_write_value(DTG2_VLENGTH1_LSB, 0x05);
/* set MSB bit of the VS_OUT output signal during progressive scan
video modes or during the vertical blank interval of field 1 in
interlaced video modes. */
ths8200_write_value(DTG2_VLENGTH1_MSB_VDLY1_MSB, 0x00);
/* set LSB bit of line number that VS_OUT signal is asserted on for
progressive video modes or for field 1 of interlaced video modes. */
ths8200_write_value(DTG2_VDLY1_LSB, 0x00);
/* set LSB bit of the duration of the VS_OUT output signal during
the vertical blank interval of field 2 in interlaced video modes.
In progressive video modes, this register must be set to all 0. */
ths8200_write_value(DTG2_VLENGTH2_LSB, 0x05);
/* set the MSB bit of the duration of the VS_OUT output signal
during the vertical blank interval of field2 in interlaced video
modes.In progressive video modes, this register must be set to all 0.*/
ths8200_write_value(DTG2_VLENGTH2_MSB_VDLY2_MSB, 0x77);
/* set LSB bit of the line number that the VS_OUT signal is asserted on
for field 2 of interlaced scan video modes.For progressive scan video
modes, this register must be set to all 1. */
ths8200_write_value(DTG2_VDLY2_LSB, 0x00);
/* set MSB and LSB bit of the number of pixels that the DTG
startup is horizontally delayed with respect to HS input for
dedicated timing modes or EAV input for embedded
timing modes. */
ths8200_write_value(DTG2_HS_IN_DLY_MSB_REG, 0x00);
ths8200_write_value(DTG2_HS_IN_DLY_LSB_REG, 0x44);
/* set MSB and LSB bit of the number of lines that the DTG
startup is vertically delayed with respect to VS input for
dedicated timing modes or the line counter value for
embedded timing.*/
ths8200_write_value(DTG2_VS_IN_DLY_MSB_REG, 0x00);
ths8200_write_value(DTG2_VS_IN_DLY_LSB_REG, 0x01);
/* place ths8200 in reset state */
ths8200_write_value(CHIP_CTL_REG, CHIP_SOFTWARE_RESET);
/* take ths8200 out of reset and in normal operation mode */
ths8200_write_value(CHIP_CTL_REG, CHIP_SOFTWARE_OUT_OF_RESET);
printk(KERN_INFO "THS8200 set video mode as 1080i\n");
return 0;
}
static __init int ths8200_init(void)
{
FN_IN;
......@@ -315,6 +514,7 @@ module_init(ths8200_init);
module_exit(ths8200_exit);
EXPORT_SYMBOL(ths8200_set_720p_mode);
EXPORT_SYMBOL(ths8200_set_1080i_mode);
MODULE_DESCRIPTION("THS8200 Video DAC Convert Driver");
MODULE_AUTHOR("Neuros Technology International LLC");
......
......@@ -142,6 +142,12 @@ static struct fb_ops davincifb_ops;
#define DISP_YRES720P 720
#define DISP_MEMY720P 720
#define BASEX1080I 0x58
#define BASEY1080I 0x5
#define DISP_XRES1080I 1920
#define DISP_YRES1080I 1080
#define DISP_MEMY1080I 1080
/* Random value chosen for now. Should be within the panel's supported range */
#define LCD_PANEL_CLOCK 180000
......@@ -1041,10 +1047,14 @@ int __init davincifb_setup(char *options)
else if (!strncmp(this_opt + 7, "720p", 4)) {
dmparams.output = HD720P;
dmparams.format = COMPONENT;
} else if (!strncmp(this_opt + 7, "1080i", 5)) {
dmparams.output = HD1080I;
dmparams.format = COMPONENT;
}
} else if (!strncmp(this_opt, "format=", 7)) {
if (dmparams.output == LCD ||
dmparams.output == HD720P)
dmparams.output == HD720P ||
dmparams.output == HD1080I)
continue;
if (!strncmp(this_opt + 7, "composite", 9))
dmparams.format = COMPOSITE;
......@@ -1104,6 +1114,7 @@ int __init davincifb_setup(char *options)
"Output on %s%s, Enabled windows: %s %s %s %s\n",
(dmparams.output == LCD) ? "LCD" :
(dmparams.output == HD720P) ? "HD720P":
(dmparams.output == HD1080I) ? "HD1080I":
(dmparams.output == NTSC) ? "NTSC" :
(dmparams.output == PAL) ? "PAL" : "unknown device!",
(dmparams.format == 0) ? "" :
......@@ -1122,6 +1133,9 @@ int __init davincifb_setup(char *options)
} else if (dmparams.output == HD720P) {
format_xres = DISP_XRES720P;
format_yres = DISP_YRES720P;
} else if (dmparams.output == HD1080I) {
format_xres = DISP_XRES1080I;
format_yres = DISP_YRES1080I;
} else {
printk(KERN_INFO
"DaVinci:invalid format..defaulting width to 480\n");
......@@ -1467,6 +1481,91 @@ static void enable_digital_output(bool on)
}
}
static void davincifb_1080i_component_config(int on)
{
if (on) {
#ifdef CONFIG_THS8200
/* Enable THS8200 DAC output mode as 1080I */
ths8200_set_1080i_mode();
#endif/* CONFIG_THS8200 */
/* Reset video encoder module */
dispc_reg_out(VENC_VMOD, 0);
/* Set new baseX and baseY */
dispc_reg_out(OSD_BASEPX, BASEX1080I);
dispc_reg_out(OSD_BASEPY, BASEY1080I);
enable_digital_output(true);
dispc_reg_merge(PINMUX0, PINMUX0_LFLDEN, PINMUX0_LFLDEN);
/* Enable OSD0 Window */
dispc_reg_out(OSD_OSDWIN0MD, 0x00002003);
/* Enable OSD1 Window */
dispc_reg_out(OSD_OSDWIN1MD, 0x00008002);
/* Set Timing parameters for 720P frame (must match what THS8200 expects) */
dispc_reg_out(VENC_HSPLS, BASEX1080I);
dispc_reg_out(VENC_VSPLS, BASEY1080I);
dispc_reg_out(VENC_HINT, 2200-1);
dispc_reg_out(VENC_HSTART, 200);
dispc_reg_out(VENC_HVALID, DISP_XRES1080I);
dispc_reg_out(VENC_VINT, 1125-1);
dispc_reg_out(VENC_VSTART, 13);
dispc_reg_out(VENC_VVALID, DISP_YRES1080I/2);
dispc_reg_out(VENC_HSDLY, 0);
dispc_reg_out(VENC_VSDLY, 0);
dispc_reg_out(VENC_YCCCTL, 0);
dispc_reg_out(VENC_VSTARTA, 13);
dispc_reg_out(OSD_VIDWINMD, 0x203);
/* Set VID0 window origin and size */
dispc_reg_out(OSD_VIDWIN0XP, 200 - BASEX1080I);
dispc_reg_out(OSD_VIDWIN0YP, 13);
dispc_reg_out(OSD_VIDWIN0XL, DISP_XRES1080I);
dispc_reg_out(OSD_VIDWIN0YL, DISP_YRES1080I/2);
/* Set VID1 window origin and size */
dispc_reg_out(OSD_VIDWIN1XP, 200 - BASEX1080I);
dispc_reg_out(OSD_VIDWIN1YP, 13);
dispc_reg_out(OSD_VIDWIN1XL, DISP_XRES1080I);
dispc_reg_out(OSD_VIDWIN1YL, DISP_YRES1080I/2);
/* Set OSD0 window origin and size */
dispc_reg_out(OSD_OSDWIN0XP, 200 - BASEX1080I);
dispc_reg_out(OSD_OSDWIN0YP, 13);
dispc_reg_out(OSD_OSDWIN0XL, DISP_XRES1080I);
dispc_reg_out(OSD_OSDWIN0YL, DISP_YRES1080I/2);
/* Set OSD1 window origin and size */
dispc_reg_out(OSD_OSDWIN1XP, 200 - BASEX1080I);
dispc_reg_out(OSD_OSDWIN1YP, 13);
dispc_reg_out(OSD_OSDWIN1XL, DISP_XRES1080I);
dispc_reg_out(OSD_OSDWIN1YL, DISP_YRES1080I/2);
/* Set OSD1 window origin and size */
dispc_reg_out(OSD_CURXP, 200 - BASEX1080I);
dispc_reg_out(OSD_CURYP, 13);
dispc_reg_out(OSD_CURXL, DISP_XRES1080I);
dispc_reg_out(OSD_CURYL, DISP_YRES1080I/2);
/* Enable all VENC, non-standard timing mode, master timing, HD, interlaced */
dispc_reg_out(VENC_VMOD,
(VENC_VMOD_VENC | VENC_VMOD_VMD |
VENC_VMOD_HDMD | VENC_VMOD_NSIT));
printk(KERN_INFO "Davinci set video mode as 1080i\n");
} else {
/* Reset video encoder module */
dispc_reg_out(VENC_VMOD, 0);
}
}
static void davincifb_720p_component_config(int on)
{
if (on) {
......@@ -1543,7 +1642,7 @@ static void davincifb_720p_component_config(int on)
dispc_reg_out(VENC_VMOD,
(VENC_VMOD_VENC | VENC_VMOD_VMD | VENC_VMOD_HDMD));
printk(KERN_INFO "Davinci set Video Mode as 720p\n");
printk(KERN_INFO "Davinci set video mode as 720p\n");
} else{
/* Reset video encoder module */
dispc_reg_out(VENC_VMOD, 0);
......@@ -1794,6 +1893,8 @@ static int davincifb_probe(struct platform_device *pdev)
dm->output_device_config = davincifb_pal_component_config;
else if ((dmparams.output == HD720P) && (dmparams.format == COMPONENT))
dm->output_device_config = davincifb_720p_component_config;
else if ((dmparams.output == HD1080I) && (dmparams.format == COMPONENT))
dm->output_device_config = davincifb_1080i_component_config;
/* Add support for other displays here */
else {
printk(KERN_WARNING "Unsupported output device!\n");
......
......@@ -150,4 +150,12 @@
*/
int ths8200_set_720p_mode(void);
/**
* set THS8200 DAC mode as 1080i
*
* @return int
* 0: success, other error.
*/
int ths8200_set_1080i_mode(void);
#endif /* End of DAVINCI_THS8200 */
......@@ -435,6 +435,7 @@
#define NTSC 1
#define PAL 2
#define HD720P 3
#define HD1080I 4
#define COMPOSITE 1
#define SVIDEO 2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment