summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorG, Manjunath Kondaiah <manjugk@ti.com>2010-10-29 16:19:10 +0530
committerG, Manjunath Kondaiah <manjugk@ti.com>2010-10-29 16:19:32 +0530
commit29e973b87c89e22a8ee95ee38afb0039a395d50d (patch)
tree0709d8db8e4e1fd445c944d0b157104d35b5e50f
parent08e5ff41d66926d88ef166ca53f6972753fbb360 (diff)
parent80b87dcb1b6167f303e617fdb7c70d814b2468d5 (diff)
Merge branch 'Display changes' into L24.11ti-2.6.35-omap4-L24.11-p1
-rw-r--r--arch/arm/plat-omap/include/plat/display.h33
-rw-r--r--drivers/media/video/omap/omap_vout.c214
-rw-r--r--drivers/media/video/omap/omap_wb.c12
-rw-r--r--[-rwxr-xr-x]drivers/video/omap2/dss/core.c26
-rw-r--r--drivers/video/omap2/dss/dispc.c559
-rw-r--r--drivers/video/omap2/dss/display.c23
-rw-r--r--drivers/video/omap2/dss/dss.c19
-rw-r--r--drivers/video/omap2/dss/dss.h4
-rw-r--r--drivers/video/omap2/dss/edid.c9
-rw-r--r--drivers/video/omap2/dss/hdmi.c56
-rw-r--r--drivers/video/omap2/dss/manager.c47
-rw-r--r--drivers/video/omap2/dss/overlay.c14
12 files changed, 567 insertions, 449 deletions
diff --git a/arch/arm/plat-omap/include/plat/display.h b/arch/arm/plat-omap/include/plat/display.h
index 6a1eeaf0b36d..122cea0b7347 100644
--- a/arch/arm/plat-omap/include/plat/display.h
+++ b/arch/arm/plat-omap/include/plat/display.h
@@ -264,10 +264,17 @@ enum omap_writeback_capturemode {
};
enum device_n_buffer_type {
- PBUF_PDEV = 0,
- PBUF_IDEV = 1,
- IBUF_IDEV = 2,
- IBUF_PDEV = 3,
+ OMAP_FLAG_IDEV = 1, /* interlaced device */
+ OMAP_FLAG_IBUF = 2, /* sequentially interlaced buffer */
+ OMAP_FLAG_ISWAP = 4, /* bottom-top interlacing */
+
+ PBUF_PDEV = 0,
+ PBUF_IDEV = OMAP_FLAG_IDEV,
+ PBUF_IDEV_SWAP = OMAP_FLAG_IDEV | OMAP_FLAG_ISWAP,
+ IBUF_IDEV = OMAP_FLAG_IBUF | OMAP_FLAG_IDEV,
+ IBUF_IDEV_SWAP = OMAP_FLAG_IBUF | OMAP_FLAG_IDEV | OMAP_FLAG_ISWAP,
+ IBUF_PDEV = OMAP_FLAG_IBUF,
+ IBUF_PDEV_SWAP = OMAP_FLAG_IBUF | OMAP_FLAG_ISWAP,
};
/* RFBI */
@@ -410,7 +417,6 @@ struct omap_overlay_info {
enum omap_overlay_zorder zorder;
u32 p_uv_addr; /* relevant for NV12 format only */
enum device_n_buffer_type field;
- u16 pic_width; /* for interlacing with cropping this is required */
u16 pic_height; /* for interlacing with cropping this is required */
};
@@ -772,17 +778,8 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
int omap_rfbi_update(struct omap_dss_device *dssdev,
u16 x, u16 y, u16 w, u16 h,
void (*callback)(void *), void *data);
-void calc_tiler_row_rotation(u8 rotation,
- u16 width,
- enum omap_color_mode color_mode,
- int y_decim,
- s32 *row_inc,
- unsigned *offset1,
- enum device_n_buffer_type ilace,
- u16 pic_width,
- u16 pic_height);
-
-void change_base_address(u32 offset, u16 *flag, int id);
-u16 *get_offset_cnt(int id, u32 *offset);
-int nature_of_hdmi(void);
+
+void change_base_address(int id, u32 p_uv_addr);
+bool is_hdmi_interlaced(void);
+
#endif
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index c986302aa368..32b267e00acd 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -1051,73 +1051,63 @@ int omapvid_apply_changes(struct omap_vout_device *vout)
return 0;
}
+/* This function inplements the interlace logic for VENC & ilace HDMI. It
+ * retruns '1' in case of a frame being completely displayed and signals to
+ * queue another frame whereas '0' means only half of the frame is only
+ * displayed and the remaing half is yet to be displayed */
static int interlace_display(struct omap_vout_device *vout, u32 irqstatus,
- struct timeval timevalue, u32 flags)
+ struct timeval timevalue)
{
- unsigned long fid;
+ unsigned long fid;
if (vout->first_int) {
vout->first_int = 0;
- spin_unlock_irqrestore(&vout->vbq_lock, flags);
return 0;
}
- if (irqstatus & DISPC_IRQ_EVSYNC_ODD) {
+ if (irqstatus & DISPC_IRQ_EVSYNC_ODD)
fid = 1;
- } else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN) {
+ else if (irqstatus & DISPC_IRQ_EVSYNC_EVEN)
fid = 0;
- } else {
- spin_unlock_irqrestore(&vout->vbq_lock, flags);
+ else
return 0;
- }
+
vout->field_id ^= 1;
if (fid != vout->field_id) {
- if (0 == fid)
- vout->field_id = fid;
-
- spin_unlock_irqrestore(&vout->vbq_lock, flags);
- return 0;
- }
- if (0 == fid) {
- if (vout->cur_frm == vout->next_frm) {
- spin_unlock_irqrestore(&vout->vbq_lock, flags);
+ /* reset field ID */
+ vout->field_id = 0;
+ } else if (0 == fid) {
+ if (vout->cur_frm == vout->next_frm)
return 0;
- }
+
vout->cur_frm->ts = timevalue;
vout->cur_frm->state = VIDEOBUF_DONE;
wake_up_interruptible(&vout->cur_frm->done);
vout->cur_frm = vout->next_frm;
- return 1;
- } else if (1 == fid) {
- if (list_empty(&vout->dma_queue) ||
- (vout->cur_frm != vout->next_frm)) {
- spin_unlock_irqrestore(&vout->vbq_lock, flags);
- return 0;
- }
- return 2;
- }
- return 3;
+ } else {
+ if (list_empty(&vout->dma_queue) ||
+ vout->cur_frm != vout->next_frm)
+ return 0;
+ }
+ return vout->field_id;
}
-static int i_to_p_base_address_change(struct omap_vout_device *vout,
- unsigned long flags)
+/* This returns the the infromation of level of completion of display of
+ the complete frame */
+static int i_to_p_base_address_change(struct omap_vout_device *vout)
{
- u16 *cnt;
- u32 offset;
+ struct omap_overlay *ovl;
+ struct omapvideo_info *ovid;
+ ovid = &(vout->vid_info);
+ ovl = ovid->overlays[0];
- struct omap_overlay *ovl;
- struct omapvideo_info *ovid;
+ if (vout->field_id == 0) {
+ change_base_address(ovl->id, ovl->info.p_uv_addr);
+ dispc_go(ovl->manager->device->channel);
+ }
+ vout->field_id ^= 1;
+ return vout->field_id;
+}
- ovid = &(vout->vid_info);
- ovl = ovid->overlays[0];
- cnt = get_offset_cnt(ovl->id, &offset);
- change_base_address(offset, cnt, ovl->id);
- if (*cnt == 1) {
- *cnt = 2;
- spin_unlock_irqrestore(&vout->vbq_lock, flags);
- return 1;
- }
- return 0;
-}
void omap_vout_isr(void *arg, unsigned int irqstatus)
{
@@ -1162,20 +1152,20 @@ void omap_vout_isr(void *arg, unsigned int irqstatus)
case OMAP_DISPLAY_TYPE_DSI:
if (!(irqstatus & irq))
goto vout_isr_err;
- else if (ovl->info.field == IBUF_PDEV) {
- if ((irq == DISPC_IRQ_FRAMEDONE) ||
- (irq == DISPC_IRQ_FRAMEDONE2)) {
- ret = i_to_p_base_address_change(vout, flags);
- if (ret == 1) {
- dispc_go(cur_display->channel);
- return;
- }
- }
+
+ /* display 2nd field for interlaced buffers if progressive */
+ if ((ovl->info.field & OMAP_FLAG_IBUF) &&
+ !(ovl->info.field & OMAP_FLAG_IDEV) &&
+ (irq == DISPC_IRQ_FRAMEDONE ||
+ irq == DISPC_IRQ_FRAMEDONE2)) {
+ if (i_to_p_base_address_change(vout))
+ goto vout_isr_err;
}
break;
case OMAP_DISPLAY_TYPE_DPI:
if (!(irqstatus & (DISPC_IRQ_VSYNC | DISPC_IRQ_VSYNC2)))
goto vout_isr_err;
+
#ifdef CONFIG_PANEL_PICO_DLP
if (dispc_go_busy(OMAP_DSS_CHANNEL_LCD2)) {
printk(KERN_INFO "dpi busy %d\n", cur_display->type);
@@ -1185,37 +1175,27 @@ void omap_vout_isr(void *arg, unsigned int irqstatus)
break;
#ifdef CONFIG_OMAP2_DSS_HDMI
case OMAP_DISPLAY_TYPE_HDMI:
- if (ovl->info.field == PBUF_PDEV) {
- if (!(irqstatus & DISPC_IRQ_EVSYNC_EVEN))
+ if (ovl->info.field & OMAP_FLAG_IDEV) {
+ if (interlace_display(vout, irqstatus, timevalue))
+ goto intlace;
+ else
goto vout_isr_err;
- } else if (ovl->info.field == IBUF_PDEV) {
+ } else if (ovl->info.field & OMAP_FLAG_IBUF) {
if (irqstatus & DISPC_IRQ_EVSYNC_EVEN) {
- ret = i_to_p_base_address_change(vout, flags);
- if (ret == 1) {
- dispc_go(cur_display->channel);
- return;
- }
- }
- } else if (ovl->info.field == IBUF_IDEV) {
- ret = interlace_display(vout, irqstatus,
- timevalue, flags);
- if (ret == 0)
- return;
- else if (ret == 1)
+ if (i_to_p_base_address_change(vout))
goto vout_isr_err;
- else if (ret == 2)
- goto intlace;
- }
- break;
+ }
+ } else {
+ if (!(irqstatus & DISPC_IRQ_EVSYNC_EVEN))
+ goto vout_isr_err;
+ }
+ break;
#else
case OMAP_DISPLAY_TYPE_VENC:
- ret = interlace_display(vout, irqstatus, timevalue, flags);
- if (ret == 0)
- return;
- else if (ret == 1)
- goto vout_isr_err;
- else if (ret == 2)
+ if (interlace_display(vout, irqstatus, timevalue))
goto intlace;
+ else
+ goto vout_isr_err;
#endif
default:
goto vout_isr_err;
@@ -1236,7 +1216,7 @@ wb:
intlace:
vout->next_frm = list_entry(vout->dma_queue.next,
- struct videobuf_buffer, queue);
+ struct videobuf_buffer, queue);
list_del(&vout->next_frm->queue);
vout->next_frm->state = VIDEOBUF_ACTIVE;
@@ -1890,9 +1870,8 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
struct omap_video_timings *timing;
struct omap_vout_device *vout = fh;
u16 multiplier = 1;
- u8 device_type = PROGRESSIVE;
- /* default is progressive buffer and progressive display */
- enum device_n_buffer_type dev_buf_type = PBUF_PDEV;
+ bool interlace = false;
+ enum device_n_buffer_type dev_buf_type;
if (vout->streaming)
return -EBUSY;
@@ -1912,25 +1891,53 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
/* validate the combination of input buffer & device type.
Code needs to be added for interlaced LCD display */
if (ovl->manager->device->type == OMAP_DISPLAY_TYPE_HDMI)
- device_type = nature_of_hdmi();
+ interlace = is_hdmi_interlaced();
- if (f->fmt.pix.field != V4L2_FIELD_NONE &&
- f->fmt.pix.field != V4L2_FIELD_SEQ_TB)
+ switch (f->fmt.pix.field) {
+ case V4L2_FIELD_ANY:
+ /* default to no interlacing */
f->fmt.pix.field = V4L2_FIELD_NONE;
- if ((f->fmt.pix.field == V4L2_FIELD_NONE) &&
- (device_type == PROGRESSIVE))
- dev_buf_type = PBUF_PDEV;
- else if ((f->fmt.pix.field == V4L2_FIELD_NONE) &&
- (device_type == INTERLACED))
- dev_buf_type = PBUF_IDEV;
- else if ((f->fmt.pix.field == V4L2_FIELD_SEQ_TB) &&
- (device_type == INTERLACED))
- dev_buf_type = IBUF_IDEV;
- else if ((f->fmt.pix.field == V4L2_FIELD_SEQ_TB) &&
- (device_type == PROGRESSIVE))
- dev_buf_type = IBUF_PDEV;
+ /* fall through to V4L2_FIELD_NONE */
+ case V4L2_FIELD_TOP:
+ case V4L2_FIELD_BOTTOM:
+ /* These are really non-interlaced, so treat as FIELD_NONE */
+
+ case V4L2_FIELD_NONE:
+ /* Treat progressive images as TB interleaved */
+
+ case V4L2_FIELD_INTERLACED:
+ case V4L2_FIELD_INTERLACED_TB:
+ /*
+ * We don't provide deinterlacing, so simply display these
+ * on progressive displays
+ */
+ dev_buf_type = interlace ? PBUF_IDEV : PBUF_PDEV;
+ break;
+
+ case V4L2_FIELD_INTERLACED_BT:
+ /* switch fields for interlaced buffers. We cannot display
+ these on progressive display */
+ if (!interlace)
+ return -EINVAL;
+ dev_buf_type = PBUF_IDEV_SWAP;
+ break;
+
+ case V4L2_FIELD_SEQ_TB:
+ dev_buf_type = interlace ? IBUF_IDEV : IBUF_PDEV;
+ break;
+
+ case V4L2_FIELD_SEQ_BT:
+ dev_buf_type = interlace ? IBUF_IDEV_SWAP : IBUF_PDEV_SWAP;
+ break;
+ case V4L2_FIELD_ALTERNATE:
+ /* no support for this format */
+ default:
+ return -EINVAL;
+ }
+
+ /* TODO: check if TILER ADAPTATION is needed here. */
/* We dont support RGB24-packed mode if vrfb rotation
* is enabled*/
if ((rotation_enabled(vout)) &&
@@ -1939,11 +1946,11 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
goto s_fmt_vid_out_exit;
}
- /* y resolution to be doubled in case of interlaced HDMI */
- if ((ovl->info.field == IBUF_IDEV) || (ovl->info.field == PBUF_IDEV))
+ /* get the framebuffer parameters */
+ /* y resolution to be doubled in case of interlaced output */
+ if (dev_buf_type & OMAP_FLAG_IDEV)
multiplier = 2;
- /* get the framebuffer parameters */
if (!cpu_is_omap44xx() && rotate_90_or_270(vout)) {
vout->fbuf.fmt.height = timing->x_res;
vout->fbuf.fmt.width = timing->y_res * multiplier;
@@ -1966,7 +1973,6 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
vout->pix = f->fmt.pix;
vout->vrfb_bpp = 1;
ovl->info.field = dev_buf_type;
- ovl->info.pic_width = f->fmt.pix.width;
ovl->info.pic_height = f->fmt.pix.height;
/* If YUYV then vrfb bpp is 2, for others its 1 */
@@ -2174,8 +2180,8 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
/* get the display device attached to the overlay */
timing = &ovl->manager->device->panel.timings;
- /* y resolution to be doubled in case of interlaced HDMI */
- if ((ovl->info.field == IBUF_IDEV) || (ovl->info.field == PBUF_IDEV))
+ /* y resolution to be doubled in case of interlaced output */
+ if (ovl->info.field & OMAP_FLAG_IDEV)
multiplier = 2;
if (rotate_90_or_270(vout)) {
diff --git a/drivers/media/video/omap/omap_wb.c b/drivers/media/video/omap/omap_wb.c
index ca7480de0de1..03f19bf82c39 100644
--- a/drivers/media/video/omap/omap_wb.c
+++ b/drivers/media/video/omap/omap_wb.c
@@ -606,6 +606,16 @@ static int omap_wb_tiler_buffer_setup(struct omap_wb_device *wb,
(void **) wb->buf_phy_uv_addr_alloced + start,
aligned);
} else {
+ unsigned int width = pix->width;
+ switch (video_mode_to_dss_mode(pix)) {
+ case OMAP_DSS_COLOR_UYVY:
+ case OMAP_DSS_COLOR_YUV2:
+ width /= 2;
+ bpp = 4;
+ break;
+ default:
+ break;
+ }
/* Only bpp of 1, 2, and 4 is supported by tiler */
fmt = (bpp == 1 ? TILFMT_8BIT :
bpp == 2 ? TILFMT_16BIT :
@@ -613,7 +623,7 @@ static int omap_wb_tiler_buffer_setup(struct omap_wb_device *wb,
if (fmt == TILFMT_INVALID)
return -ENOMEM;
- tiler_alloc_packed(&n_alloc, fmt, pix->width,
+ tiler_alloc_packed(&n_alloc, fmt, width,
pix->height,
(void **) wb->buf_phy_addr + start,
(void **) wb->buf_phy_addr_alloced + start,
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 2b23c75aa551..1eab132328b1 100755..100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -147,6 +147,7 @@ static void core_dump_clocks(struct seq_file *s)
seq_printf(s, "- CORE -\n");
seq_printf(s, "internal clk count\t\t%u\n", core.num_clks_enabled);
+ seq_printf(s, "mainclk count\t\t%u\n", dss_get_mainclk_state());
for (i = 0; i < 5; i++) {
if (!clocks[i])
@@ -302,6 +303,7 @@ static void dss_clk_enable_no_ctx(enum dss_clock clks)
{
unsigned num_clks = count_clk_bits(clks);
+ /* don't do aggressive clock cutting on OMAP4 */
if (cpu_is_omap44xx())
return;
@@ -328,11 +330,21 @@ void dss_clk_enable(enum dss_clock clks)
if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore())
restore_all_ctx();
}
-void dss_opt_clock_enable()
+
+int dss_opt_clock_enable()
{
- clk_enable(core.dss_ick);
- clk_enable(core.dss1_fck);
- clk_enable(core.dss_96m_fck);
+ int r = clk_enable(core.dss_ick);
+ if (!r) {
+ r = clk_enable(core.dss1_fck);
+ if (!r) {
+ r = clk_enable(core.dss_96m_fck);
+ if (!r)
+ return 0;
+ clk_disable(core.dss1_fck);
+ }
+ clk_disable(core.dss_ick);
+ }
+ return r;
}
void dss_opt_clock_disable()
@@ -472,8 +484,10 @@ struct regulator *dss_get_vdda_dac(void)
static void dss_debug_dump_clocks(struct seq_file *s)
{
core_dump_clocks(s);
- dss_dump_clocks(s);
- dispc_dump_clocks(s);
+ if (dss_get_mainclk_state()) {
+ dss_dump_clocks(s);
+ dispc_dump_clocks(s);
+ }
#ifdef CONFIG_OMAP2_DSS_DSI
dsi1_dump_clocks(s);
dsi2_dump_clocks(s);
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 0ab488f219f3..a53b509ccacb 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -202,13 +202,13 @@ void __iomem *dispc_base;
/* n=0: VID3, n=1: WB*/
/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} n=0: VID3, n=1: WB */
-#define DISPC_VID_V3_WB_FIR_COEF_H2(n, i) DISPC_REG(0x0730+(n)*0x6C+(i)*0x8)
+#define DISPC_VID_V3_WB_FIR_COEF_H2(n, i) DISPC_REG(0x0730+(n)*0x70+(i)*0x8)
/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
-#define DISPC_VID_V3_WB_FIR_COEF_HV2(n, i) DISPC_REG(0x0734+(n)*0x6C+(i)*0x8)
+#define DISPC_VID_V3_WB_FIR_COEF_HV2(n, i) DISPC_REG(0x0734+(n)*0x70+(i)*0x8)
/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
-#define DISPC_VID_V3_WB_FIR_COEF_V2(n, i) DISPC_REG(0x0770+(n)*0x6C+(i)*0x4)
+#define DISPC_VID_V3_WB_FIR_COEF_V2(n, i) DISPC_REG(0x0770+(n)*0x70+(i)*0x4)
/*********End Vid3 and WB Registers ***************/
@@ -1246,7 +1246,7 @@ static void _dispc_set_scale_coef(enum omap_plane plane, const s8 *hfir,
((vfir[16] << 16) & 0xFF0000) |
((vfir[24] << 24) & 0xFF000000));
v = ((vfir[0] & 0xFF) | ((vfir[32] << 8) & 0xFF00));
-
+
_dispc_write_firh_reg(plane, i, h);
_dispc_write_firhv_reg(plane, i, hv);
_dispc_write_firv_reg(plane, i, v);
@@ -1842,7 +1842,7 @@ static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
{
u32 val;
- struct dispc_reg ac1_reg[4] = { DISPC_VID_ACCU1(0),
+ struct dispc_reg ac1_reg[4] = { DISPC_VID_ACCU1(0),
DISPC_VID_ACCU1(1) };
if (cpu_is_omap44xx()){
@@ -2071,24 +2071,24 @@ static void _dispc_set_scaling(enum omap_plane plane,
BUG_ON(plane == OMAP_DSS_GFX);
if (scale_x) {
- fir_hinc = 1024 * (orig_width - 1) / (out_width - 1);
+ fir_hinc = (1024 * orig_width) / out_width;
if (fir_hinc > 4095)
fir_hinc = 4095;
hfir = get_scaling_coef(orig_width, out_width, 0, 0, 0);
} else {
- fir_hinc = 0;
- hfir = fir5_zero;
+ fir_hinc = 1024;
+ hfir = fir3_m8;
}
if (scale_y) {
- fir_vinc = 1024 * (orig_height - 1) / (out_height - 1);
+ fir_vinc = (1024 * orig_height) / out_height;
if (fir_vinc > 4095)
fir_vinc = 4095;
vfir = get_scaling_coef(orig_height, out_height, 0, 0,
three_taps);
- } else {
- fir_vinc = 0;
- vfir = fir5_zero;
+ } else {
+ fir_vinc = 1024;
+ vfir = fir3_m8;
}
_dispc_set_scale_coef(plane, hfir, vfir, three_taps);
@@ -2138,24 +2138,24 @@ static void _dispc_set_scaling_uv(enum omap_plane plane,
const s8 *hfir, *vfir;
if (scale_x) {
- fir_hinc = 1024 * (orig_width - 1) / (out_width - 1);
+ fir_hinc = (1024 * orig_width) / out_width;
if (fir_hinc > 4095)
fir_hinc = 4095;
hfir = get_scaling_coef(orig_width, out_width, 0, 0, 0);
} else {
- fir_hinc = 0;
- hfir = fir5_zero;
+ fir_hinc = 1024;
+ hfir = fir3_m8;
}
if (scale_y) {
- fir_vinc = 1024 * (orig_height - 1) / (out_height - 1);
+ fir_vinc = (1024 * orig_height) / out_height;
if (fir_vinc > 4095)
fir_vinc = 4095;
vfir = get_scaling_coef(orig_height, out_height, 0,
ilace, three_taps);
} else {
- fir_vinc = 0;
- vfir = fir5_zero;
+ fir_vinc = 1024;
+ vfir = fir3_m8;
}
for (i = 0; i < 8; i++, hfir++, vfir++) {
@@ -2174,25 +2174,30 @@ static void _dispc_set_scaling_uv(enum omap_plane plane,
if (three_taps && v)
printk(KERN_ERR "three_tap v is %x\n", v);
}
-
- /* set chroma resampling */
- REG_FLD_MOD(DISPC_VID_ATTRIBUTES2(plane - 1),
- (fir_hinc || fir_vinc) ? 1 : 0, 8, 8);
+ /* set chroma resampling. Not applicable for WB plane*/
+ if (plane != OMAP_DSS_WB)
+ REG_FLD_MOD(DISPC_VID_ATTRIBUTES2(plane - 1),
+ (fir_hinc || fir_vinc) ? 1 : 0, 8, 8);
/* set H scaling */
- REG_FLD_MOD(dispc_reg_att[plane], fir_hinc ? 1 : 0, 6, 6);
+ REG_FLD_MOD(dispc_reg_att[plane], fir_hinc ? 1 : 0, 5, 5);
/* set V scaling */
- REG_FLD_MOD(dispc_reg_att[plane], fir_vinc ? 1 : 0, 5, 5);
+ REG_FLD_MOD(dispc_reg_att[plane], fir_vinc ? 1 : 0, 6, 6);
_dispc_set_fir2(plane, fir_hinc, fir_vinc);
- if (ilace == IBUF_IDEV) {
+ if ((ilace & OMAP_FLAG_IBUF) &&
+ (ilace & OMAP_FLAG_IDEV)) {
accu0 = (-3 * fir_vinc / 4) % 1024;
accu1 = (-fir_vinc / 4) % 1024;
} else {
accu0 = accu1 = (-fir_vinc / 2) % 1024;
}
+
+ if (ilace & OMAP_FLAG_ISWAP)
+ swap(accu0, accu1);
+
accuh = (-fir_hinc / 2) % 1024;
_dispc_set_vid_accu2_0(plane, 0x80, 0);
@@ -2204,55 +2209,59 @@ static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
bool mirroring, enum omap_color_mode color_mode)
{
BUG_ON(plane == OMAP_DSS_WB);
- if (!cpu_is_omap44xx()) {
- if (color_mode == OMAP_DSS_COLOR_YUV2 ||
- color_mode == OMAP_DSS_COLOR_UYVY) {
- int vidrot = 0;
-
- if (mirroring) {
- switch (rotation) {
- case OMAP_DSS_ROT_0:
- vidrot = 2;
- break;
- case OMAP_DSS_ROT_90:
- vidrot = 1;
- break;
- case OMAP_DSS_ROT_180:
- vidrot = 0;
- break;
- case OMAP_DSS_ROT_270:
- vidrot = 3;
- break;
- }
- } else {
- switch (rotation) {
- case OMAP_DSS_ROT_0:
- vidrot = 0;
- break;
- case OMAP_DSS_ROT_90:
- vidrot = 1;
- break;
- case OMAP_DSS_ROT_180:
- vidrot = 2;
- break;
- case OMAP_DSS_ROT_270:
- vidrot = 3;
- break;
- }
+
+ if (color_mode == OMAP_DSS_COLOR_YUV2 ||
+ color_mode == OMAP_DSS_COLOR_UYVY) {
+ int vidrot = 0;
+
+ if (mirroring) {
+ switch (rotation) {
+ case OMAP_DSS_ROT_0:
+ vidrot = 2;
+ break;
+ case OMAP_DSS_ROT_90:
+ vidrot = 1;
+ break;
+ case OMAP_DSS_ROT_180:
+ vidrot = 0;
+ break;
+ case OMAP_DSS_ROT_270:
+ vidrot = 3;
+ break;
}
+ } else {
+ switch (rotation) {
+ case OMAP_DSS_ROT_0:
+ vidrot = 0;
+ break;
+ case OMAP_DSS_ROT_90:
+ vidrot = 1;
+ break;
+ case OMAP_DSS_ROT_180:
+ vidrot = 2;
+ break;
+ case OMAP_DSS_ROT_270:
+ vidrot = 3;
+ break;
+ }
+ }
- REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12);
+ REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12);
+ if (!cpu_is_omap44xx()) {
if (rotation == OMAP_DSS_ROT_90 ||
rotation == OMAP_DSS_ROT_270)
REG_FLD_MOD(dispc_reg_att[plane], 0x1, 18, 18);
else
REG_FLD_MOD(dispc_reg_att[plane], 0x0, 18, 18);
- } else {
- REG_FLD_MOD(dispc_reg_att[plane], 0, 13, 12);
- REG_FLD_MOD(dispc_reg_att[plane], 0, 18, 18);
}
- } else if (plane != OMAP_DSS_GFX) {
+ } else {
+ REG_FLD_MOD(dispc_reg_att[plane], 0, 13, 12);
+ if (!cpu_is_omap44xx())
+ REG_FLD_MOD(dispc_reg_att[plane], 0, 18, 18);
+ }
+
+ if (plane != OMAP_DSS_GFX) {
if (color_mode == OMAP_DSS_COLOR_NV12) {
/* DOUBLESTRIDE : 0 for 90-, 270-; 1 for 0- and 180- */
if (rotation == 1 || rotation == 3)
@@ -2260,12 +2269,6 @@ static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
else
REG_FLD_MOD(dispc_reg_att[plane], 0x1, 22, 22);
}
- /* Set the rotation value for pipeline */
- if (color_mode == OMAP_DSS_COLOR_UYVY ||
- color_mode == OMAP_DSS_COLOR_YUV2)
- REG_FLD_MOD(dispc_reg_att[plane], rotation, 13, 12);
- else
- REG_FLD_MOD(dispc_reg_att[plane], 0, 13, 12);
}
}
@@ -2311,19 +2314,18 @@ static s32 pixinc(int pixels, u8 ps)
BUG();
}
-void calc_tiler_row_rotation(u8 rotation,
+static void calc_tiler_row_rotation(u8 rotation,
u16 width,
enum omap_color_mode color_mode,
int y_decim,
s32 *row_inc,
unsigned *offset1,
enum device_n_buffer_type ilace,
- u16 pic_width,
u16 pic_height)
{
u8 ps = 1;
u32 line_size = 0;
- DSSDBG("calc_tiler_rot(%d): %d\n", rotation, width);
+ DSSDBG("calc_tiler_rot(%d): %dx%d\n", rotation, width, pic_height);
switch (color_mode) {
case OMAP_DSS_COLOR_RGB16:
@@ -2360,6 +2362,7 @@ void calc_tiler_row_rotation(u8 rotation,
case 1:
case 3:
+ /* input width/height already swapped for rotated frames */
line_size = (4 == ps) ? 16384 : 8192 ;
break;
@@ -2368,21 +2371,28 @@ void calc_tiler_row_rotation(u8 rotation,
return;
}
- *row_inc = line_size * y_decim + 1 - (width * ps) +
- ((ilace == PBUF_IDEV) ? (line_size * y_decim) : 0);
+ /* assume TB. We worry about swapping top/bottom outside of this call */
- if ((ilace == IBUF_IDEV) || (ilace == IBUF_PDEV))
+ if (ilace & OMAP_FLAG_IBUF) {
+ /* bottom half of image is the odd frame */
*offset1 = line_size * pic_height;
- else if (ilace == PBUF_IDEV)
- *offset1 = line_size;
+ } else if (ilace & OMAP_FLAG_IDEV) {
+ /* even and odd frames are interleaved */
+
+ /* offset1 is always at an odd line */
+ *offset1 = line_size * (y_decim | 1);
+ y_decim *= 2;
+ }
+ *row_inc = line_size * y_decim + 1 - (width * ps);
DSSDBG(" colormode: %d, rotation: %d, ps: %d, width: %d,"
- " row_inc:%d\n",
- color_mode, rotation, ps, width, *row_inc);
+ " height: %d, row_inc:%d\n",
+ color_mode, rotation, ps, width, pic_height, *row_inc);
return;
}
+
static void calc_vrfb_rotation_offset(u8 rotation, bool mirror,
u16 screen_width,
u16 width, u16 height,
@@ -2702,9 +2712,10 @@ int dispc_scaling_decision(u16 width, u16 height,
bool can_scale = plane != OMAP_DSS_GFX;
u16 in_width, in_height;
- unsigned long fclk = 0;
+ unsigned long fclk = 0, fclk5 = 0;
int min_factor, max_factor; /* decimation search limits */
int x, y; /* decimation search variables */
+ unsigned long fclk_max = dispc_fclk_rate();
/* restrict search region based on whether we can decimate */
if (!can_decimate_x) {
@@ -2720,9 +2731,6 @@ int dispc_scaling_decision(u16 width, u16 height,
if (min_y_decim > 1)
return -EINVAL;
min_y_decim = max_y_decim = 1;
- } else {
- if (max_y_decim > 16)
- max_y_decim = 16;
}
/*
@@ -2757,8 +2765,8 @@ int dispc_scaling_decision(u16 width, u16 height,
y < min_y_decim || y > max_y_decim)
goto loop;
- in_width = width / x;
- in_height = height / y;
+ in_width = DIV_ROUND_UP(width, x);
+ in_height = DIV_ROUND_UP(height, y);
if (in_width == out_width && in_height == out_height)
break;
@@ -2771,53 +2779,56 @@ int dispc_scaling_decision(u16 width, u16 height,
goto loop;
/* Must use 3-tap filter */
+ *three_tap = false;
if (!cpu_is_omap44xx())
*three_tap = in_width > 1024;
else if (omap_rev() == OMAP4430_REV_ES1_0)
*three_tap = in_width > 1280;
- else
- /* use 3-tap unless downscaling by more than 2 */
- *three_tap = out_height * 2 >= in_height;
-
- /* predecimation on OMAP4 still fetches the whole lines, so
- we multiply back the width (still closer than using width) */
- if (*three_tap) {
- fclk = calc_fclk(channel, in_width,
- in_height, out_width, out_height);
-
- /* Try 5-tap filter if 3-tap fclk is too high*/
- if (cpu_is_omap34xx() && in_height > out_height &&
- fclk > dispc_fclk_rate()) {
- printk(KERN_ERR
- "Should use 5 tap but cannot\n");
- }
- } else {
- fclk = calc_fclk_five_taps(channel,
- in_width, in_height,
- out_width, out_height, color_mode);
- }
+ /* Also use 3-tap if downscaling by 2 or less */
+ *three_tap |= out_height * 2 >= in_height;
+
+ /*
+ * Predecimation on OMAP4 still fetches the whole lines
+ * :TODO: How does it affect the required clock speed?
+ */
+ fclk = calc_fclk(channel, in_width, in_height,
+ out_width, out_height);
+ fclk5 = *three_tap ? 0 :
+ calc_fclk_five_taps(channel, in_width, in_height,
+ out_width, out_height, color_mode);
+
+ DSSDBG("%d*%d,%d*%d->%d,%d requires %lu(3T), %lu(5T) Hz\n",
+ in_width, x, in_height, y, out_width, out_height,
+ fclk, fclk5);
+
+ /* Use 3-tap if 5-tap clock requirement is too high */
+ *three_tap |= fclk5 > fclk_max;
+
+ /* for now we always use 5-tap unless 3-tap is required */
+ if (!*three_tap)
+ fclk = fclk5;
/* OMAP2/3 has a scaler size limitation */
if (!cpu_is_omap44xx() && in_width > (1024 << *three_tap))
goto loop;
DSSDBG("required fclk rate = %lu Hz\n", fclk);
- DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
+ DSSDBG("current fclk rate = %lu Hz\n", fclk_max);
- if (fclk > dispc_fclk_rate()) {
- DSSERR("failed to set up scaling, "
- "required fclk rate = %lu Hz, "
- "current fclk rate = %lu Hz\n",
- fclk, dispc_fclk_rate());
+ if (fclk > fclk_max)
goto loop;
- }
break;
loop:
/* err if exhausted search region */
- if (x == max_x_decim && y == max_y_decim)
+ if (x == max_x_decim && y == max_y_decim) {
+ DSSERR("failed to set up scaling, "
+ "required fclk rate = %lu Hz, "
+ "current fclk rate = %lu Hz\n",
+ fclk, fclk_max);
return -EINVAL;
+ }
/* get to next factor */
if (x == y) {
@@ -2847,7 +2858,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
u8 rotation, int mirror,
u8 global_alpha,
enum omap_channel channel, u32 puv_addr,
- u16 pic_width, u16 pic_height)
+ u16 pic_height)
{
bool fieldmode = 0;
int cconv = 0;
@@ -2862,20 +2873,22 @@ static int _dispc_setup_plane(enum omap_plane plane,
if (paddr == 0)
return -EINVAL;
+ /* NOTE: fieldmode is not used on OMAP4 -> neither for predecimation */
if (ilace && height == out_height)
fieldmode = 1;
- if ((ilace == IBUF_IDEV) || (ilace == IBUF_PDEV) ||
- (ilace == PBUF_IDEV)) {
+ if (ilace != PBUF_PDEV) {
#ifdef CONFIG_OMAP2_DSS_HDMI
+ /* HDMI output */
height /= 2;
#else
+ /* VENC output */
if (fieldmode)
height /= 2;
#endif
pos_y /= 2;
pic_height /= 2;
- if ((ilace == IBUF_IDEV) || (ilace == PBUF_IDEV))
+ if (ilace & OMAP_FLAG_IDEV)
out_height /= 2;
DSSDBG("adjusting for ilace: height %d, pos_y %d, "
@@ -2883,6 +2896,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
height, pos_y, out_height);
}
+ /* check if color format is supported */
if (plane == OMAP_DSS_GFX) {
switch (color_mode) {
case OMAP_DSS_COLOR_ARGB16:
@@ -2942,8 +2956,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
}
/* predecimate */
- width /= x_decim;
- height /= y_decim;
+ width = DIV_ROUND_UP(width, x_decim);
+ height = DIV_ROUND_UP(height, y_decim);
if (ilace && !fieldmode) {
/*
@@ -2962,83 +2976,85 @@ static int _dispc_setup_plane(enum omap_plane plane,
/* Fields are independent but interleaved in memory. */
if (fieldmode)
field_offset = 1;
- pix_inc = 0x1;
- offset0 = 0x0;
- offset1 = 0x0;
- if(cpu_is_omap44xx()) {
- /* check if tiler address; else set row_inc = 1*/
- if ((paddr >= 0x60000000) && (paddr <= 0x7fffffff)) {
- struct tiler_view_orient orient;
- u8 mir_x = 0, mir_y = 0;
- unsigned long tiler_width, tiler_height;
-
- pix_inc = 1 + (x_decim - 1) * bpp;
- calc_tiler_row_rotation(rotation, width * x_decim,
- color_mode, y_decim, &row_inc, &offset1,
- ilace, pic_width, pic_height);
-
- /* get rotated top-left coordinate
- (if rotation is applied before mirroring) */
- memset(&orient, 0, sizeof(orient));
+ /* default values */
+ row_inc = pix_inc = 0x1;
+ offset0 = offset1 = 0x0;
+
+ if (rotation_type == OMAP_DSS_ROT_TILER) {
+ struct tiler_view_orient orient = {0};
+ unsigned long tiler_width = width, tiler_height = height;
+ u8 mir_x = 0, mir_y = 0;
+ u8 tiler_rotation = rotation;
+
+ pix_inc = 1 + (x_decim - 1) * bpp;
+ calc_tiler_row_rotation(rotation, width * x_decim,
+ color_mode, y_decim, &row_inc,
+ &offset1, ilace, pic_height);
+
+ if (ilace & OMAP_FLAG_ISWAP)
+ swap(offset0, offset1);
+
+ /* mirroring is applied before rotataion */
+ if (tiler_rotation & 1)
+ tiler_rotation ^= 2;
+
+ tiler_rotate_view(&orient, tiler_rotation * 90);
+
+ if (mirror) {
if (rotation & 1)
- rotation ^= 2;
+ mir_x = 1;
+ else
+ mir_y = 1;
+ }
+ orient.x_invert ^= mir_x;
+ orient.y_invert ^= mir_y;
- tiler_rotate_view(&orient, rotation * 90);
+ DSSDBG("RXY = %d %d %d\n", orient.rotate_90,
+ orient.x_invert, orient.y_invert);
- if (mirror) {
- if (rotation & 1)
- mir_x = 1;
- else
- mir_y = 1;
- }
- orient.x_invert ^= mir_x;
- orient.y_invert ^= mir_y;
-
- DSSDBG("RXY = %d %d %d\n", orient.rotate_90,
- orient.x_invert, orient.y_invert);
-
- if (orient.rotate_90 & 1) {
- tiler_height = width;
- tiler_width = height;
- } else {
- tiler_height = height;
- tiler_width = width;
- }
+ if (orient.rotate_90 & 1)
+ swap(tiler_width, tiler_height);
- switch (color_mode) {
- case OMAP_DSS_COLOR_YUV2:
- case OMAP_DSS_COLOR_UYVY:
- tiler_width /= 2;
- break;
- default:
- break;
- }
- DSSDBG("w, h = %ld %ld\n", tiler_width, tiler_height);
+ if (color_mode == OMAP_DSS_COLOR_YUV2 ||
+ color_mode == OMAP_DSS_COLOR_UYVY)
+ tiler_width /= 2;
- paddr = tiler_reorient_topleft(tiler_get_natural_addr((void *)paddr),
+ DSSDBG("w, h = %ld %ld\n", tiler_width, tiler_height);
+
+ paddr = tiler_reorient_topleft(
+ tiler_get_natural_addr((void *)paddr),
orient, tiler_width, tiler_height);
+ if (puv_addr)
+ puv_addr = tiler_reorient_topleft(
+ tiler_get_natural_addr(
+ (void *) puv_addr), orient,
+ tiler_width/2, tiler_height/2);
+
+ /*
+ * BA1 used as temporary storage to pointer to lower
+ * half of interlaced buffer on progressive display
+ */
+ if ((ilace & OMAP_FLAG_IBUF) && !(ilace & OMAP_FLAG_IDEV)) {
+ dispc_write_reg(DISPC_VID_BA1(plane - 1),
+ paddr + offset1);
+ /* UV offset is 1/2 Y offset for even offsets */
if (puv_addr)
- puv_addr = tiler_reorient_topleft(
- tiler_get_natural_addr((void *)puv_addr),
- orient, tiler_width/2, tiler_height/2);
- DSSDBG("rotated addresses: 0x%0x, 0x%0x\n",
+ dispc_write_reg(DISPC_VID_BA_UV1(plane - 1),
+ puv_addr + offset1 / 2);
+ }
+ DSSDBG("rotated addresses: 0x%0x, 0x%0x\n",
paddr, puv_addr);
- /* set BURSTTYPE if rotation is non-zero */
- REG_FLD_MOD(dispc_reg_att[plane], 0x1, 29, 29);
- } else
- row_inc = 0x1;
- }
- if (!cpu_is_omap44xx()) {
- row_inc = 0x1;
- if (rotation_type == OMAP_DSS_ROT_DMA)
- calc_dma_rotation_offset(rotation, mirror,
+ /* set BURSTTYPE if rotation is non-zero */
+ REG_FLD_MOD(dispc_reg_att[plane], 0x1, 29, 29);
+ } else if (rotation_type == OMAP_DSS_ROT_DMA) {
+ calc_dma_rotation_offset(rotation, mirror,
screen_width, width, frame_height, color_mode,
fieldmode, field_offset,
&offset0, &offset1, &row_inc, &pix_inc);
- else
- calc_vrfb_rotation_offset(rotation, mirror,
+ } else if (rotation_type == OMAP_DSS_ROT_VRFB) {
+ calc_vrfb_rotation_offset(rotation, mirror,
screen_width, width, frame_height, color_mode,
fieldmode, field_offset,
&offset0, &offset1, &row_inc, &pix_inc);
@@ -3959,6 +3975,70 @@ void dispc_dump_regs(struct seq_file *s)
DUMPREG(DISPC_VID_SIZE(1));
DUMPREG(DISPC_VID_ATTRIBUTES(1));
DUMPREG(DISPC_VID_V3_WB_ATTRIBUTES(1));
+ DUMPREG(DISPC_VID_V3_WB_ACCU0(1));
+ DUMPREG(DISPC_VID_V3_WB_ACCU1(1));
+ DUMPREG(DISPC_VID_V3_WB_BA0(1));
+ DUMPREG(DISPC_VID_V3_WB_BA1(1));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_H(1, 0));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_H(1, 1));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_H(1, 2));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_H(1, 3));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_H(1, 4));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_H(1, 5));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_H(1, 6));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_H(1, 7));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_HV(1, 0));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_HV(1, 1));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_HV(1, 2));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_HV(1, 3));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_HV(1, 4));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_HV(1, 5));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_HV(1, 6));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_HV(1, 7));
+
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_H2(1, 0));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_H2(1, 1));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_H2(1, 2));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_H2(1, 3));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_H2(1, 4));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_H2(1, 5));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_H2(1, 6));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_H2(1, 7));
+
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_HV2(1, 0));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_HV2(1, 1));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_HV2(1, 2));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_HV2(1, 3));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_HV2(1, 4));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_HV2(1, 5));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_HV2(1, 6));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_HV2(1, 7));
+
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_V2(1, 0));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_V2(1, 1));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_V2(1, 2));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_V2(1, 3));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_V2(1, 4));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_V2(1, 5));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_V2(1, 6));
+ DUMPREG(DISPC_VID_V3_WB_FIR_COEF_V2(1, 7));
+
+ DUMPREG(DISPC_VID_V3_WB_BUF_SIZE_STATUS(1));
+ DUMPREG(DISPC_VID_V3_WB_BUF_THRESHOLD(1));
+ DUMPREG(DISPC_VID_V3_WB_FIR(1));
+ DUMPREG(DISPC_VID_V3_WB_PICTURE_SIZE(1));
+ DUMPREG(DISPC_VID_V3_WB_PIXEL_INC(1));
+ DUMPREG(DISPC_VID_V3_WB_ROW_INC(1));
+ DUMPREG(DISPC_VID_V3_WB_SIZE(1));
+ DUMPREG(DISPC_VID_V3_WB_FIR2(1));
+ DUMPREG(DISPC_VID_V3_WB_ACCU2_0(1));
+ DUMPREG(DISPC_VID_V3_WB_ACCU2_1(1));
+ DUMPREG(DISPC_VID_V3_WB_CONV_COEF(1, 0));
+ DUMPREG(DISPC_VID_V3_WB_CONV_COEF(1, 1));
+ DUMPREG(DISPC_VID_V3_WB_CONV_COEF(1, 2));
+ DUMPREG(DISPC_VID_V3_WB_CONV_COEF(1, 3));
+ DUMPREG(DISPC_VID_V3_WB_CONV_COEF(1, 4));
+
DUMPREG(DISPC_VID_FIFO_THRESHOLD(1));
DUMPREG(DISPC_VID_FIFO_SIZE_STATUS(1));
DUMPREG(DISPC_VID_ROW_INC(1));
@@ -4579,7 +4659,6 @@ static void dispc_error_worker(struct work_struct *work)
if (enable)
dssdev->driver->enable(dssdev);
}
-
}
if (errors & DISPC_IRQ_OCP_ERR) {
@@ -4678,7 +4757,7 @@ void dispc_fake_vsync_irq(enum omap_dsi_index ix)
DSSERR("Invalid display id for fake vsync\n");
return;
}
-
+
for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
struct omap_dispc_isr_data *isr_data;
isr_data = &dispc.registered_isr[i];
@@ -4808,24 +4887,24 @@ int dispc_enable_plane(enum omap_plane plane, bool enable)
}
int dispc_setup_plane(enum omap_plane plane,
- u32 paddr, u16 screen_width,
- u16 pos_x, u16 pos_y,
- u16 width, u16 height,
- u16 out_width, u16 out_height,
- enum omap_color_mode color_mode,
- enum device_n_buffer_type ilace,
- int x_decim, int y_decim, bool three_tap,
- enum omap_dss_rotation_type rotation_type,
- u8 rotation, bool mirror, u8 global_alpha,
- enum omap_channel channel, u32 puv_addr,
- u16 pic_width, u16 pic_height)
+ u32 paddr, u16 screen_width,
+ u16 pos_x, u16 pos_y,
+ u16 width, u16 height,
+ u16 out_width, u16 out_height,
+ enum omap_color_mode color_mode,
+ enum device_n_buffer_type ilace,
+ int x_decim, int y_decim, bool three_tap,
+ enum omap_dss_rotation_type rotation_type,
+ u8 rotation, bool mirror, u8 global_alpha,
+ enum omap_channel channel, u32 puv_addr,
+ u16 pic_height)
{
int r = 0;
DSSDBG("dispc_setup_plane %d, pa %x, sw %d, %d,%d, %dx%d -> %dx%d, "
- "ilace %d, decim %dx%d, %d-tap, cmode %x, rot %d, mir %d "
- "chan %d\n",
+ "ilace %d, decim %dx%d, %d-tap, cmode %x, rot %d, mir %d "
+ "chan %d\n",
plane, paddr, screen_width, pos_x, pos_y,
width, height,
out_width, out_height,
@@ -4844,33 +4923,33 @@ int dispc_setup_plane(enum omap_plane plane,
rotation, mirror,
global_alpha,
channel, puv_addr,
- pic_width, pic_height);
+ pic_height);
enable_clocks(0);
return r;
}
-void change_base_address(u32 offset, u16 *flag, int id)
+/* retrives the new adress from BA1 and puts it into BA0 */
+void change_base_address(int plane, u32 p_uv_addr)
+
{
- u32 val;
- if (*flag == 0) {
- val = dispc_read_reg(DISPC_VID_BA0(id - 1));
- dispc_write_reg(DISPC_VID_BA0(id - 1), val+offset);
- val = dispc_read_reg(DISPC_VID_BA_UV0(id - 1));
- dispc_write_reg(DISPC_VID_BA_UV0(id - 1), val+offset);
- *flag = *flag + 1;
- }
+ u32 val;
+ val = dispc_read_reg(DISPC_VID_BA1(plane - 1));
+ dispc_write_reg(DISPC_VID_BA0(plane - 1), val);
+ if (p_uv_addr) {
+ val = dispc_read_reg(DISPC_VID_BA_UV1(plane - 1));
+ dispc_write_reg(DISPC_VID_BA_UV0(plane - 1), val);
+ }
}
/* Writeback*/
int dispc_setup_wb(struct writeback_cache_data *wb)
{
- unsigned long mir_x, mir_y;
unsigned long tiler_width, tiler_height;
- u8 orientation = 0, rotation = 0, mirror = 0 ;
+ u8 rotation = 0, mirror = 0 ;
int ch_width, ch_height, out_ch_width, out_ch_height, scale_x, scale_y;
- struct tiler_view_orient orient;
+ struct tiler_view_orient orient = {0};
u32 paddr = wb->paddr;
u32 puv_addr = wb->puv_addr; /* relevant for NV12 format only */
u16 out_width = wb->width;
@@ -4880,7 +4959,7 @@ int dispc_setup_wb(struct writeback_cache_data *wb)
unsigned offset1 = 0;
enum device_n_buffer_type ilace = PBUF_PDEV;
- u16 pic_width = 0, pic_height = 0;/* not required in case
+ u16 pic_height = 0;/* not required in case
of progressive cases */
enum omap_color_mode color_mode = wb->color_mode; /* output color */
@@ -4981,38 +5060,37 @@ int dispc_setup_wb(struct writeback_cache_data *wb)
pix_inc = 0x1;
if ((paddr >= 0x60000000) && (paddr <= 0x7fffffff)) {
+ u8 mir_x = 0, mir_y = 0;
+ tiler_width = out_width, tiler_height = out_height;
+
calc_tiler_row_rotation(rotation, out_width,
color_mode, 1, /* y_decim = 1 */
&row_inc,
&offset1, ilace,
- pic_width, pic_height);
+ pic_height);
+
+ /* mirroring is applied before rotataion */
+ /* mirroring is applied before rotataion */
+ if (rotation & 1)
+ rotation ^= 2;
- orientation = calc_tiler_orientation(rotation, (u8)mirror);
- /* get rotated top-left coordinate
- (if rotation is applied before mirroring) */
- memset(&orient, 0, sizeof(orient));
tiler_rotate_view(&orient, rotation * 90);
if (mirror) {
- /* Horizontal mirroring */
- if (rotation == 1 || rotation == 3)
+ if (rotation & 1)
mir_x = 1;
else
mir_y = 1;
- } else {
- mir_x = 0;
- mir_y = 0;
}
orient.x_invert ^= mir_x;
orient.y_invert ^= mir_y;
- if (orient.rotate_90 & 1) {
- tiler_height = width;
- tiler_width = height;
- } else {
- tiler_height = height;
- tiler_width = width;
- }
+ if (orient.rotate_90 & 1)
+ swap(tiler_width, tiler_height);
+
+ if (color_mode == OMAP_DSS_COLOR_YUV2 ||
+ color_mode == OMAP_DSS_COLOR_UYVY)
+ tiler_width /= 2;
paddr = tiler_reorient_topleft(tiler_get_natural_addr((void *)paddr),
orient, tiler_width, tiler_height);
@@ -5021,10 +5099,11 @@ int dispc_setup_wb(struct writeback_cache_data *wb)
puv_addr = tiler_reorient_topleft(
tiler_get_natural_addr((void *)puv_addr),
orient, tiler_width/2, tiler_height/2);
- DSSDBG("rotated addresses: 0x%0x, 0x%0x\n",
+
+ DSSDBG("rotated addresses: 0x%0x, 0x%0x\n",
paddr, puv_addr);
- /* set BURSTTYPE if rotation is non-zero */
- REG_FLD_MOD(dispc_reg_att[plane], 0x1, 8, 8);
+ /* set BURSTTYPE if rotation is non-zero */
+ REG_FLD_MOD(dispc_reg_att[plane], 0x1, 8, 8);
} else
row_inc = 1;
@@ -5036,6 +5115,12 @@ int dispc_setup_wb(struct writeback_cache_data *wb)
if (OMAP_DSS_COLOR_NV12 == color_mode) {
_dispc_set_plane_ba_uv0(plane, puv_addr);
_dispc_set_plane_ba_uv1(plane, puv_addr);
+
+ /* DOUBLESTRIDE : 0 for 90-, 270-; 1 for 0- and 180- */
+ if (rotation == 1 || rotation == 3)
+ REG_FLD_MOD(dispc_reg_att[plane], 0x0, 22, 22);
+ else
+ REG_FLD_MOD(dispc_reg_att[plane], 0x1, 22, 22);
}
_dispc_set_row_inc(plane, row_inc);
_dispc_set_pix_inc(plane, pix_inc);
@@ -5080,9 +5165,9 @@ int dispc_setup_wb(struct writeback_cache_data *wb)
out_width, out_height,
0, three_taps, false, scale_x, scale_y);
- if (ch_width != width) {
+ if (out_ch_width != out_width) {
/* this is true for YUV formats */
- printk(KERN_ERR "scale uv set");
+ DSSDBG("scale uv set");
_dispc_set_scaling_uv(plane, ch_width, ch_height,
out_ch_width, out_ch_height, 0,
three_taps, false, scale_x, scale_y);
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index aa6dc7578abf..d2b0b690194d 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -601,8 +601,12 @@ static int dss_resume_device(struct device *dev, void *data)
if (dssdev->activate_after_resume && dssdev->driver->resume) {
r = dssdev->driver->resume(dssdev);
- if (r)
+ if (r) {
+ DSSERR("Failed to resume %s device (%d), disabling\n",
+ dssdev->name, r);
+ dssdev->driver->disable(dssdev);
return r;
+ }
}
dssdev->activate_after_resume = false;
@@ -628,7 +632,10 @@ static int dss_check_state_disabled(struct device *dev, void *data)
return -EINVAL;
}
-/* disables mainclk if all devices are suspended /disabled */
+/*
+ * Checks if all devices are suspended/disabled.
+ * Disables mainclk (DSS clocks on OMAP4) if true and do_clk_disable is true.
+ */
int dss_mainclk_state_disable(bool do_clk_disable)
{
int r;
@@ -637,8 +644,8 @@ int dss_mainclk_state_disable(bool do_clk_disable)
r = bus_for_each_dev(bus, NULL, NULL, dss_check_state_disabled);
if (r) {
- /* All devices are not disabled /suspended */
- return -EINVAL;
+ /* Some devices are not disabled/suspended */
+ return -EBUSY;
} else {
if (do_clk_disable) {
save_all_ctx();
@@ -648,7 +655,11 @@ int dss_mainclk_state_disable(bool do_clk_disable)
}
}
-/* enables mainclk if all devices are suspended /disabled */
+/*
+ * enables mainclk (DSS clocks on OMAP4 if all devices are either in disabled or
+ * suspended state before calling this function.
+ * Returns 0 on success.
+ */
int dss_mainclk_state_enable(void)
{
int r;
@@ -661,7 +672,7 @@ int dss_mainclk_state_enable(void)
return -EINVAL;
} else {
r = dss_mainclk_enable();
- if (!r)
+ if (r >= 0)
restore_all_ctx();
return 0;
}
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 3469e38d4fb0..a9f61bd038ec 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -134,6 +134,13 @@ void dss_restore_context(void)
#undef SR
#undef RR
+/*
+ * OMAP4 does not allow aggressive DSS clock cutting, so we must keep the
+ * clocks enabled during display use. These next two methods on OMAP4
+ * increment and decrement the global mainclk counter. The needed opt
+ * clocks are enabled once during bootup and then handled by the pm
+ * framework.
+ */
bool dss_get_mainclk_state()
{
return dss.mainclk_state;
@@ -141,20 +148,22 @@ bool dss_get_mainclk_state()
int dss_mainclk_enable()
{
+ int ret = 0;
+
if (!dss.mainclk_state) {
- pm_runtime_get_sync(&dss.pdev->dev);
- dss.mainclk_state = true;
- return 0;
+ ret = pm_runtime_get_sync(&dss.pdev->dev);
+ if (ret >= 0)
+ dss.mainclk_state = true;
}
- return -EINVAL;
+ return ret;
}
void dss_mainclk_disable()
{
if (dss.mainclk_state) {
- pm_runtime_put_sync(&dss.pdev->dev);
dss.mainclk_state = false;
+ pm_runtime_put_sync(&dss.pdev->dev);
}
}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 6e51020b99f5..569d0b2012e3 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -226,7 +226,7 @@ struct bus_type *dss_get_bus(void);
struct regulator *dss_get_vdds_dsi(void);
struct regulator *dss_get_vdds_sdi(void);
struct regulator *dss_get_vdda_dac(void);
-void dss_opt_clock_enable(void);
+int dss_opt_clock_enable(void);
void dss_opt_clock_disable(void);
void save_all_ctx(void);
void restore_all_ctx(void);
@@ -462,7 +462,7 @@ int dispc_setup_plane(enum omap_plane plane,
enum omap_dss_rotation_type rotation_type,
u8 rotation, bool mirror,
u8 global_alpha, enum omap_channel channel,
- u32 puv_addr, u16 pic_width, u16 pic_height);
+ u32 puv_addr, u16 pic_height);
bool dispc_go_busy(enum omap_channel channel);
void dispc_go(enum omap_channel channel);
diff --git a/drivers/video/omap2/dss/edid.c b/drivers/video/omap2/dss/edid.c
index fbfbd415129e..68daf042054f 100644
--- a/drivers/video/omap2/dss/edid.c
+++ b/drivers/video/omap2/dss/edid.c
@@ -41,7 +41,7 @@
/*This is the structure which has all supported timing values that OMAP4 supports*/
-const struct omap_video_timings omap_hdmi_timings[31] = {
+const struct omap_video_timings omap_hdmi_timings[32] = {
{640, 480, 25200, 96, 16, 48, 2, 10, 33},
{1280, 720, 74250, 40, 440, 220, 5, 5, 20},
{1280, 720, 74250, 40, 110, 220, 5, 5, 20},
@@ -60,7 +60,7 @@ const struct omap_video_timings omap_hdmi_timings[31] = {
{640, 480, 25175, 96, 16, 48, 2 , 11, 31},
{800, 600, 40000, 128, 40, 88, 4 , 1, 23},
{848, 480, 33750, 112, 16, 112, 8 , 6, 23},
- {1280, 768, 71000, 128, 64, 192, 7 , 3, 20},
+ {1280, 768, 79500, 128, 64, 192, 7 , 3, 20},
{1280, 800, 83500, 128, 72, 200, 6 , 3, 22},
{1360, 768, 85500, 112, 64, 256, 6 , 3, 18},
{1280, 960, 108000, 112, 96, 312, 3 , 1, 36},
@@ -73,7 +73,8 @@ const struct omap_video_timings omap_hdmi_timings[31] = {
{1920, 1080, 148500, 44, 88, 80, 5, 4, 36},
{1280, 768, 68250, 32, 48, 80, 7, 3, 12},
{1400, 1050, 101000, 32, 48, 80, 4, 3, 23},
- {1680, 1050, 119000, 32, 48, 80, 6, 3, 21} } ;
+ {1680, 1050, 119000, 32, 48, 80, 6, 3, 21},
+ {1280, 800, 79500, 32, 48, 80, 6, 3, 14} } ;
int get_edid_timing_info(union HDMI_EDID_DTD *edid_dtd, struct omap_video_timings *timings)
{
@@ -137,7 +138,7 @@ int get_edid_timing_info(union HDMI_EDID_DTD *edid_dtd, struct omap_video_timing
* support VESA timings? My monitor at home would pick 1920x1080 * otherwise, but that seems to not work well (monitor blanks out and * comes back, and picture doesn't fill full screen, but leaves a black * bar on left (native res is 2048x1152). However if I only consider
* VESA timings, it picks 1680x1050 and the picture is stable and fills * whole screen..
*/
- for (i = 14; i < 31; i++) {
+ for (i = 14; i < 32; i++) {
const struct omap_video_timings *timings =
&omap_hdmi_timings[i];
int hz, hscan, pixclock;
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index c1fa2d39d4c9..8106f1947fd2 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -113,8 +113,13 @@ enum hdmi_ioctl_cmds {
#define HDMI_TXPHY_POWER_CTRL 0x8ul
#define HDMI_TXPHY_PAD_CFG_CTRL 0xCul
+struct hdmi_hvsync_pol {
+ int vsync_pol;
+ int hsync_pol;
+};
+
/*This is the structure which has all supported timing values that OMAP4 supports*/
-const struct omap_video_timings all_timings_direct[31] = {
+const struct omap_video_timings all_timings_direct[32] = {
{640, 480, 25200, 96, 16, 48, 2, 10, 33},
{1280, 720, 74250, 40, 440, 220, 5, 5, 20},
{1280, 720, 74250, 40, 110, 220, 5, 5, 20},
@@ -133,7 +138,7 @@ const struct omap_video_timings all_timings_direct[31] = {
{640, 480, 25175, 96, 16, 48, 2 , 11, 31},
{800, 600, 40000, 128, 40, 88, 4 , 1, 23},
{848, 480, 33750, 112, 16, 112, 8 , 6, 23},
- {1280, 768, 71000, 128, 64, 192, 7 , 3, 20},
+ {1280, 768, 79500, 128, 64, 192, 7 , 3, 20},
{1280, 800, 83500, 128, 72, 200, 6 , 3, 22},
{1360, 768, 85500, 112, 64, 256, 6 , 3, 18},
{1280, 960, 108000, 112, 96, 312, 3 , 1, 36},
@@ -146,13 +151,25 @@ const struct omap_video_timings all_timings_direct[31] = {
{1920, 1080, 148500, 44, 88, 80, 5, 4, 36},
{1280, 768, 68250, 32, 48, 80, 7, 3, 12},
{1400, 1050, 101000, 32, 48, 80, 4, 3, 23},
- {1680, 1050, 119000, 32, 48, 80, 6, 3, 21} };
+ {1680, 1050, 119000, 32, 48, 80, 6, 3, 21},
+ {1280, 800, 79500, 32, 48, 80, 6, 3, 14} };
/*This is a static Mapping array which maps the timing values with corresponding CEA / VESA code*/
-int code_index[31] = {1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35,
+int code_index[32] = {1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35,
/* <--14 CEA 17--> vesa*/
4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A,
- 0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39};
+ 0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B};
+
+/*Static mapping of the Timing values with the corresponding Vsync and Hsync polarity*/
+const struct hdmi_hvsync_pol hvpol_mapping[32] = {
+ {0, 0}, {1, 1}, {1, 1}, {0, 0},
+ {0, 0}, {0, 0}, {0, 0}, {1, 1},
+ {1, 1}, {1, 1}, {0, 0}, {0, 0},
+ {1, 1}, {0, 0}, {0, 0}, {1, 1},
+ {1, 1}, {1, 0}, {1, 0}, {1, 1},
+ {1, 1}, {1, 1}, {0, 0}, {1, 0},
+ {1, 0}, {1, 0}, {1, 1}, {1, 1},
+ {0, 1}, {0, 1}, {0, 1}, {0, 1} };
/*This is revere static mapping which maps the CEA / VESA code to the corresponding timing values*/
/* note: table is 10 entries per line to make it easier to find index.. */
@@ -166,7 +183,7 @@ int code_cea[39] = {
int code_vesa[83] = {
-1, -1, -1, -1, 14, -1, -1, -1, -1, 15,
-1, -1, -1, -1, 16, -1, 22, -1, -1, -1,
- -1, -1, 28, 17, -1, -1, -1, -1, 18, -1,
+ -1, -1, 28, 17, -1, -1, -1, 31, 18, -1,
-1, -1, 20, -1, -1, 21, -1, -1, -1, 19,
-1, 29, 23, -1, -1, -1, -1, 24, -1, -1,
-1, -1, -1, -1, -1, -1, -1, 30, 25, -1,
@@ -204,8 +221,12 @@ static void update_cfg (struct hdmi_config *cfg, struct omap_video_timings *timi
cfg->vfp = timings->vfp;
cfg->vsw = timings->vsw;
cfg->pixel_clock = timings->pixel_clock;
- cfg->v_pol = 1; // XXX get this from EDID
- cfg->h_pol = 1; // XXX get this from EDID
+}
+
+static void update_cfg_pol(struct hdmi_config *cfg, int code)
+{
+ cfg->v_pol = hvpol_mapping[code].vsync_pol;
+ cfg->h_pol = hvpol_mapping[code].hsync_pol;
}
static inline void hdmi_write_reg(u32 base, u16 idx, u32 val)
@@ -812,6 +833,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
}
update_cfg(&hdmi.cfg, p);
+ update_cfg_pol(&hdmi.cfg, code);
code = get_timings_index();
dssdev->panel.timings = all_timings_direct[code];
@@ -1262,7 +1284,7 @@ static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
struct hdmi_cm cm = {-1};
DSSDBG("hdmi_get_code");
- for (i = 0; i < 31; i++) {
+ for (i = 0; i < 32; i++) {
temp = all_timings_direct[i];
if ((temp.pixel_clock == timing->pixel_clock) &&
(temp.x_res == timing->x_res) &&
@@ -1560,19 +1582,7 @@ static int get_edid_timing_data(struct HDMI_EDID *edid)
}
-int nature_of_hdmi(void)
+bool is_hdmi_interlaced(void)
{
- if ((hdmi.mode)) {
- switch (hdmi.code) {
- case 5:
- case 6:
- case 20:
- case 21:
- return INTERLACED;
- default:
- return PROGRESSIVE;
- }
- }
- return PROGRESSIVE;
+ return hdmi.cfg.interlace;
}
-
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index c8a2f1ba7bad..2809dcd3c722 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -420,11 +420,7 @@ struct overlay_cache_data {
bool manual_update;
enum omap_overlay_zorder zorder;
u32 p_uv_addr; /* relevent for NV12 format only */
- u16 pic_width; /* for ilace */
u16 pic_height; /* for ilace */
- u32 ibufpdev_offset; /* for ilace buffer &
- progressive display device offset*/
- u16 ibufpdev_flag; /* for ilace buffer and progressive display device */
};
struct manager_cache_data {
@@ -799,6 +795,9 @@ static int configure_overlay(enum omap_plane plane)
}
switch (c->color_mode) {
+ case OMAP_DSS_COLOR_NV12:
+ bpp = 8;
+ break;
case OMAP_DSS_COLOR_RGB16:
case OMAP_DSS_COLOR_ARGB16:
case OMAP_DSS_COLOR_YUV2:
@@ -864,28 +863,13 @@ static int configure_overlay(enum omap_plane plane)
w -= 1;
}
}
- if (cpu_is_omap44xx()){
- if ((paddr >= 0x60000000) && (paddr <= 0x7fffffff)) {
- u16 height, pic_height;
- s32 row_inc;
- if (c->ilace == IBUF_PDEV) {
- height = h/2;
- pic_height = c->pic_height/2;
-
- calc_tiler_row_rotation(c->rotation,
- w, height, c->color_mode, &row_inc,
- &c->ibufpdev_offset, c->ilace, c->pic_width,
- pic_height);
-
- c->ibufpdev_flag = 0;
- }
- }
- }
+
r = dispc_scaling_decision(w, h, outw, outh,
plane, c->color_mode, c->channel,
c->rotation, c->min_x_decim, c->max_x_decim,
c->min_y_decim, c->max_y_decim,
&x_decim, &y_decim, &three_tap);
+
r = r ? : dispc_setup_plane(plane,
paddr,
c->screen_width,
@@ -900,7 +884,6 @@ static int configure_overlay(enum omap_plane plane)
c->global_alpha,
c->channel,
c->p_uv_addr,
- c->pic_width,
c->pic_height);
if (r) {
@@ -1045,9 +1028,11 @@ static int configure_dispc(void)
/* Do nothing as of now as we dont
* support Manager yet with WB
*/
+ /*WB GO bit has to be used only in case of
+ capture mode and not in memory mode*/
+ dispc_go_wb();
break;
}
- dispc_go_wb();
wb->shadow_dirty = false;
dispc_enable_plane(OMAP_DSS_WB, 1);
}
@@ -1298,8 +1283,8 @@ static void dss_apply_irq_handler(void *data, u32 mask)
omap_dispc_unregister_isr(dss_apply_irq_handler, NULL,
DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
- DISPC_IRQ_EVSYNC_EVEN | (cpu_is_omap44xx()) ?
- DISPC_IRQ_VSYNC2 : 0);
+ DISPC_IRQ_EVSYNC_EVEN | ((cpu_is_omap44xx()) ?
+ DISPC_IRQ_VSYNC2 : 0));
dss_cache.irq_enabled = false;
end:
@@ -1371,7 +1356,6 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
oc->screen_width = ovl->info.screen_width;
oc->width = ovl->info.width;
oc->height = ovl->info.height;
- oc->pic_width = ovl->info.pic_width;
oc->pic_height = ovl->info.pic_height;
oc->color_mode = ovl->info.color_mode;
oc->rotation = ovl->info.rotation;
@@ -1509,7 +1493,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
r = omap_dispc_register_isr(dss_apply_irq_handler, NULL,
DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
DISPC_IRQ_EVSYNC_EVEN |
- (cpu_is_omap44xx()) ? DISPC_IRQ_VSYNC2 : 0);
+ ((cpu_is_omap44xx()) ? DISPC_IRQ_VSYNC2 : 0));
dss_cache.irq_enabled = true;
}
configure_dispc();
@@ -1989,15 +1973,6 @@ int omap_dss_get_num_overlay_managers(void)
return num_managers;
}
-u16 *get_offset_cnt(int id, u32 *offset)
-{
- struct overlay_cache_data *oc;
- oc = &dss_cache.overlay_cache[id];
- *offset = oc->ibufpdev_offset;
- return &oc->ibufpdev_flag;
-
-}
-
EXPORT_SYMBOL(omap_dss_get_num_overlay_managers);
struct omap_overlay_manager *omap_dss_get_overlay_manager(int num)
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 896319232e18..6b461e83b297 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -279,7 +279,6 @@ static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
return size;
}
-
static ssize_t overlay_decim_show(u16 min, u16 max, char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d..%d\n", min, max);
@@ -303,13 +302,10 @@ static ssize_t overlay_decim_store(u16 *min, u16 *max,
char *last;
*min = *max = simple_strtoul(buf, &last, 10);
- if (last < buf + size) {
+ if (last < buf + size && *last == '.') {
/* check for .. separator */
- if (last + 2 >= buf + size ||
- last[0] != '.' ||
- last[1] != '.') {
+ if (last + 2 >= buf + size || last[1] != '.')
return -EINVAL;
- }
*max = simple_strtoul(last + 2, &last, 10);
@@ -604,6 +600,10 @@ static int omap_dss_set_manager(struct omap_overlay *ovl,
ovl->manager = mgr;
+ /* do not set channel out if DSS is off */
+ if (!dss_get_mainclk_state())
+ return 0;
+
dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
/* XXX: on manual update display, in auto update mode, a bug happens
* here. When an overlay is first enabled on LCD, then it's disabled,
@@ -814,7 +814,7 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
mgr = lcd2_mgr;
}
} else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
- && dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
+ && dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
if (!lcd_mgr->device || force) {
if (lcd_mgr->device)
lcd_mgr->unset_device(lcd_mgr);