Skip to content

Commit

Permalink
ipuv3: support bt656/bt1120 output
Browse files Browse the repository at this point in the history
Support BT656 (8bit) and BT1120 (12bit) interlaced output on display port
from RGB and YUV frame-buffer input for PAL and NTSC mode.

Features supported:
- Support BT656(8 bits) and BT1120 (16 bits)interlaced output on display port.
- Support both RGB and YUV frame buffer for BT656/BT1120 output.
- Support PAL and NTSC mode.
- Support on the fly switch between PAL and NTSC mode.

Notes:
- For 8 bits BT656 interface, the default data pins are
  "DISP0_DAT_23~DISP0_DAT_16", it can also be any other continued display data
  pins, for example if "DISP0_DAT_7~DISP0_DAT_0" are used, the macro
  "BT656_IF_DI_MSB" in "kernel_imx/drivers/mxc/ipu3/ipu_disp.c" should be
  changed from "23" to "7".
- For 16 bits BT1120 interface, the default data pins are
  "DISP0_DAT_23~DISP0_DAT_8", it can also be any other continued display data
  pins, the macro "BT656_IF_DI_MSB" should be modified if the hardware pins
  are changed.
- When bt656 interface is the second display for each IPU,1-layer-fb
  (it can be checked with command:
   "$ cat /sys/class/graphics/fbx/fsl_disp_propperty"),
  the frame buffer can only be YUV format. In this case, the IPU DC channel
  was used for BT656 display, it has no CSC function, so RGB frame buffer was
  not supported.

See https://community.freescale.com/docs/DOC-94019

Written-by: Qiang Li
Device-tree support Written-by: Tim Harvey <tharvey@gateworks.com>

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
  • Loading branch information
Gateworks committed Jun 12, 2014
1 parent eaa0b87 commit 5580cda
Show file tree
Hide file tree
Showing 13 changed files with 1,555 additions and 296 deletions.
20 changes: 20 additions & 0 deletions Documentation/devicetree/bindings/video/fsl,bt656.txt
@@ -0,0 +1,20 @@
* Freescale BT656/BT1120 interface output

Required properties for bt656 on specified board:
- compatible: should be "fsl,bt656"
- reg: <base addr, range> contains pxp register base address and range
- default_ifmt: BT656|BT1120 - input format
- ipu_id: 0|1
- disp_id: 0|1
- status: should be set to "okay" if want to use bt656

Examples:
bt656: bt656@0 {
compatible = "fsl,bt656";
default_ifmt = "BT656";
ipu_id = <1>;
disp_id = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ipu2_2>;
status = "okay";
};
50 changes: 30 additions & 20 deletions drivers/media/platform/mxc/output/mxc_vout.c
Expand Up @@ -74,6 +74,7 @@ struct mxc_vout_fb {
int ipu_id;
struct v4l2_rect crop_bounds;
unsigned int disp_fmt;
unsigned int if_fmt;
bool disp_support_csc;
bool disp_support_windows;
};
Expand Down Expand Up @@ -294,12 +295,28 @@ static ipu_channel_t get_ipu_channel(struct fb_info *fbi)
static unsigned int get_ipu_fmt(struct fb_info *fbi)
{
mm_segment_t old_fs;
unsigned int fb_fmt;
unsigned int di_fmt;

if (fbi->fbops->fb_ioctl) {
old_fs = get_fs();
set_fs(KERNEL_DS);
fbi->fbops->fb_ioctl(fbi, MXCFB_GET_DIFMT,
(unsigned long)&di_fmt);
set_fs(old_fs);
}

return di_fmt;
}

static unsigned int get_fb_fmt(struct fb_info *fbi)
{
mm_segment_t old_fs;
unsigned int fb_fmt;

if (fbi->fbops->fb_ioctl) {
old_fs = get_fs();
set_fs(KERNEL_DS);
fbi->fbops->fb_ioctl(fbi, MXCFB_GET_FBFMT,
(unsigned long)&fb_fmt);
set_fs(old_fs);
}
Expand Down Expand Up @@ -328,14 +345,21 @@ static void update_display_setting(void)
g_fb_setting[i].crop_bounds.top = 0;
g_fb_setting[i].crop_bounds.width = fbi->var.xres;
g_fb_setting[i].crop_bounds.height = fbi->var.yres;
g_fb_setting[i].disp_fmt = get_ipu_fmt(fbi);
g_fb_setting[i].disp_fmt = get_fb_fmt(fbi);
g_fb_setting[i].if_fmt = get_ipu_fmt(fbi);

if (get_ipu_channel(fbi) == MEM_BG_SYNC) {
bg_crop_bounds[g_fb_setting[i].ipu_id] =
g_fb_setting[i].crop_bounds;
g_fb_setting[i].disp_support_csc = true;
if(colorspaceofpixel(g_fb_setting[i].disp_fmt) != colorspaceofpixel(g_fb_setting[i].if_fmt))
g_fb_setting[i].disp_support_csc = false; // DP CSC need be used for fb to di output.
else
g_fb_setting[i].disp_support_csc = true;
} else if (get_ipu_channel(fbi) == MEM_FG_SYNC) {
g_fb_setting[i].disp_support_csc = true;
if(colorspaceofpixel(g_fb_setting[i].disp_fmt) != colorspaceofpixel(g_fb_setting[i].if_fmt))
g_fb_setting[i].disp_support_csc = false; // DP CSC need be used for fb to di output.
else
g_fb_setting[i].disp_support_csc = true;
g_fb_setting[i].disp_support_windows = true;
}
}
Expand Down Expand Up @@ -392,10 +416,7 @@ static int update_setting_from_fbi(struct mxc_vout_output *vout,
vout->task.output.crop.pos.y = 0;
vout->task.output.crop.w = vout->crop_bounds.width;
vout->task.output.crop.h = vout->crop_bounds.height;
if (colorspaceofpixel(vout->disp_fmt) == YUV_CS)
vout->task.output.format = IPU_PIX_FMT_UYVY;
else
vout->task.output.format = IPU_PIX_FMT_RGB565;
vout->task.output.format = vout->disp_fmt;

return 0;
}
Expand Down Expand Up @@ -1202,18 +1223,7 @@ static int mxc_vout_try_task(struct mxc_vout_output *vout)
v4l2_info(vout->vfd->v4l2_dev, "Bypass IC.\n");
output->format = input->format;
} else {
/* if need CSC, choose IPU-DP or IPU_IC do it */
if (vout->disp_support_csc) {
if (colorspaceofpixel(input->format) == YUV_CS)
output->format = IPU_PIX_FMT_UYVY;
else
output->format = IPU_PIX_FMT_RGB565;
} else {
if (colorspaceofpixel(vout->disp_fmt) == YUV_CS)
output->format = IPU_PIX_FMT_UYVY;
else
output->format = IPU_PIX_FMT_RGB565;
}
output->format = vout->disp_fmt;

vout->tiled_bypass_pp = false;
if ((IPU_PIX_FMT_TILED_NV12 == input->format) ||
Expand Down
3 changes: 3 additions & 0 deletions drivers/mxc/ipu3/ipu_common.c
Expand Up @@ -482,6 +482,9 @@ static int ipu_probe(struct platform_device *pdev)
/* Set MCU_T to divide MCU access window into 2 */
ipu_cm_write(ipu, 0x00400000L | (IPU_MCU_T_DEFAULT << 18),
IPU_DISP_GEN);
} else {
ipu->fg_csc_type = ipu->bg_csc_type = CSC_NONE;
ipu->color_key_4rgb = true;
}

/* setup ipu clk tree after ipu reset */
Expand Down
4 changes: 4 additions & 0 deletions drivers/mxc/ipu3/ipu_device.c
Expand Up @@ -462,6 +462,8 @@ cs_t colorspaceofpixel(int fmt)
case IPU_PIX_FMT_RGBA32:
case IPU_PIX_FMT_RGB32:
case IPU_PIX_FMT_ABGR32:
case IPU_PIX_FMT_LVDS666:
case IPU_PIX_FMT_LVDS888:
return RGB_CS;
break;
case IPU_PIX_FMT_UYVY:
Expand All @@ -476,6 +478,8 @@ cs_t colorspaceofpixel(int fmt)
case IPU_PIX_FMT_NV12:
case IPU_PIX_FMT_TILED_NV12:
case IPU_PIX_FMT_TILED_NV12F:
case IPU_PIX_FMT_BT656:
case IPU_PIX_FMT_BT1120:
return YUV_CS;
break;
default:
Expand Down

0 comments on commit 5580cda

Please sign in to comment.