* [PATCH 06/21] OMAPDSS: DISPC: Pass overlay caps as a parameter to dispc plane functions
From: Archit Taneja @ 2012-09-13 12:26 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
Currently, the functions below take the omap_plane parameter and derive the
overlay caps within them. Pass the overlay caps as a parameter to the function
to allow these to be used by writeback too.
- dispc_plane_set_zorder()
- dispc_plane_set_pre_mult_alpha()
- dispc_plane_setup_global_alpha()
- dispc_plane_calc_scaling()
- dispc_ovl_setup()
These functions will be used for writeback later, and the caps will help in
deciding if they are to be used for writeback or not. This allows reuse of
overlay caps for writeback.
Using omap_overlay_caps for writeback seems a bit incorrect, but caps is
something already in use by users of OMAPDSS(omapfb/omap_vout), so we use
overlay caps for overlay like features of writeback too.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 40 +++++++++++++++++++--------------------
1 file changed, 19 insertions(+), 21 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index f60fcf4..3a0a576 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -733,11 +733,10 @@ static void dispc_plane_set_output_size(enum omap_plane plane, int width,
dispc_write_reg(DISPC_OVL_SIZE(plane), val);
}
-static void dispc_plane_set_zorder(enum omap_plane plane, u8 zorder)
+static void dispc_plane_set_zorder(enum omap_plane plane,
+ enum omap_overlay_caps caps, u8 zorder)
{
- struct omap_overlay *ovl = omap_dss_get_overlay(plane);
-
- if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) = 0)
+ if ((caps & OMAP_DSS_OVL_CAP_ZORDER) = 0)
return;
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), zorder, 27, 26);
@@ -754,24 +753,22 @@ static void dispc_ovl_enable_zorder_planes(void)
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25);
}
-static void dispc_plane_set_pre_mult_alpha(enum omap_plane plane, bool enable)
+static void dispc_plane_set_pre_mult_alpha(enum omap_plane plane,
+ enum omap_overlay_caps caps, bool enable)
{
- struct omap_overlay *ovl = omap_dss_get_overlay(plane);
-
- if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) = 0)
+ if ((caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) = 0)
return;
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28);
}
static void dispc_plane_setup_global_alpha(enum omap_plane plane,
- u8 global_alpha)
+ enum omap_overlay_caps caps, u8 global_alpha)
{
static const unsigned shifts[] = { 0, 8, 16, 24, };
int shift;
- struct omap_overlay *ovl = omap_dss_get_overlay(plane);
- if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) = 0)
+ if ((caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) = 0)
return;
shift = shifts[plane];
@@ -2200,13 +2197,12 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
}
static int dispc_plane_calc_scaling(enum omap_plane plane,
- enum omap_channel channel,
+ enum omap_overlay_caps caps, enum omap_channel channel,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
int *x_predecim, int *y_predecim, u16 pos_x)
{
- struct omap_overlay *ovl = omap_dss_get_overlay(plane);
const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
const int max_decim_limit = 16;
unsigned long core_clk = 0;
@@ -2215,7 +2211,7 @@ static int dispc_plane_calc_scaling(enum omap_plane plane,
if (width = out_width && height = out_height)
return 0;
- if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) = 0)
+ if ((caps & OMAP_DSS_OVL_CAP_SCALE) = 0)
return -EINVAL;
*x_predecim = max_decim_limit;
@@ -2266,6 +2262,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
bool replication, const struct omap_video_timings *mgr_timings)
{
struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+ enum omap_overlay_caps caps = ovl->caps;
bool five_taps = true;
bool fieldmode = 0;
int r, cconv = 0;
@@ -2314,9 +2311,10 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
if (!dss_feat_color_mode_supported(plane, oi->color_mode))
return -EINVAL;
- r = dispc_plane_calc_scaling(plane, channel, mgr_timings, in_width,
- in_height, out_width, out_height, oi->color_mode,
- &five_taps, &x_predecim, &y_predecim, oi->pos_x);
+ r = dispc_plane_calc_scaling(plane, caps, channel, mgr_timings,
+ in_width, in_height, out_width, out_height,
+ oi->color_mode, &five_taps, &x_predecim, &y_predecim,
+ oi->pos_x);
if (r)
return r;
@@ -2395,7 +2393,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
dispc_plane_set_input_size(plane, in_width, in_height);
- if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) {
+ if (caps & OMAP_DSS_OVL_CAP_SCALE) {
dispc_plane_set_scaling(plane, in_width, in_height, out_width,
out_height, ilace, five_taps, fieldmode,
oi->color_mode, oi->rotation);
@@ -2406,9 +2404,9 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
dispc_plane_set_rotation_attrs(plane, oi->rotation, oi->mirror,
oi->color_mode);
- dispc_plane_set_zorder(plane, oi->zorder);
- dispc_plane_set_pre_mult_alpha(plane, oi->pre_mult_alpha);
- dispc_plane_setup_global_alpha(plane, oi->global_alpha);
+ dispc_plane_set_zorder(plane, caps, oi->zorder);
+ dispc_plane_set_pre_mult_alpha(plane, caps, oi->pre_mult_alpha);
+ dispc_plane_setup_global_alpha(plane, caps, oi->global_alpha);
dispc_plane_enable_replication(plane, replication);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 07/21] OMAPDSS: OVERLAY: Add position and replication as overlay caps
From: Archit Taneja @ 2012-09-13 12:26 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
Add position and replication as overlay caps, and pass overlay caps as an
argument to the corresponding functions. Adding position and replication to
overlay caps seems a bit unnecessary, but it allows us to use the
corresponding functions for writeback too.
These caps will be set for all overlays, but not for writeback. This is done
so writeback can reuse dispc_ovl_setup() to the maximum.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 20 ++++++++++++-----
drivers/video/omap2/dss/dss_features.c | 38 +++++++++++++++++++++-----------
include/video/omapdss.h | 2 ++
3 files changed, 42 insertions(+), 18 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 3a0a576..325cd51 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -703,9 +703,15 @@ static void dispc_plane_set_ba1_uv(enum omap_plane plane, u32 paddr)
dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr);
}
-static void dispc_plane_set_pos(enum omap_plane plane, int x, int y)
+static void dispc_plane_set_pos(enum omap_plane plane,
+ enum omap_overlay_caps caps, int x, int y)
{
- u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0);
+ u32 val;
+
+ if ((caps & OMAP_DSS_OVL_CAP_POS) = 0)
+ return;
+
+ val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0);
dispc_write_reg(DISPC_OVL_POSITION(plane), val);
}
@@ -1056,11 +1062,15 @@ static void dispc_plane_set_vid_color_conv(enum omap_plane plane, bool enable)
dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
}
-static void dispc_plane_enable_replication(enum omap_plane plane, bool enable)
+static void dispc_plane_enable_replication(enum omap_plane plane,
+ enum omap_overlay_caps caps, bool enable)
{
static const unsigned shifts[] = { 5, 10, 10, 10 };
int shift;
+ if ((caps & OMAP_DSS_OVL_CAP_REPLICATION) = 0)
+ return;
+
shift = shifts[plane];
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, shift, shift);
}
@@ -2389,7 +2399,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, in_width,
in_height, out_width, out_height);
- dispc_plane_set_pos(plane, oi->pos_x, pos_y);
+ dispc_plane_set_pos(plane, caps, oi->pos_x, pos_y);
dispc_plane_set_input_size(plane, in_width, in_height);
@@ -2408,7 +2418,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
dispc_plane_set_pre_mult_alpha(plane, caps, oi->pre_mult_alpha);
dispc_plane_setup_global_alpha(plane, caps, oi->global_alpha);
- dispc_plane_enable_replication(plane, replication);
+ dispc_plane_enable_replication(plane, caps, replication);
return 0;
}
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 63d109f..8b6c79f 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -269,54 +269,66 @@ static const enum omap_color_mode omap4_dss_supported_color_modes[] = {
static const enum omap_overlay_caps omap2_dss_overlay_caps[] = {
/* OMAP_DSS_GFX */
- 0,
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO1 */
- OMAP_DSS_OVL_CAP_SCALE,
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO2 */
- OMAP_DSS_OVL_CAP_SCALE,
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
};
static const enum omap_overlay_caps omap3430_dss_overlay_caps[] = {
/* OMAP_DSS_GFX */
- OMAP_DSS_OVL_CAP_GLOBAL_ALPHA,
+ OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO1 */
- OMAP_DSS_OVL_CAP_SCALE,
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO2 */
- OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA,
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
};
static const enum omap_overlay_caps omap3630_dss_overlay_caps[] = {
/* OMAP_DSS_GFX */
- OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA,
+ OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO1 */
- OMAP_DSS_OVL_CAP_SCALE,
+ OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO2 */
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA,
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
};
static const enum omap_overlay_caps omap4_dss_overlay_caps[] = {
/* OMAP_DSS_GFX */
OMAP_DSS_OVL_CAP_GLOBAL_ALPHA | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA |
- OMAP_DSS_OVL_CAP_ZORDER,
+ OMAP_DSS_OVL_CAP_ZORDER | OMAP_DSS_OVL_CAP_POS |
+ OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO1 */
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO2 */
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
/* OMAP_DSS_VIDEO3 */
OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_GLOBAL_ALPHA |
- OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER,
+ OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA | OMAP_DSS_OVL_CAP_ZORDER |
+ OMAP_DSS_OVL_CAP_POS | OMAP_DSS_OVL_CAP_REPLICATION,
};
static const char * const omap2_dss_clk_source_names[] = {
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index e65e2e9..46097bd 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -187,6 +187,8 @@ enum omap_overlay_caps {
OMAP_DSS_OVL_CAP_GLOBAL_ALPHA = 1 << 1,
OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA = 1 << 2,
OMAP_DSS_OVL_CAP_ZORDER = 1 << 3,
+ OMAP_DSS_OVL_CAP_POS = 1 << 4,
+ OMAP_DSS_OVL_CAP_REPLICATION = 1 << 5,
};
enum omap_overlay_manager_caps {
--
1.7.9.5
^ permalink raw reply related
* [PATCH 08/21] OMAPDSS: DISPC: Make dispc_ovl_setup call dispc_plane_setup
From: Archit Taneja @ 2012-09-13 12:26 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
Add a new static function called dispc_plane_setup(). This function is used by
dispc_ovl_setup() to configure the overlay registers.
This split is done so that dispc_wb_setup() can reuse the common overlay related
registers configured in dispc_plane_setup().
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 125 ++++++++++++++++++++++-----------------
1 file changed, 70 insertions(+), 55 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 325cd51..e6d8b77 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2268,43 +2268,34 @@ static int dispc_plane_calc_scaling(enum omap_plane plane,
return 0;
}
-int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
+static int dispc_plane_setup(enum omap_plane plane, enum omap_channel channel,
+ enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr,
+ u16 screen_width, int pos_x, int pos_y, u16 width, u16 height,
+ u16 out_width, u16 out_height, enum omap_color_mode color_mode,
+ u8 rotation, bool mirror, u8 zorder, u8 pre_mult_alpha,
+ u8 global_alpha, enum omap_dss_rotation_type rotation_type,
bool replication, const struct omap_video_timings *mgr_timings)
{
- struct omap_overlay *ovl = omap_dss_get_overlay(plane);
- enum omap_overlay_caps caps = ovl->caps;
bool five_taps = true;
bool fieldmode = 0;
int r, cconv = 0;
unsigned offset0, offset1;
s32 row_inc;
s32 pix_inc;
- u16 frame_height = oi->height;
+ u16 frame_height = height;
unsigned int field_offset = 0;
- u16 in_height = oi->height;
- u16 in_width = oi->width;
- u16 out_width, out_height;
- enum omap_channel channel;
+ u16 in_height = height;
+ u16 in_width = width;
int x_predecim = 1, y_predecim = 1;
bool ilace = mgr_timings->interlace;
- u16 pos_y = oi->pos_y;
-
- channel = dispc_ovl_get_channel_out(plane);
-
- DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> "
- "%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d\n",
- plane, oi->paddr, oi->p_uv_addr,
- oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
- oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
- oi->mirror, ilace, channel, replication);
- if (oi->paddr = 0)
+ if (paddr = 0)
return -EINVAL;
- out_width = oi->out_width = 0 ? oi->width : oi->out_width;
- out_height = oi->out_height = 0 ? oi->height : oi->out_height;
+ out_width = out_width = 0 ? width : out_width;
+ out_height = out_height = 0 ? height : out_height;
- if (ilace && oi->height = out_height)
+ if (ilace && height = out_height)
fieldmode = 1;
if (ilace) {
@@ -2314,26 +2305,26 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
out_height /= 2;
DSSDBG("adjusting for ilace: height %d, pos_y %d, "
- "out_height %d\n",
- in_height, pos_y, out_height);
+ "out_height %d\n", in_height, pos_y,
+ out_height);
}
- if (!dss_feat_color_mode_supported(plane, oi->color_mode))
+ if (!dss_feat_color_mode_supported(plane, color_mode))
return -EINVAL;
r = dispc_plane_calc_scaling(plane, caps, channel, mgr_timings,
in_width, in_height, out_width, out_height,
- oi->color_mode, &five_taps, &x_predecim, &y_predecim,
- oi->pos_x);
+ color_mode, &five_taps, &x_predecim, &y_predecim,
+ pos_x);
if (r)
return r;
in_width = DIV_ROUND_UP(in_width, x_predecim);
in_height = DIV_ROUND_UP(in_height, y_predecim);
- if (oi->color_mode = OMAP_DSS_COLOR_YUV2 ||
- oi->color_mode = OMAP_DSS_COLOR_UYVY ||
- oi->color_mode = OMAP_DSS_COLOR_NV12)
+ if (color_mode = OMAP_DSS_COLOR_YUV2 ||
+ color_mode = OMAP_DSS_COLOR_UYVY ||
+ color_mode = OMAP_DSS_COLOR_NV12)
cconv = 1;
if (ilace && !fieldmode) {
@@ -2359,70 +2350,94 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
row_inc = 0;
pix_inc = 0;
- if (oi->rotation_type = OMAP_DSS_ROT_TILER)
- calc_tiler_rotation_offset(oi->screen_width, in_width,
- oi->color_mode, fieldmode, field_offset,
+ if (rotation_type = OMAP_DSS_ROT_TILER)
+ calc_tiler_rotation_offset(screen_width, in_width,
+ color_mode, fieldmode, field_offset,
&offset0, &offset1, &row_inc, &pix_inc,
x_predecim, y_predecim);
- else if (oi->rotation_type = OMAP_DSS_ROT_DMA)
- calc_dma_rotation_offset(oi->rotation, oi->mirror,
- oi->screen_width, in_width, frame_height,
- oi->color_mode, fieldmode, field_offset,
+ else if (rotation_type = OMAP_DSS_ROT_DMA)
+ calc_dma_rotation_offset(rotation, mirror,
+ screen_width, in_width, frame_height,
+ color_mode, fieldmode, field_offset,
&offset0, &offset1, &row_inc, &pix_inc,
x_predecim, y_predecim);
else
- calc_vrfb_rotation_offset(oi->rotation, oi->mirror,
- oi->screen_width, in_width, frame_height,
- oi->color_mode, fieldmode, field_offset,
+ calc_vrfb_rotation_offset(rotation, mirror,
+ screen_width, in_width, frame_height,
+ color_mode, fieldmode, field_offset,
&offset0, &offset1, &row_inc, &pix_inc,
x_predecim, y_predecim);
DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n",
offset0, offset1, row_inc, pix_inc);
- dispc_plane_set_color_mode(plane, oi->color_mode);
+ dispc_plane_set_color_mode(plane, color_mode);
- dispc_plane_configure_burst_type(plane, oi->rotation_type);
+ dispc_plane_configure_burst_type(plane, rotation_type);
- dispc_plane_set_ba0(plane, oi->paddr + offset0);
- dispc_plane_set_ba1(plane, oi->paddr + offset1);
+ dispc_plane_set_ba0(plane, paddr + offset0);
+ dispc_plane_set_ba1(plane, paddr + offset1);
- if (OMAP_DSS_COLOR_NV12 = oi->color_mode) {
- dispc_plane_set_ba0_uv(plane, oi->p_uv_addr + offset0);
- dispc_plane_set_ba1_uv(plane, oi->p_uv_addr + offset1);
+ if (OMAP_DSS_COLOR_NV12 = color_mode) {
+ dispc_plane_set_ba0_uv(plane, p_uv_addr + offset0);
+ dispc_plane_set_ba1_uv(plane, p_uv_addr + offset1);
}
dispc_plane_set_row_inc(plane, row_inc);
dispc_plane_set_pix_inc(plane, pix_inc);
- DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, in_width,
+ DSSDBG("%d,%d %dx%d -> %dx%d\n", pos_x, pos_y, in_width,
in_height, out_width, out_height);
- dispc_plane_set_pos(plane, caps, oi->pos_x, pos_y);
+ dispc_plane_set_pos(plane, caps, pos_x, pos_y);
dispc_plane_set_input_size(plane, in_width, in_height);
if (caps & OMAP_DSS_OVL_CAP_SCALE) {
dispc_plane_set_scaling(plane, in_width, in_height, out_width,
out_height, ilace, five_taps, fieldmode,
- oi->color_mode, oi->rotation);
+ color_mode, rotation);
dispc_plane_set_output_size(plane, out_width, out_height);
dispc_plane_set_vid_color_conv(plane, cconv);
}
- dispc_plane_set_rotation_attrs(plane, oi->rotation, oi->mirror,
- oi->color_mode);
+ dispc_plane_set_rotation_attrs(plane, rotation, mirror, color_mode);
- dispc_plane_set_zorder(plane, caps, oi->zorder);
- dispc_plane_set_pre_mult_alpha(plane, caps, oi->pre_mult_alpha);
- dispc_plane_setup_global_alpha(plane, caps, oi->global_alpha);
+ dispc_plane_set_zorder(plane, caps, zorder);
+ dispc_plane_set_pre_mult_alpha(plane, caps, pre_mult_alpha);
+ dispc_plane_setup_global_alpha(plane, caps, global_alpha);
dispc_plane_enable_replication(plane, caps, replication);
return 0;
}
+int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
+ bool replication, const struct omap_video_timings *mgr_timings)
+{
+ int r;
+ struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+ enum omap_channel channel;
+
+ channel = dispc_ovl_get_channel_out(plane);
+
+ DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> "
+ "%dx%d, cmode %x, rot %d, mir %d, chan %d repl %d\n",
+ plane, oi->paddr, oi->p_uv_addr, oi->screen_width, oi->pos_x,
+ oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height,
+ oi->color_mode, oi->rotation, oi->mirror, channel, replication);
+
+ r = dispc_plane_setup(plane, channel, ovl->caps, oi->paddr,
+ oi->p_uv_addr, oi->screen_width, oi->pos_x, oi->pos_y,
+ oi->width, oi->height, oi->out_width, oi->out_height,
+ oi->color_mode, oi->rotation, oi->mirror, oi->zorder,
+ oi->pre_mult_alpha, oi->global_alpha, oi->rotation_type,
+ replication, mgr_timings);
+
+ return r;
+}
+
int dispc_ovl_enable(enum omap_plane plane, bool enable)
{
DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 09/21] OMAPDSS: DISPC: Calculate scaling limits in a more generic way
From: Archit Taneja @ 2012-09-13 12:26 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
Scaling calculations for an overlay are done by comparing pixel clock of the
connected overlay manager and the core clock of DISPC. The pixel clock is the
output rate of the scalar. The scalar block needs to provide pixels at this rate
since the manager is connected to a panel, which has real time constraints.
In the case of writeback in memory to memory mode, the output of the scalar
blocks aren't connected to a display, and hence there isn't a pixel clock which
causes downscaling limitations.
Make the input to scaling calculations a bit more generic by passing the scalar
output rate rather than passing pixel clock of the overlay manager connected to
the pipeline, as we now have use cases where the scalar's output may not go to
a manager connected to a panel.
This also helps us in replacing omap_channel arguments with output_rate, making
dispc_plane_setup more pipeline specific.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 126 ++++++++++++++++++++++-----------------
1 file changed, 72 insertions(+), 54 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index e6d8b77..58cb06c 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -86,13 +86,13 @@ struct dispc_features {
u16 sw_max;
u16 vp_max;
u16 hp_max;
- int (*calc_scaling) (enum omap_channel channel,
+ int (*calc_scaling) (enum omap_plane plane, unsigned long out_rate,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
int *x_predecim, int *y_predecim, int *decim_x, int *decim_y,
u16 pos_x, unsigned long *core_clk);
- unsigned long (*calc_core_clk) (enum omap_channel channel,
+ unsigned long (*calc_core_clk) (unsigned long out_rate,
u16 width, u16 height, u16 out_width, u16 out_height);
u8 num_fifos;
@@ -236,6 +236,8 @@ static const struct {
};
static void _omap_dispc_set_irqs(void);
+static unsigned long dispc_plane_output_rate(enum omap_plane plane);
+static unsigned long dispc_plane_lclk_rate(enum omap_plane plane);
static inline void dispc_write_reg(const u16 idx, u32 val)
{
@@ -1925,29 +1927,25 @@ static void calc_tiler_rotation_offset(u16 screen_width, u16 width,
* This function is used to avoid synclosts in OMAP3, because of some
* undocumented horizontal position and timing related limitations.
*/
-static int check_horiz_timing_omap3(enum omap_channel channel,
- const struct omap_video_timings *t, u16 pos_x,
- u16 width, u16 height, u16 out_width, u16 out_height)
+static int check_horiz_timing_omap3(enum omap_plane plane,
+ unsigned long out_rate, const struct omap_video_timings *t,
+ u16 pos_x, u16 width, u16 height, u16 out_width, u16 out_height)
{
int DS = DIV_ROUND_UP(height, out_height);
- unsigned long nonactive, lclk, pclk;
+ unsigned long nonactive;
+ unsigned long lclk_rate = dispc_plane_lclk_rate(plane);
static const u8 limits[3] = { 8, 10, 20 };
u64 val, blank;
int i;
nonactive = t->x_res + t->hfp + t->hsw + t->hbp - out_width;
- pclk = dispc_mgr_pclk_rate(channel);
- if (dss_mgr_is_lcd(channel))
- lclk = dispc_mgr_lclk_rate(channel);
- else
- lclk = dispc_fclk_rate();
i = 0;
if (out_height < height)
i++;
if (out_width < width)
i++;
- blank = div_u64((u64)(t->hbp + t->hsw + t->hfp) * lclk, pclk);
+ blank = div_u64((u64)(t->hbp + t->hsw + t->hfp) * lclk_rate, out_rate);
DSSDBG("blanking period + ppl = %llu (limit = %u)\n", blank, limits[i]);
if (blank <= limits[i])
return -EINVAL;
@@ -1957,7 +1955,7 @@ static int check_horiz_timing_omap3(enum omap_channel channel,
* So, atleast DS-2 lines must have already been fetched by DISPC
* during nonactive - pos_x period.
*/
- val = div_u64((u64)(nonactive - pos_x) * lclk, pclk);
+ val = div_u64((u64)(nonactive - pos_x) * lclk_rate, out_rate);
DSSDBG("(nonactive - pos_x) * pcd = %llu max(0, DS - 2) * width = %d\n",
val, max(0, DS - 2) * width);
if (val < max(0, DS - 2) * width)
@@ -1968,7 +1966,7 @@ static int check_horiz_timing_omap3(enum omap_channel channel,
* only one line can be loaded during the active period. So, atleast
* DS - 1 lines should be loaded during nonactive period.
*/
- val = div_u64((u64)nonactive * lclk, pclk);
+ val = div_u64((u64)nonactive * lclk_rate, out_rate);
DSSDBG("nonactive * pcd = %llu, max(0, DS - 1) * width = %d\n",
val, max(0, DS - 1) * width);
if (val < max(0, DS - 1) * width)
@@ -1977,21 +1975,21 @@ static int check_horiz_timing_omap3(enum omap_channel channel,
return 0;
}
-static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
+static unsigned long calc_core_clk_five_taps(unsigned long out_rate,
const struct omap_video_timings *mgr_timings, u16 width,
u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode)
{
u32 core_clk = 0;
- u64 tmp, pclk = dispc_mgr_pclk_rate(channel);
+ u64 tmp;
if (height <= out_height && width <= out_width)
- return (unsigned long) pclk;
+ return (unsigned long) out_rate;
if (height > out_height) {
unsigned int ppl = mgr_timings->x_res;
- tmp = pclk * height * out_width;
+ tmp = out_rate * height * out_width;
do_div(tmp, 2 * out_height * ppl);
core_clk = tmp;
@@ -1999,14 +1997,14 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
if (ppl = out_width)
return 0;
- tmp = pclk * (height - 2 * out_height) * out_width;
+ tmp = out_rate * (height - 2 * out_height) * out_width;
do_div(tmp, 2 * out_height * (ppl - out_width));
core_clk = max_t(u32, core_clk, tmp);
}
}
if (width > out_width) {
- tmp = pclk * width;
+ tmp = out_rate * width;
do_div(tmp, out_width);
core_clk = max_t(u32, core_clk, tmp);
@@ -2017,22 +2015,19 @@ static unsigned long calc_core_clk_five_taps(enum omap_channel channel,
return core_clk;
}
-static unsigned long calc_core_clk_24xx(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_24xx(unsigned long out_rate, u16 width,
u16 height, u16 out_width, u16 out_height)
{
- unsigned long pclk = dispc_mgr_pclk_rate(channel);
-
if (height > out_height && width > out_width)
- return pclk * 4;
+ return out_rate * 4;
else
- return pclk * 2;
+ return out_rate * 2;
}
-static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_34xx(unsigned long out_rate, u16 width,
u16 height, u16 out_width, u16 out_height)
{
unsigned int hf, vf;
- unsigned long pclk = dispc_mgr_pclk_rate(channel);
/*
* FIXME how to determine the 'A' factor
@@ -2052,21 +2047,20 @@ static unsigned long calc_core_clk_34xx(enum omap_channel channel, u16 width,
else
vf = 1;
- return pclk * vf * hf;
+ return out_rate * vf * hf;
}
-static unsigned long calc_core_clk_44xx(enum omap_channel channel, u16 width,
+static unsigned long calc_core_clk_44xx(unsigned long out_rate, u16 width,
u16 height, u16 out_width, u16 out_height)
{
- unsigned long pclk = dispc_mgr_pclk_rate(channel);
-
if (width > out_width)
- return DIV_ROUND_UP(pclk, out_width) * width;
+ return DIV_ROUND_UP(out_rate, out_width) * width;
else
- return pclk;
+ return out_rate;
}
-static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
+static int dispc_ovl_calc_scaling_24xx(enum omap_plane plane,
+ unsigned long out_rate,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
@@ -2083,7 +2077,7 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
do {
in_height = DIV_ROUND_UP(height, *decim_y);
in_width = DIV_ROUND_UP(width, *decim_x);
- *core_clk = dispc.feat->calc_core_clk(channel, in_width,
+ *core_clk = dispc.feat->calc_core_clk(out_rate, in_width,
in_height, out_width, out_height);
error = (in_width > maxsinglelinewidth || !*core_clk ||
*core_clk > dispc_core_clk_rate());
@@ -2106,7 +2100,8 @@ static int dispc_ovl_calc_scaling_24xx(enum omap_channel channel,
return 0;
}
-static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
+static int dispc_ovl_calc_scaling_34xx(enum omap_plane plane,
+ unsigned long out_rate,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
@@ -2122,19 +2117,21 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
do {
in_height = DIV_ROUND_UP(height, *decim_y);
in_width = DIV_ROUND_UP(width, *decim_x);
- *core_clk = calc_core_clk_five_taps(channel, mgr_timings,
+ *core_clk = calc_core_clk_five_taps(out_rate, mgr_timings,
in_width, in_height, out_width, out_height, color_mode);
- error = check_horiz_timing_omap3(channel, mgr_timings, pos_x,
- in_width, in_height, out_width, out_height);
+ error = check_horiz_timing_omap3(plane, out_rate, mgr_timings,
+ pos_x, in_width, in_height, out_width,
+ out_height);
if (in_width > maxsinglelinewidth)
if (in_height > out_height &&
in_height < out_height * 2)
*five_taps = false;
if (!*five_taps)
- *core_clk = dispc.feat->calc_core_clk(channel, in_width,
- in_height, out_width, out_height);
+ *core_clk = dispc.feat->calc_core_clk(out_rate,
+ in_width, in_height, out_width,
+ out_height);
error = (error || in_width > maxsinglelinewidth * 2 ||
(in_width > maxsinglelinewidth && *five_taps) ||
@@ -2151,8 +2148,8 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
}
} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
- if (check_horiz_timing_omap3(channel, mgr_timings, pos_x, width, height,
- out_width, out_height)){
+ if (check_horiz_timing_omap3(plane, out_rate, mgr_timings, pos_x, width,
+ height, out_width, out_height)){
DSSERR("horizontal timing too tight\n");
return -EINVAL;
}
@@ -2170,7 +2167,8 @@ static int dispc_ovl_calc_scaling_34xx(enum omap_channel channel,
return 0;
}
-static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
+static int dispc_ovl_calc_scaling_44xx(enum omap_plane plane,
+ unsigned long out_rate,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
@@ -2184,7 +2182,7 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
in_width_max = dispc_core_clk_rate() /
- DIV_ROUND_UP(dispc_mgr_pclk_rate(channel), out_width);
+ DIV_ROUND_UP(out_rate, out_width);
*decim_x = DIV_ROUND_UP(width, in_width_max);
*decim_x = *decim_x > decim_x_min ? *decim_x : decim_x_min;
@@ -2201,13 +2199,13 @@ static int dispc_ovl_calc_scaling_44xx(enum omap_channel channel,
return -EINVAL;
}
- *core_clk = dispc.feat->calc_core_clk(channel, in_width, in_height,
+ *core_clk = dispc.feat->calc_core_clk(out_rate, in_width, in_height,
out_width, out_height);
return 0;
}
static int dispc_plane_calc_scaling(enum omap_plane plane,
- enum omap_overlay_caps caps, enum omap_channel channel,
+ enum omap_overlay_caps caps, unsigned long out_rate,
const struct omap_video_timings *mgr_timings,
u16 width, u16 height, u16 out_width, u16 out_height,
enum omap_color_mode color_mode, bool *five_taps,
@@ -2246,9 +2244,9 @@ static int dispc_plane_calc_scaling(enum omap_plane plane,
if (decim_y > *y_predecim || out_height > height * 8)
return -EINVAL;
- ret = dispc.feat->calc_scaling(channel, mgr_timings, width, height,
- out_width, out_height, color_mode, five_taps, x_predecim,
- y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
+ ret = dispc.feat->calc_scaling(plane, out_rate, mgr_timings, width,
+ height, out_width, out_height, color_mode, five_taps,
+ x_predecim, y_predecim, &decim_x, &decim_y, pos_x, &core_clk);
if (ret)
return ret;
@@ -2268,8 +2266,8 @@ static int dispc_plane_calc_scaling(enum omap_plane plane,
return 0;
}
-static int dispc_plane_setup(enum omap_plane plane, enum omap_channel channel,
- enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr,
+static int dispc_plane_setup(enum omap_plane plane, enum omap_overlay_caps caps,
+ unsigned long out_rate, u32 paddr, u32 p_uv_addr,
u16 screen_width, int pos_x, int pos_y, u16 width, u16 height,
u16 out_width, u16 out_height, enum omap_color_mode color_mode,
u8 rotation, bool mirror, u8 zorder, u8 pre_mult_alpha,
@@ -2312,7 +2310,7 @@ static int dispc_plane_setup(enum omap_plane plane, enum omap_channel channel,
if (!dss_feat_color_mode_supported(plane, color_mode))
return -EINVAL;
- r = dispc_plane_calc_scaling(plane, caps, channel, mgr_timings,
+ r = dispc_plane_calc_scaling(plane, caps, out_rate, mgr_timings,
in_width, in_height, out_width, out_height,
color_mode, &five_taps, &x_predecim, &y_predecim,
pos_x);
@@ -2419,6 +2417,7 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
int r;
struct omap_overlay *ovl = omap_dss_get_overlay(plane);
enum omap_channel channel;
+ unsigned long out_rate;
channel = dispc_ovl_get_channel_out(plane);
@@ -2428,7 +2427,9 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height,
oi->color_mode, oi->rotation, oi->mirror, channel, replication);
- r = dispc_plane_setup(plane, channel, ovl->caps, oi->paddr,
+ out_rate = dispc_plane_output_rate(plane);
+
+ r = dispc_plane_setup(plane, ovl->caps, out_rate, oi->paddr,
oi->p_uv_addr, oi->screen_width, oi->pos_x, oi->pos_y,
oi->width, oi->height, oi->out_width, oi->out_height,
oi->color_mode, oi->rotation, oi->mirror, oi->zorder,
@@ -2993,6 +2994,23 @@ unsigned long dispc_core_clk_rate(void)
return fclk / lcd;
}
+static unsigned long dispc_plane_output_rate(enum omap_plane plane)
+{
+ enum omap_channel channel = dispc_ovl_get_channel_out(plane);
+
+ return dispc_mgr_pclk_rate(channel);
+}
+
+static unsigned long dispc_plane_lclk_rate(enum omap_plane plane)
+{
+ enum omap_channel channel = dispc_ovl_get_channel_out(plane);
+
+ if (dss_mgr_is_lcd(channel))
+ return dispc_mgr_lclk_rate(channel);
+ else
+ return dispc_fclk_rate();
+
+}
static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel)
{
int lcd, pcd;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 10/21] OMAPDSS: DISPC: Allow both upscaling and downscaling of chroma
From: Archit Taneja @ 2012-09-13 12:26 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
In the function dispc_plane_set_scaling_uv(), create a parameter which tells if
we want to upscale or downscale the chroma plane.
Downscaling of chroma is required by writeback pipeline for converting the input
YUV444 color format to YUV422 or NV12.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 32 ++++++++++++++++++++++----------
1 file changed, 22 insertions(+), 10 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 58cb06c..60a60fc 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1462,6 +1462,7 @@ static void dispc_plane_set_scaling_uv(enum omap_plane plane,
{
int scale_x = out_width != orig_width;
int scale_y = out_height != orig_height;
+ bool chroma_upscale = true;
if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE))
return;
@@ -1478,23 +1479,34 @@ static void dispc_plane_set_scaling_uv(enum omap_plane plane,
switch (color_mode) {
case OMAP_DSS_COLOR_NV12:
- /* UV is subsampled by 2 vertically*/
- orig_height >>= 1;
- /* UV is subsampled by 2 horz.*/
- orig_width >>= 1;
+ if (chroma_upscale) {
+ /* UV is subsampled by 2 horizontally and vertically */
+ orig_height >>= 1;
+ orig_width >>= 1;
+ } else {
+ /* UV is downsampled by 2 horizontally and vertically */
+ orig_height <<= 1;
+ orig_width <<= 1;
+ }
+
break;
case OMAP_DSS_COLOR_YUV2:
case OMAP_DSS_COLOR_UYVY:
- /*For YUV422 with 90/270 rotation,
- *we don't upsample chroma
- */
+ /* For YUV422 with 90/270 rotation, we don't upsample chroma */
if (rotation = OMAP_DSS_ROT_0 ||
- rotation = OMAP_DSS_ROT_180)
- /* UV is subsampled by 2 hrz*/
- orig_width >>= 1;
+ rotation = OMAP_DSS_ROT_180) {
+ if (chroma_upscale)
+ /* UV is subsampled by 2 horizontally */
+ orig_width >>= 1;
+ else
+ /* UV is downsampled by 2 horizontally */
+ orig_width <<= 1;
+ }
+
/* must use FIR for YUV422 if rotated */
if (rotation != OMAP_DSS_ROT_0)
scale_x = scale_y = true;
+
break;
default:
BUG();
--
1.7.9.5
^ permalink raw reply related
* [PATCH 11/21] OMAPDSS: DISPC: Add writeback register offsets and dss features structs
From: Archit Taneja @ 2012-09-13 12:26 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
Since writeback has many overlay like properties, and most of it's registers are
similar to that of overlays, it's possible to reuse most of the overlay related
DISPC code for writeback when considering it as a plane. Writeback was added as
a plane in the omap_plane field as OMAP_DSS_WB.
Add the writeback register offsets in dispc.h, add minimal WB plane related info
needed in dss_features. Add a function which returns the number of writeback
pipelines an OMAP version has.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.h | 33 ++++++++++++++++++++++++++++++++
drivers/video/omap2/dss/dss_features.c | 19 ++++++++++++++++++
drivers/video/omap2/dss/dss_features.h | 1 +
3 files changed, 53 insertions(+)
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h
index 84cc472..2b008f7 100644
--- a/drivers/video/omap2/dss/dispc.h
+++ b/drivers/video/omap2/dss/dispc.h
@@ -373,6 +373,7 @@ static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0000;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0008;
default:
BUG();
@@ -388,6 +389,7 @@ static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0004;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x000C;
default:
BUG();
@@ -407,6 +409,8 @@ static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane)
return 0x04BC;
case OMAP_DSS_VIDEO3:
return 0x0310;
+ case OMAP_DSS_WB:
+ return 0x0118;
default:
BUG();
return 0;
@@ -425,6 +429,8 @@ static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane)
return 0x04C0;
case OMAP_DSS_VIDEO3:
return 0x0314;
+ case OMAP_DSS_WB:
+ return 0x011C;
default:
BUG();
return 0;
@@ -454,6 +460,7 @@ static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x000C;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x00A8;
default:
BUG();
@@ -470,6 +477,7 @@ static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0010;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0070;
default:
BUG();
@@ -489,6 +497,8 @@ static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane)
return 0x04DC;
case OMAP_DSS_VIDEO3:
return 0x032C;
+ case OMAP_DSS_WB:
+ return 0x0310;
default:
BUG();
return 0;
@@ -504,6 +514,7 @@ static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0014;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x008C;
default:
BUG();
@@ -537,6 +548,7 @@ static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x001C;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x00A4;
default:
BUG();
@@ -553,6 +565,7 @@ static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0020;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0098;
default:
BUG();
@@ -602,6 +615,7 @@ static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0024;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0090;
default:
BUG();
@@ -621,6 +635,8 @@ static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane)
return 0x055C;
case OMAP_DSS_VIDEO3:
return 0x0424;
+ case OMAP_DSS_WB:
+ return 0x290;
default:
BUG();
return 0;
@@ -637,6 +653,7 @@ static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0028;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0094;
default:
BUG();
@@ -655,6 +672,7 @@ static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x002C;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0000;
default:
BUG();
@@ -674,6 +692,8 @@ static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane)
return 0x0560;
case OMAP_DSS_VIDEO3:
return 0x0428;
+ case OMAP_DSS_WB:
+ return 0x0294;
default:
BUG();
return 0;
@@ -690,6 +710,7 @@ static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane)
case OMAP_DSS_VIDEO2:
return 0x0030;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0004;
default:
BUG();
@@ -709,6 +730,8 @@ static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane)
return 0x0564;
case OMAP_DSS_VIDEO3:
return 0x042C;
+ case OMAP_DSS_WB:
+ return 0x0298;
default:
BUG();
return 0;
@@ -726,6 +749,7 @@ static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i)
case OMAP_DSS_VIDEO2:
return 0x0034 + i * 0x8;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0010 + i * 0x8;
default:
BUG();
@@ -746,6 +770,8 @@ static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i)
return 0x0568 + i * 0x8;
case OMAP_DSS_VIDEO3:
return 0x0430 + i * 0x8;
+ case OMAP_DSS_WB:
+ return 0x02A0 + i * 0x8;
default:
BUG();
return 0;
@@ -763,6 +789,7 @@ static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i)
case OMAP_DSS_VIDEO2:
return 0x0038 + i * 0x8;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0014 + i * 0x8;
default:
BUG();
@@ -783,6 +810,8 @@ static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i)
return 0x056C + i * 0x8;
case OMAP_DSS_VIDEO3:
return 0x0434 + i * 0x8;
+ case OMAP_DSS_WB:
+ return 0x02A4 + i * 0x8;
default:
BUG();
return 0;
@@ -799,6 +828,7 @@ static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i)
case OMAP_DSS_VIDEO1:
case OMAP_DSS_VIDEO2:
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0074 + i * 0x4;
default:
BUG();
@@ -818,6 +848,7 @@ static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i)
case OMAP_DSS_VIDEO2:
return 0x00B4 + i * 0x4;
case OMAP_DSS_VIDEO3:
+ case OMAP_DSS_WB:
return 0x0050 + i * 0x4;
default:
BUG();
@@ -838,6 +869,8 @@ static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i)
return 0x05A8 + i * 0x4;
case OMAP_DSS_VIDEO3:
return 0x0470 + i * 0x4;
+ case OMAP_DSS_WB:
+ return 0x02E0 + i * 0x4;
default:
BUG();
return 0;
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 8b6c79f..5968fd8 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -46,6 +46,7 @@ struct omap_dss_features {
const int num_mgrs;
const int num_ovls;
+ const int num_wbs;
const enum omap_display_type *supported_displays;
const enum omap_dss_output_id *supported_outputs;
const enum omap_color_mode *supported_color_modes;
@@ -265,6 +266,16 @@ static const enum omap_color_mode omap4_dss_supported_color_modes[] = {
OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
OMAP_DSS_COLOR_RGBX32,
+
+ /* OMAP_DSS_WB */
+ OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U |
+ OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 |
+ OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 |
+ OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U |
+ OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY |
+ OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
+ OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
+ OMAP_DSS_COLOR_RGBX32,
};
static const enum omap_overlay_caps omap2_dss_overlay_caps[] = {
@@ -576,6 +587,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
.num_mgrs = 3,
.num_ovls = 4,
+ .num_wbs = 1,
.supported_displays = omap4_dss_supported_displays,
.supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes,
@@ -597,6 +609,7 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
.num_mgrs = 3,
.num_ovls = 4,
+ .num_wbs = 1,
.supported_displays = omap4_dss_supported_displays,
.supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes,
@@ -618,6 +631,7 @@ static const struct omap_dss_features omap4_dss_features = {
.num_mgrs = 3,
.num_ovls = 4,
+ .num_wbs = 1,
.supported_displays = omap4_dss_supported_displays,
.supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes,
@@ -674,6 +688,11 @@ int dss_feat_get_num_ovls(void)
return omap_current_dss_features->num_ovls;
}
+int dss_feat_get_num_wbs(void)
+{
+ return omap_current_dss_features->num_wbs;
+}
+
unsigned long dss_feat_get_param_min(enum dss_range_param param)
{
return omap_current_dss_features->dss_params[param].min;
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index fb8ed59..66fd9f7 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -102,6 +102,7 @@ enum dss_range_param {
/* DSS Feature Functions */
int dss_feat_get_num_mgrs(void);
int dss_feat_get_num_ovls(void);
+int dss_feat_get_num_wbs(void);
unsigned long dss_feat_get_param_min(enum dss_range_param param);
unsigned long dss_feat_get_param_max(enum dss_range_param param);
enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 12/21] OMAPDSS: DISPC: Configure input and output sizes for writeback
From: Archit Taneja @ 2012-09-13 12:26 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
Writeback uses the WB_PICTURE_SIZE register to define the size of the content
written to memory, this is the output of the scalar. It uses the WB_SIZE
register to define the size of the content coming from the overlay/manager to
which it is connected, this is the input to the scalar. This naming is different
as compared to overlays.
Add checks for writeback in dispc_plane_set_input_size() and
dispc_plane_set_output_size() to write to the correct registers.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 60a60fc..8673a33 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -723,7 +723,7 @@ static void dispc_plane_set_input_size(enum omap_plane plane, int width,
{
u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
- if (plane = OMAP_DSS_GFX)
+ if (plane = OMAP_DSS_GFX || plane = OMAP_DSS_WB)
dispc_write_reg(DISPC_OVL_SIZE(plane), val);
else
dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val);
@@ -738,7 +738,10 @@ static void dispc_plane_set_output_size(enum omap_plane plane, int width,
val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
- dispc_write_reg(DISPC_OVL_SIZE(plane), val);
+ if (plane = OMAP_DSS_WB)
+ dispc_write_reg(DISPC_OVL_PICTURE_SIZE(plane), val);
+ else
+ dispc_write_reg(DISPC_OVL_SIZE(plane), val);
}
static void dispc_plane_set_zorder(enum omap_plane plane,
--
1.7.9.5
^ permalink raw reply related
* [PATCH 13/21] OMAPDSS: DISPC: Pass dummy scalar output rates for writeback pipeline
From: Archit Taneja @ 2012-09-13 12:26 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
The scalar output rate for writeback pipeline when configured in memory to
memory mode isn't a fixed rate, it can increase or reduce based on the time
it needs to downscale. It also depends on the rate at which it can receive
and push out data from/to the interconnect.
Set the scalar output rates for writeback to a low dummy value(set to 1) to
represent that it can output at low rates, this is done so that maximum
downscaling is possible in memory to memory mode.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 8673a33..1d5dddf 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -3011,21 +3011,30 @@ unsigned long dispc_core_clk_rate(void)
static unsigned long dispc_plane_output_rate(enum omap_plane plane)
{
- enum omap_channel channel = dispc_ovl_get_channel_out(plane);
+ if (plane != OMAP_DSS_WB) {
+ enum omap_channel channel = dispc_ovl_get_channel_out(plane);
- return dispc_mgr_pclk_rate(channel);
+ return dispc_mgr_pclk_rate(channel);
+ } else {
+ return 1;
+ }
}
static unsigned long dispc_plane_lclk_rate(enum omap_plane plane)
{
- enum omap_channel channel = dispc_ovl_get_channel_out(plane);
- if (dss_mgr_is_lcd(channel))
- return dispc_mgr_lclk_rate(channel);
- else
- return dispc_fclk_rate();
+ if (plane != OMAP_DSS_WB) {
+ enum omap_channel channel = dispc_ovl_get_channel_out(plane);
+ if (dss_mgr_is_lcd(channel))
+ return dispc_mgr_lclk_rate(channel);
+ else
+ return dispc_fclk_rate();
+ } else {
+ return 1;
+ }
}
+
static void dispc_dump_clocks_channel(struct seq_file *s, enum omap_channel channel)
{
int lcd, pcd;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 14/21] OMAPDSS: DISPC: Downscale chroma if plane is writeback
From: Archit Taneja @ 2012-09-13 12:26 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
When converting YUYV444 content to YUV422 or NV12 formats through writeback
pipeline, the scalar needs to downscale the chroma plane. Ensure that chroma
is downscaled when the pipeline is writeback.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 1d5dddf..f3bf93d 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1465,7 +1465,7 @@ static void dispc_plane_set_scaling_uv(enum omap_plane plane,
{
int scale_x = out_width != orig_width;
int scale_y = out_height != orig_height;
- bool chroma_upscale = true;
+ bool chroma_upscale = plane != OMAP_DSS_WB ? true : false;
if (!dss_has_feature(FEAT_HANDLE_UV_SEPARATE))
return;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 15/21] OMAPDSS: DISPC: Don't set chroma resampling bit for writeback
From: Archit Taneja @ 2012-09-13 12:26 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
The bit YUVCHROMARESAMPLING isn't there for writeback in DISPC_WB_ATTRIBUTES2.
It isn't there because we don't upsample chroma like for video pipelines, we
downsample chroma in writeback to get YUV422 or NV12 formats from the YUV444
input.
Ignore this bit in dispc_ovl_set_scaling_uv() if the plane is OMAP_DSS_WB.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index f3bf93d..b0f14c0 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1473,7 +1473,8 @@ static void dispc_plane_set_scaling_uv(enum omap_plane plane,
color_mode != OMAP_DSS_COLOR_UYVY &&
color_mode != OMAP_DSS_COLOR_NV12)) {
/* reset chroma resampling for RGB formats */
- REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8);
+ if (plane != OMAP_DSS_WB)
+ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8);
return;
}
@@ -1525,8 +1526,10 @@ static void dispc_plane_set_scaling_uv(enum omap_plane plane,
out_width, out_height, five_taps,
rotation, DISPC_COLOR_COMPONENT_UV);
- REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane),
- (scale_x || scale_y) ? 1 : 0, 8, 8);
+ if (plane != OMAP_DSS_WB)
+ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane),
+ (scale_x || scale_y) ? 1 : 0, 8, 8);
+
/* set H scaling */
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_x ? 1 : 0, 5, 5);
/* set V scaling */
--
1.7.9.5
^ permalink raw reply related
* [PATCH 16/21] OMAPDSS: DISPC: Add function to set channel in for writeback
From: Archit Taneja @ 2012-09-13 12:27 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
Writeback can take input from either one of the overlays, or one of the overlay
managers. Add an enum which represents the channel_in for writeback, and maps
to the register field programming.
Add a function to configure channel in for writeback. This will be used later in
APPLY.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 7 +++++++
drivers/video/omap2/dss/dss.h | 13 +++++++++++++
2 files changed, 20 insertions(+)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index b0f14c0..a33ed8e 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -987,6 +987,13 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
return channel;
}
+void dispc_wb_set_channel_in(enum dss_writeback_channel channel)
+{
+ enum omap_plane plane = OMAP_DSS_WB;
+
+ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), channel, 18, 16);
+}
+
static void dispc_plane_set_burst_size(enum omap_plane plane,
enum omap_burst_size burst_size)
{
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 4b1ca03..ea17d68 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -113,6 +113,17 @@ enum dss_dsi_content_type {
DSS_DSI_CONTENT_GENERIC,
};
+enum dss_writeback_channel {
+ DSS_WB_LCD1_MGR = 0,
+ DSS_WB_LCD2_MGR = 1,
+ DSS_WB_TV_MGR = 2,
+ DSS_WB_OVL0 = 3,
+ DSS_WB_OVL1 = 4,
+ DSS_WB_OVL2 = 5,
+ DSS_WB_OVL3 = 6,
+ DSS_WB_LCD3_MGR = 7,
+};
+
struct dss_clock_info {
/* rates that we get with dividers below */
unsigned long fck;
@@ -470,6 +481,8 @@ int dispc_mgr_get_clock_div(enum omap_channel channel,
void dispc_mgr_setup(enum omap_channel channel,
struct omap_overlay_manager_info *info);
+void dispc_wb_set_channel_in(enum dss_writeback_channel channel);
+
/* VENC */
#ifdef CONFIG_OMAP2_DSS_VENC
int venc_init_platform_driver(void) __init;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 17/21] OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup
From: Archit Taneja @ 2012-09-13 12:27 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
Create struct omap_dss_writeback_info, this is similar to omap_overlay_info,
the major difference is that there is no parameter which describes the input
size to writeback, this is because this is always fixed, and decided by the
connected overlay or overlay manager. One more difference is that screen_width
is renamed to buf_width, to give the value of stride the writeback buffer has.
Call dispc_plane_setup() through dispc_wb_setup() to configure overlay-like
parameters. The parameters in dispc_plane_setup() which do not hold for
writeback are filled passed as zeroes or false, dispc_plane_setup() takes
care of not configuring them as they won't possess the needed overlay caps.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 30 ++++++++++++++++++++++++++++++
drivers/video/omap2/dss/dss.h | 2 ++
include/video/omapdss.h | 13 +++++++++++++
3 files changed, 45 insertions(+)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index a33ed8e..f575875 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2464,6 +2464,36 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
return r;
}
+int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
+ const struct omap_video_timings *mgr_timings)
+{
+ int r;
+ enum omap_plane plane = OMAP_DSS_WB;
+ const int pos_x = 0, pos_y = 0;
+ const u8 zorder = 0, global_alpha = 0;
+ const bool replication = false;
+ int in_width = mgr_timings->x_res;
+ int in_height = mgr_timings->y_res;
+ unsigned long out_rate;
+ enum omap_overlay_caps caps + OMAP_DSS_OVL_CAP_SCALE | OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA;
+
+ DSSDBG("dispc_wb_setup, pa %x, pa_uv %x, %d,%d -> %dx%d, cmode %x, "
+ "rot %d, mir %d\n", wi->paddr, wi->p_uv_addr, in_width,
+ in_height, wi->width, wi->height, wi->color_mode, wi->rotation,
+ wi->mirror);
+
+ out_rate = dispc_plane_output_rate(plane);
+
+ r = dispc_plane_setup(plane, caps, out_rate, wi->paddr, wi->p_uv_addr,
+ wi->buf_width, pos_x, pos_y, in_width, in_height,
+ wi->width, wi->height, wi->color_mode, wi->rotation,
+ wi->mirror, zorder, wi->pre_mult_alpha, global_alpha,
+ wi->rotation_type, replication, mgr_timings);
+
+ return r;
+}
+
int dispc_ovl_enable(enum omap_plane plane, bool enable)
{
DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index ea17d68..bd7c5cf 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -482,6 +482,8 @@ void dispc_mgr_setup(enum omap_channel channel,
struct omap_overlay_manager_info *info);
void dispc_wb_set_channel_in(enum dss_writeback_channel channel);
+int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
+ const struct omap_video_timings *timings);
/* VENC */
#ifdef CONFIG_OMAP2_DSS_VENC
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 46097bd..3729173 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -510,6 +510,19 @@ struct omap_dsi_pin_config {
int pins[OMAP_DSS_MAX_DSI_PINS];
};
+struct omap_dss_writeback_info {
+ u32 paddr;
+ u32 p_uv_addr;
+ u16 buf_width;
+ u16 width;
+ u16 height;
+ enum omap_color_mode color_mode;
+ u8 rotation;
+ enum omap_dss_rotation_type rotation_type;
+ bool mirror;
+ u8 pre_mult_alpha;
+};
+
struct omap_dss_output {
struct list_head list;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 18/21] OMAPDSS: DISPC: Configure writeback specific parameters in dispc_wb_setup()
From: Archit Taneja @ 2012-09-13 12:27 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
Configure some of the writeback specific parameters in dispc_wb_setup(). The
writeback parameters configured are:
truncation: This needs to be set if the color depth input to writeback is more
than the color depth of the color mode we want to store in memory.
writeback mode: This configures whether we want to use writeback in mem to mem
or capture mode. This information will be directly passed by APPLY later.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 26 +++++++++++++++++++++++++-
drivers/video/omap2/dss/dss.h | 2 +-
2 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index f575875..a44cbac 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2465,13 +2465,15 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,
}
int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
- const struct omap_video_timings *mgr_timings)
+ bool mem_to_mem, const struct omap_video_timings *mgr_timings)
{
int r;
+ u32 l;
enum omap_plane plane = OMAP_DSS_WB;
const int pos_x = 0, pos_y = 0;
const u8 zorder = 0, global_alpha = 0;
const bool replication = false;
+ bool truncation;
int in_width = mgr_timings->x_res;
int in_height = mgr_timings->y_res;
unsigned long out_rate;
@@ -2491,6 +2493,28 @@ int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
wi->mirror, zorder, wi->pre_mult_alpha, global_alpha,
wi->rotation_type, replication, mgr_timings);
+ switch (wi->color_mode) {
+ case OMAP_DSS_COLOR_RGB16:
+ case OMAP_DSS_COLOR_RGB24P:
+ case OMAP_DSS_COLOR_ARGB16:
+ case OMAP_DSS_COLOR_RGBA16:
+ case OMAP_DSS_COLOR_RGB12U:
+ case OMAP_DSS_COLOR_ARGB16_1555:
+ case OMAP_DSS_COLOR_XRGB16_1555:
+ case OMAP_DSS_COLOR_RGBX16:
+ truncation = true;
+ break;
+ default:
+ truncation = false;
+ break;
+ }
+
+ /* setup extra DISPC_WB_ATTRIBUTES */
+ l = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
+ l = FLD_MOD(l, truncation, 10, 10); /* TRUNCATIONENABLE */
+ l = FLD_MOD(l, mem_to_mem, 19, 19); /* WRITEBACKMODE */
+ dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), l);
+
return r;
}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index bd7c5cf..c49c054 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -483,7 +483,7 @@ void dispc_mgr_setup(enum omap_channel channel,
void dispc_wb_set_channel_in(enum dss_writeback_channel channel);
int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
- const struct omap_video_timings *timings);
+ bool mem_to_mem, const struct omap_video_timings *timings);
/* VENC */
#ifdef CONFIG_OMAP2_DSS_VENC
--
1.7.9.5
^ permalink raw reply related
* [PATCH 19/21] OMAPDSS: DISPC: Configure writeback FIFOs
From: Archit Taneja @ 2012-09-13 12:27 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
Extend the DISPC fifo functions to also configure the writeback FIFO thresholds.
The most optimal configuration for writeback is to push out data to the
interconnect the moment writeback pushes enough pixels in the FIFO to form a
burst. This reduces the chance of writeback overflowing it's FIFO.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index a44cbac..6068271 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -997,7 +997,7 @@ void dispc_wb_set_channel_in(enum dss_writeback_channel channel)
static void dispc_plane_set_burst_size(enum omap_plane plane,
enum omap_burst_size burst_size)
{
- static const unsigned shifts[] = { 6, 14, 14, 14, };
+ static const unsigned shifts[] = { 6, 14, 14, 14, 14, };
int shift;
shift = shifts[plane];
@@ -1229,6 +1229,14 @@ void dispc_plane_compute_fifo_thresholds(enum omap_plane plane,
if (manual_update && dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) {
*fifo_low = plane_fifo_size - burst_size * 2;
*fifo_high = total_fifo_size - burst_size;
+ } else if (plane = OMAP_DSS_WB) {
+ /*
+ * Most optimal configuration for writeback is to push out data
+ * to the interconnect the moment writeback pushes enough pixels
+ * in the FIFO to form a burst
+ */
+ *fifo_low = 0;
+ *fifo_high = burst_size;
} else {
*fifo_low = plane_fifo_size - burst_size;
*fifo_high = total_fifo_size - buf_unit;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 20/21] OMAPDSS: DISPC: Add manager like functions for writeback
From: Archit Taneja @ 2012-09-13 12:27 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
Add functions to enable writeback, and set/check state of GO bit. These bits are
identical in behaviour with the corresponding overlay manager bits. Configure
them in a similar way to mgr_enable() and mgr_go_* functions. Add a helper to
get the FRAMEDONE irq corresponding to writeback.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 70 +++++++++++++++++++++++++++++++++++++++
drivers/video/omap2/dss/dss.h | 5 +++
2 files changed, 75 insertions(+)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 6068271..1623c9b 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -535,6 +535,11 @@ u32 dispc_mgr_get_framedone_irq(enum omap_channel channel)
return mgr_desc[channel].framedone_irq;
}
+u32 dispc_wb_get_framedone_irq(void)
+{
+ return DISPC_IRQ_FRAMEDONEWB;
+}
+
bool dispc_mgr_go_busy(enum omap_channel channel)
{
return mgr_fld_read(channel, DISPC_MGR_FLD_GO) = 1;
@@ -562,6 +567,30 @@ void dispc_mgr_go(enum omap_channel channel)
mgr_fld_write(channel, DISPC_MGR_FLD_GO, 1);
}
+bool dispc_wb_go_busy(void)
+{
+ return REG_GET(DISPC_CONTROL2, 6, 6) = 1;
+}
+
+void dispc_wb_go(void)
+{
+ enum omap_plane plane = OMAP_DSS_WB;
+ bool enable, go;
+
+ enable = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0) = 1;
+
+ if (!enable)
+ return;
+
+ go = REG_GET(DISPC_CONTROL2, 6, 6) = 1;
+ if (go) {
+ DSSERR("GO bit not down for WB\n");
+ return;
+ }
+
+ REG_FLD_MOD(DISPC_CONTROL2, 1, 6, 6);
+}
+
static void dispc_plane_write_firh_reg(enum omap_plane plane, int reg,
u32 value)
{
@@ -2678,6 +2707,47 @@ void dispc_mgr_enable(enum omap_channel channel, bool enable)
BUG();
}
+void dispc_wb_enable(bool enable)
+{
+ enum omap_plane plane = OMAP_DSS_WB;
+ struct completion frame_done_completion;
+ bool is_on;
+ int r;
+ u32 irq;
+
+ is_on = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
+ irq = DISPC_IRQ_FRAMEDONEWB;
+
+ if (!enable && is_on) {
+ init_completion(&frame_done_completion);
+
+ r = omap_dispc_register_isr(dispc_disable_isr,
+ &frame_done_completion, irq);
+ if (r)
+ DSSERR("failed to register FRAMEDONEWB isr\n");
+ }
+
+ REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0);
+
+ if (!enable && is_on) {
+ if (!wait_for_completion_timeout(&frame_done_completion,
+ msecs_to_jiffies(100)))
+ DSSERR("timeout waiting for FRAMEDONEWB\n");
+
+ r = omap_dispc_unregister_isr(dispc_disable_isr,
+ &frame_done_completion, irq);
+ if (r)
+ DSSERR("failed to unregister FRAMEDONEWB isr\n");
+ }
+}
+
+bool dispc_wb_is_enabled(void)
+{
+ enum omap_plane plane = OMAP_DSS_WB;
+
+ return REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
+}
+
void dispc_lcd_enable_signal_polarity(bool act_high)
{
if (!dss_has_feature(FEAT_LCDENABLEPOL))
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index c49c054..59ea86a 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -481,6 +481,11 @@ int dispc_mgr_get_clock_div(enum omap_channel channel,
void dispc_mgr_setup(enum omap_channel channel,
struct omap_overlay_manager_info *info);
+u32 dispc_wb_get_framedone_irq(void);
+bool dispc_wb_go_busy(void);
+void dispc_wb_go(void);
+void dispc_wb_enable(bool enable);
+bool dispc_wb_is_enabled(void);
void dispc_wb_set_channel_in(enum dss_writeback_channel channel);
int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
bool mem_to_mem, const struct omap_video_timings *timings);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 21/21] OMAPDSS: DISPC: Configure color conversion coefficients for writeback
From: Archit Taneja @ 2012-09-13 12:27 UTC (permalink / raw)
To: tomi.valkeinen; +Cc: linux-omap, linux-fbdev, Archit Taneja
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
Writeback pipeline receives RGB data from one of the overlays or one of the
overlay managers. If the target color mode is YUV422 or NV12, we need to convert
the RGB pixels to YUV. The scalar in WB then converts it to the target color
mode.
Hence, the color conversion coefficients that need to be programmed are the ones
which convert a RGB24 pixel to YUV444. Program these coefficients for writeback
pipeline.
Signed-off-by: Archit Taneja <archit@ti.com>
---
drivers/video/omap2/dss/dispc.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 1623c9b..5811a18 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -681,20 +681,30 @@ static void dispc_plane_set_scale_coef(enum omap_plane plane, int fir_hinc,
static void _dispc_setup_color_conv_coef(void)
{
int i;
+ int num_ovl = dss_feat_get_num_ovls();
+ int num_wb = dss_feat_get_num_wbs();
+
const struct color_conv_coef {
int ry, rcr, rcb, gy, gcr, gcb, by, bcr, bcb;
int full_range;
- } ctbl_bt601_5 = {
- 298, 409, 0, 298, -208, -100, 298, 0, 517, 0,
+ } ctbl_bt601_5[2] = {
+ { 298, 409, 0, 298, -208, -100, 298, 0, 517, 0, },
+ { 66, 112, -38, 129, -94, -74, 25, -18, 112, 0, },
};
const struct color_conv_coef *ct;
#define CVAL(x, y) (FLD_VAL(x, 26, 16) | FLD_VAL(y, 10, 0))
+#define YUVTORGB 0
+#define RGBTOYUV 1
- ct = &ctbl_bt601_5;
+ ct = &ctbl_bt601_5[YUVTORGB];
+
+ for (i = 1; i < num_ovl + num_wb; i++) {
+
+ if (i >= num_ovl)
+ ct = &ctbl_bt601_5[RGBTOYUV];
- for (i = 1; i < dss_feat_get_num_ovls(); i++) {
dispc_write_reg(DISPC_OVL_CONV_COEF(i, 0),
CVAL(ct->rcr, ct->ry));
dispc_write_reg(DISPC_OVL_CONV_COEF(i, 1),
@@ -710,6 +720,8 @@ static void _dispc_setup_color_conv_coef(void)
11, 11);
}
+#undef RGBTOYUV
+#undef YUVTORGB
#undef CVAL
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH] video: exynos_dp: Add device tree support to DP driver
From: Ajay Kumar @ 2012-09-13 13:24 UTC (permalink / raw)
To: linux-samsung-soc, linux-fbdev, jg1.han, thomas.ab; +Cc: FlorianSchandinat
This patch enables device tree based discovery support for DP driver.
The driver is modified to handle platform data in both the cases:
with DT and non-DT.
DP-PHY should be regarded as a seperate device node while
being passed from device tree list, and device node for
DP should contain DP-PHY as child node with property name "dp-phy"
associated with it.
Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
---
drivers/video/exynos/exynos_dp_core.c | 156 +++++++++++++++++++++++++++++++--
drivers/video/exynos/exynos_dp_core.h | 2 +
2 files changed, 151 insertions(+), 7 deletions(-)
diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
index f57c915..15887bd 100644
--- a/drivers/video/exynos/exynos_dp_core.c
+++ b/drivers/video/exynos/exynos_dp_core.c
@@ -18,6 +18,7 @@
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/of.h>
#include <video/exynos_dp.h>
@@ -856,20 +857,117 @@ static irqreturn_t exynos_dp_irq_handler(int irq, void *arg)
return IRQ_HANDLED;
}
+#ifdef CONFIG_OF
+struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev)
+{
+ struct device_node *dp_node = dev->of_node;
+ struct exynos_dp_platdata *pd;
+ struct video_info *dp_video_config;
+
+ pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
+ if (!pd) {
+ dev_err(dev, "memory allocation for pdata failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ dp_video_config = devm_kzalloc(dev,
+ sizeof(*dp_video_config), GFP_KERNEL);
+
+ if (!dp_video_config) {
+ dev_err(dev, "memory allocation for video config failed\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ pd->video_info = dp_video_config;
+
+ if (of_get_property(dp_node, "samsung,h-sync-polarity", NULL))
+ dp_video_config->h_sync_polarity = 1;
+
+ if (of_get_property(dp_node, "samsung,v-sync-polarity", NULL))
+ dp_video_config->v_sync_polarity = 1;
+
+ if (of_get_property(dp_node, "samsung,interlaced", NULL))
+ dp_video_config->interlaced = 1;
+
+ of_property_read_u32(dp_node, "samsung,color_space",
+ &dp_video_config->color_space);
+
+ of_property_read_u32(dp_node, "samsung,dynamic_range",
+ &dp_video_config->dynamic_range);
+
+ of_property_read_u32(dp_node, "samsung,ycbcr_coeff",
+ &dp_video_config->ycbcr_coeff);
+
+ of_property_read_u32(dp_node, "samsung,color_depth",
+ &dp_video_config->color_depth);
+
+ of_property_read_u32(dp_node, "samsung,link_rate",
+ &dp_video_config->link_rate);
+
+ of_property_read_u32(dp_node, "samsung,lane_count",
+ &dp_video_config->lane_count);
+ return pd;
+}
+
+void exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
+{
+ struct device_node *dp_phy_node;
+
+ const __be32 *parp;
+
+ u32 phy_base;
+
+ void *virt_phy_base;
+
+ parp = of_get_property(dp->dev->of_node, "dp_phy", NULL);
+ if (!parp) {
+ dp->dp_phy_addr = NULL;
+ return;
+ }
+
+ dp_phy_node = of_find_node_by_phandle(be32_to_cpup(parp));
+ if (!dp_phy_node) {
+ dp->dp_phy_addr = NULL;
+ return;
+ }
+
+ of_property_read_u32(dp_phy_node, "samsung,dptx_phy_reg", &phy_base);
+ of_property_read_u32(dp_phy_node, "samsung,enable_bit",
+ &dp->enable_bit);
+ virt_phy_base = ioremap(phy_base, SZ_4);
+ if (!virt_phy_base) {
+ dev_err(dp->dev, "failed to ioremap dp-phy\n");
+ dp->dp_phy_addr = NULL;
+ return;
+ }
+ dp->dp_phy_addr = virt_phy_base;
+}
+
+void dp_phy_init(struct exynos_dp_device *dp)
+{
+ u32 reg;
+
+ reg = __raw_readl(dp->dp_phy_addr);
+ reg |= dp->enable_bit;
+ __raw_writel(reg, dp->dp_phy_addr);
+}
+
+void dp_phy_exit(struct exynos_dp_device *dp)
+{
+ u32 reg;
+
+ reg = __raw_readl(dp->dp_phy_addr);
+ reg &= ~(dp->enable_bit);
+ __raw_writel(reg, dp->dp_phy_addr);
+}
+#endif /* CONFIG_OF */
+
static int __devinit exynos_dp_probe(struct platform_device *pdev)
{
struct resource *res;
struct exynos_dp_device *dp;
- struct exynos_dp_platdata *pdata;
+ struct exynos_dp_platdata *pdata = pdev->dev.platform_data;
int ret = 0;
- pdata = pdev->dev.platform_data;
- if (!pdata) {
- dev_err(&pdev->dev, "no platform data\n");
- return -EINVAL;
- }
-
dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
GFP_KERNEL);
if (!dp) {
@@ -879,6 +982,19 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
dp->dev = &pdev->dev;
+ if (pdev->dev.of_node) {
+ pdata = exynos_dp_dt_parse_pdata(&pdev->dev);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+
+ exynos_dp_dt_parse_phydata(dp);
+ }
+
+ if (!pdata) {
+ dev_err(&pdev->dev, "no platform data\n");
+ return -EINVAL;
+ }
+
dp->clock = devm_clk_get(&pdev->dev, "dp");
if (IS_ERR(dp->clock)) {
dev_err(&pdev->dev, "failed to get clock\n");
@@ -909,9 +1025,13 @@ static int __devinit exynos_dp_probe(struct platform_device *pdev)
}
dp->video_info = pdata->video_info;
if (pdata->phy_init)
pdata->phy_init();
+ if (pdev->dev.of_node)
+ if (dp->dp_phy_addr)
+ dp_phy_init(dp);
+
exynos_dp_init_dp(dp);
ret = exynos_dp_detect_hpd(dp);
@@ -956,6 +1077,10 @@ static int __devexit exynos_dp_remove(struct platform_device *pdev)
if (pdata && pdata->phy_exit)
pdata->phy_exit();
+ if (pdev->dev.of_node)
+ if (dp->dp_phy_addr)
+ dp_phy_exit(dp);
+
clk_disable(dp->clock);
return 0;
@@ -971,6 +1096,10 @@ static int exynos_dp_suspend(struct device *dev)
if (pdata && pdata->phy_exit)
pdata->phy_exit();
+ if (dev->of_node)
+ if (dp->dp_phy_addr)
+ dp_phy_exit(dp);
+
clk_disable(dp->clock);
return 0;
@@ -985,6 +1114,10 @@ static int exynos_dp_resume(struct device *dev)
if (pdata && pdata->phy_init)
pdata->phy_init();
+ if (dev->of_node)
+ if (dp->dp_phy_addr)
+ dp_phy_init(dp);
+
clk_enable(dp->clock);
exynos_dp_init_dp(dp);
@@ -1013,6 +1146,14 @@ static const struct dev_pm_ops exynos_dp_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume)
};
+#ifdef CONFIG_OF
+static const struct of_device_id exynos_dp_match[] = {
+ { .compatible = "samsung,exynos5-dp" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, exynos_dp_match);
+#endif
+
static struct platform_driver exynos_dp_driver = {
.probe = exynos_dp_probe,
.remove = __devexit_p(exynos_dp_remove),
@@ -1020,6 +1161,7 @@ static struct platform_driver exynos_dp_driver = {
.name = "exynos-dp",
.owner = THIS_MODULE,
.pm = &exynos_dp_pm_ops,
+ .of_match_table = of_match_ptr(exynos_dp_match),
},
};
diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h
index 57b8a65..49b30cb 100644
--- a/drivers/video/exynos/exynos_dp_core.h
+++ b/drivers/video/exynos/exynos_dp_core.h
@@ -29,6 +29,8 @@ struct exynos_dp_device {
struct clk *clock;
unsigned int irq;
void __iomem *reg_base;
+ void __iomem *dp_phy_addr;
+ int enable_bit;
struct video_info *video_info;
struct link_train link_train;
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH v6 0/4] Runtime Interpreted Power Sequences
From: Stephen Warren @ 2012-09-13 15:24 UTC (permalink / raw)
To: Mark Brown
Cc: Alex Courbot, linux-fbdev@vger.kernel.org, Stephen Warren,
linux-pm@vger.kernel.org, Leela Krishna Amudala,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
Rob Herring, Anton Vorontsov, Tomi Valkeinen,
linux-tegra@vger.kernel.org, David Woodhouse,
devicetree-discuss@lists.ozlabs.org
In-Reply-To: <20120913072943.GB20959@opensource.wolfsonmicro.com>
On 09/13/2012 01:29 AM, Mark Brown wrote:
> On Thu, Sep 13, 2012 at 04:26:34PM +0900, Alex Courbot wrote:
>> On Thursday 13 September 2012 15:19:30 Mark Brown wrote:
>>>> On Thursday 13 September 2012 14:25:53 Mark Brown wrote:
>>>>> It would be sensible to make sure that the framework is done in such a
>>>>> way that drivers can use it - there will be drivers (perhaps not display
>>>>> ones) that have a known power sequence and which could benefit from the
>>>>> ability to use library code to implement it based on the user simply
>>>>> supplying named resources.
>
>>>> Not sure I understand what you mean, but things should be working this way
>>>> already - regulators and PWMs are acquired by name using the standard
>>>> regulator_get() and pwm_get() functions. GPIOs do not, AFAIK, have a way
>>>> to be referenced by name so their number is used instead.
>
>>> Right, but the sequencing for enabling them is currently open coded in
>>> each driver.
>
>> Mmm then I'm afraid I don't see what you wanted to say initially - could you
>> elaborate?
>
> The driver knows the power sequence. Having to type the same sequence
> into the DT or platform data for each board using the device wouuld be
> retarded so we need the drivers to be able to give the sequence to the
> library if they're going to be able to reuse it (which is a lot of what
> Tomi is talking about).
I believe that's trivial to implement. The relevant function is:
struct power_seq_set *devm_power_seq_set_build(struct device *dev,
struct platform_power_seq_set *pseq);
It's up to the driver whether pseq comes from platform data or is
hard-coded into the driver (or not provided at all, for the DT case).
So, the only change needed to convert a "hard-coded" driver to this API
is to convert the current custom data structure (or code) that describes
the sequence into a struct platform_power_seq_set.
^ permalink raw reply
* Re: [PATCH v6 1/4] Runtime Interpreted Power Sequences
From: Stephen Warren @ 2012-09-13 15:37 UTC (permalink / raw)
To: Alex Courbot
Cc: Tomi Valkeinen, Stephen Warren, Thierry Reding, Simon Glass,
Grant Likely, Rob Herring, Mark Brown, Anton Vorontsov,
David Woodhouse, Arnd Bergmann, Leela Krishna Amudala,
linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-fbdev@vger.kernel.org, devicetree-discuss@lists.ozlabs.org,
linux-pm@vger.kernel.org, linux-doc@vger.kernel.org
In-Reply-To: <3082244.Oec3ulPCgi@percival>
On 09/13/2012 01:08 AM, Alex Courbot wrote:
> On Thursday 13 September 2012 14:54:09 Tomi Valkeinen wrote:
>> * PGP Signed by an unknown key
>>
>> On Thu, 2012-09-13 at 15:36 +0900, Alex Courbot wrote:
>>
>>> On Thursday 13 September 2012 14:22:57 Tomi Valkeinen wrote:
>>>
>>>
>>>
>>>> However, I fear these board specific things may be quite a bit
>>>> anything,
>>>> so it may well be pwm, gpios and regulators are not enough for them.
>>>> For
>>>> example, there could be an FPGA on the board which requires some
>>>> configuration to accomplish the task at hand. It could be rather
>>>> difficult to handle it with a generic power sequence.
>>>
>>>
>>> Right. Note that this framework is supposed to be extended - I would like
>>> to at least add regulator voltage setting, and maybe even support for
>>> clocks and pinmux (but that might be out of place).
>>
>>
>> Yes, that's one concern of mine... I already can imagine someone
>> suggesting adding conditionals to the power sequence data.
>
> I took care of that when naming the feature - it is not a "sequence" anymore
> if you have conditionals. :P
>
>> Perhaps also
>> direct memory read/writes so you can twiddle registers directly. And so
>> on. Where's the limit what it should contain? Can we soon write full
>> drivers with the DT data? =)
>
> I shall be satisfied the day the kernel is released as one big DT node along
> with the 5KB interpreter that runs it.
I know you're joking, but *cough* OpenFirmware *cough*, right?
^ permalink raw reply
* Re: [PATCH v6 1/4] Runtime Interpreted Power Sequences
From: Stephen Warren @ 2012-09-13 15:44 UTC (permalink / raw)
To: Alex Courbot
Cc: linux-fbdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Mark Brown,
Stephen Warren, linux-pm-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Leela Krishna Amudala,
linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Rob Herring,
Anton Vorontsov,
linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
David Woodhouse,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
In-Reply-To: <3678448.5nUOr4ZZV4@percival>
On 09/13/2012 12:02 AM, Alex Courbot wrote:
> On Thursday 13 September 2012 06:07:13 Stephen Warren wrote:
>> On 09/12/2012 03:57 AM, Alexandre Courbot wrote:
>>> Some device drivers (panel backlights especially) need to follow precise
>>> sequences for powering on and off, involving gpios, regulators, PWMs
>>> with a precise powering order and delays to respect between each steps.
>>> These sequences are board-specific, and do not belong to a particular
>>> driver - therefore they have been performed by board-specific hook
>>> functions to far.
>>>
>>> With the advent of the device tree and of ARM kernels that are not
>>> board-tied, we cannot rely on these board-specific hooks anymore but
>>> need a way to implement these sequences in a portable manner. This patch
>>> introduces a simple interpreter that can execute such power sequences
>>> encoded either as platform data or within the device tree.
>>>
>>> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
>>>
>>> diff --git a/Documentation/power/power_seq.txt
>>> b/Documentation/power/power_seq.txt
>>>
>>> +Sometimes, you may want to browse the list of resources allocated by a
>>> sequence, +for instance to ensure that a resource of a given type is
>>> present. The +power_seq_set_resources() function returns a list head that
>>> can be used with +the power_seq_for_each_resource() macro to browse all
>>> the resources of a set: +
>>> + struct list_head *power_seq_set_resources(struct power_seq_set *seqs);
>>> + power_seq_for_each_resource(pos, seqs)
>>> +
>>> +Here "pos" will be a pointer to a struct power_seq_resource. This
>>> structure +contains the type of the resource, the information used for
>>> identifying it, and +the resolved resource itself.
>>
>> I don't think you need to include that [power_seq_set_resources] prototype
>> here?
>
> Why not? I thought it was customary to include the prototypes in the
> documentation, and this seems to be the right place for this function.
It's something used internally to the macro; what the user cares about
is which macro to use for the functionality you're describing, not any
prototypes needed by the internal implementation of the macro, which are
always provided by the appropriate header.
>>> diff --git a/drivers/power/power_seq/power_seq.c
>>> b/drivers/power/power_seq/power_seq.c
>>>
>>> +struct power_seq_step {
>>> + /* Copy of the platform data */
>>> + struct platform_power_seq_step pdata;
>>
>> I'd reword the comment to "Copy of the step", and name the field "step".
>
> That would make a step within a step - doesn't pdata make it more explicit
> what this member is for (containing the platform data for this step)?
Well, it's not always platform data; it could come from device tree.
Sorry for bike-shedding slightly, but how about just "data",
"step_data", "config", or "step_config"?
>>> +static const struct power_seq_res_ops
>>> power_seq_types[POWER_SEQ_NUM_TYPES] = { + [POWER_SEQ_DELAY] >>> POWER_SEQ_DELAY_TYPE,
>>> + [POWER_SEQ_REGULATOR] = POWER_SEQ_REGULATOR_TYPE,
>>> + [POWER_SEQ_PWM] = POWER_SEQ_PWM_TYPE,
>>> + [POWER_SEQ_GPIO] = POWER_SEQ_GPIO_TYPE,
>>> +};
>>
>> Ah, I see why you're using #include now.
>
> We could also go with something more dynamic and compile these files
> separately, but that would require some registration mechanism which I don't
> think is needed for such a simple feature.
Sure. There are already examples in the kernel of basically what you're
doing anyway, and it's not like it'd be hard to change this if we want
to do something different in the future too.
^ permalink raw reply
* Re: [PATCH 2/5] drivers/video/gbefb.c: use devm_ functions
From: Geert Uytterhoeven @ 2012-09-13 19:06 UTC (permalink / raw)
To: Florian Tobias Schandinat
Cc: Damien Cassou, kernel-janitors, linux-fbdev, linux-kernel
In-Reply-To: <50369498.4010006@gmx.de>
On Thu, Aug 23, 2012 at 10:37 PM, Florian Tobias Schandinat
<FlorianSchandinat@gmx.de> wrote:
> On 07/31/2012 04:39 PM, Damien Cassou wrote:
>> From: Damien Cassou <damien.cassou@lifl.fr>
>>
>> The various devm_ functions allocate memory that is released when a driver
>> detaches. This patch uses these functions for data that is allocated in
>> the probe function of a platform device and is only freed in the remove
>> function.
>>
>> Signed-off-by: Damien Cassou <damien.cassou@lifl.fr>
>
> Applied.
>> diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
>> index 7e7b7a9..9b79d38 100644
>> --- a/drivers/video/gbefb.c
>> +++ b/drivers/video/gbefb.c
>> @@ -1156,7 +1156,8 @@ static int __devinit gbefb_probe(struct platform_device *p_dev)
>> goto out_release_framebuffer;
>> }
>>
>> - gbe = (struct sgi_gbe *) ioremap(GBE_BASE, sizeof(struct sgi_gbe));
>> + gbe = (struct sgi_gbe *) devm_ioremap(&p_dev->dev, GBE_BASE,
>> + sizeof(struct sgi_gbe));
drivers/video/gbefb.c:1159:16: error: implicit declaration of function
'devm_ioremap' [-Werror=implicit-function-declaration]
drivers/video/gbefb.c:1179:3: error: implicit declaration of function
'devm_ioremap_nocache' [-Werror=implicit-function-declaration]
http://kisskb.ellerman.id.au/kisskb/buildresult/7187731/
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [RFC 1/5] video: Add generic display panel core
From: Robert Schwebel @ 2012-09-13 19:32 UTC (permalink / raw)
To: Sascha Hauer
Cc: Laurent Pinchart, linux-fbdev, Marcus Lorentzon, dri-devel,
Kyungmin Park, Richard Purdie, Sebastien Guiriec, Bryan Wu,
linux-leds, linux-media, Steffen Trumtrar
In-Reply-To: <20120913112954.GI6180@pengutronix.de>
On Thu, Sep 13, 2012 at 01:29:54PM +0200, Sascha Hauer wrote:
> > > You have seen my of videomode helper proposal. One result there
> > > was that we want to have ranges for the margin/synclen fields.
> > > Does it make sense to base this new panel framework on a more
> > > sophisticated internal reprentation of the panel parameters?
> >
> > I think it does, yes. We need a common video mode structure, and the
> > panel framework should use it. I'll try to rebase my patches on top
> > of your proposal. Have you posted the latest version ?
>
> V2 is the newest version. I'd like to implement ranges for the display
> timings which then makes for a new common video mode structure, which
> then could be used by drm and fbdev, probably with helper functions to
> convert from common videomode to drm/fbdev specific variants.
Steffen has a reworked series with the latest changes and will post them
soon.
rsc
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* Re: [PATCHv3 1/4] video: mmp display subsystem
From: Zhou Zhu @ 2012-09-14 2:54 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1347007704-27645-1-git-send-email-zzhu3@marvell.com>
Hi, Florian,
Would you please help to review my patches?
Thank you very much!
On Fri, Sep 7, 2012 at 4:48 PM, Zhou Zhu <zzhu3@marvell.com> wrote:
> Added mmp display subsystem to support Marvell MMP display controllers.
>
> This subsystem contains 4 parts:
> --fb folder
> --core.c
> --hw folder
> --panel folder
>
> 1. fb folder contains implementation of fb.
> fb get path and ovly from common interface and operates on these structures.
>
> 2. core.c provides common interface for a hardware abstraction.
> Major parts of this interface are:
> a) Path: path is a output device connected to a panel or HDMI TV.
> Main operations of the path is set/get timing/output color.
> fb operates output device through path structure.
> b) Ovly: Ovly is a buffer shown on the path.
> Ovly describes frame buffer and its source/destination size, offset, input
> color, buffer address, z-order, and so on.
> Each fb device maps to one ovly.
>
> 3. hw folder contains implementation of hardware operations defined by core.c.
> It registers paths for fb use.
>
> 4. panel folder contains implementation of panels.
> It's connected to path. Panel drivers would also regiester panels and linked
> to path when probe.
>
> Signed-off-by: Zhou Zhu <zzhu3@marvell.com>
> Signed-off-by: Lisa Du <cldu@marvell.com>
Thanks,
-Zhou
^ permalink raw reply
* Re: [PATCH 00/21] OMAPDSS: DISPC changes for writeback pipeline
From: Tomi Valkeinen @ 2012-09-14 8:27 UTC (permalink / raw)
To: Archit Taneja; +Cc: linux-omap, linux-fbdev
In-Reply-To: <1347538505-25359-1-git-send-email-archit@ti.com>
[-- Attachment #1: Type: text/plain, Size: 2489 bytes --]
On Thu, 2012-09-13 at 17:44 +0530, Archit Taneja wrote:
> DSS HW on OMAP4 onwards supports a new pipeline called writeback. Unlike other
> pipelines(called overlays in OMAPDSS), writeback takes pixel data from an
> overlay output or a overlay manager output and writes it back into a specified
> address in memory.
>
> writeback pipeline allows us to take benefit of the hardware processing
> available inside the DISPC like color space conversion, rescaling, compositing
> etc and do either a) perform memory-to-memory transfer with data processing,
> b) capture a displayed frame. The former is known as memory to memory mode of
> the writeback pipeline, and the latter is known as capture mode. More details
> about writeback can be found in the Display Subsystem section of the OMAP4/5 TRMs.
>
> witeback has properties of both overlays and overlay managers. It is like an
> overlay as it has programmable base addresses and contains blocks like scalar,
You consistently use the term "scalar" in the patches, but I believe the
correct term is "scaler".
> color conversion unit, truncation unit, DISPC DMA FIFO. It is like a manager as
> enabling it immediately starts transfer to the memory, and it has a GO bit to use
> a new writeback configuration.
>
> This series prepares the low level DISPC driver(dispc.c) to configure writeback
> registers. The aim is to reuse most of the code as most of its registers are
> like overlay or manager registers, and are configured in the same way in most
> cases. The first few patches rename dispc_ovl_* functions to dispc_plane_*
I'm not sure if the renaming causes more confusion than clarity... It
kinda creates a mishmash of ovl/plane names, and the term "plane"
doesn't really sound like it's a base for both overlays and wb. Could we
consider the wb as a special case, and keep the ovl name for most of the
things and have "wb" used for wb specific things?
> functions. The next few patches change how overlay caps are used within the
> dispc functions, this helps reusing more functions between overlays and
I dislike this a bit, I think dispc driver should know what HW it has,
you shouldn't need to pass caps to it. So I'd prefer the dispc driver to
to have this information in dispc_features. I believe all OVL_CAPS
should be there, and then exported to other drivers via some means. I
guess this means could for now be just initializing ovl->caps with data
from dispc.c.
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH 00/21] OMAPDSS: DISPC changes for writeback pipeline
From: Tomi Valkeinen @ 2012-09-14 8:46 UTC (permalink / raw)
To: Archit Taneja; +Cc: linux-omap, linux-fbdev
In-Reply-To: <1347611263.2559.44.camel@deskari>
[-- Attachment #1: Type: text/plain, Size: 1200 bytes --]
On Fri, 2012-09-14 at 11:27 +0300, Tomi Valkeinen wrote:
> On Thu, 2012-09-13 at 17:44 +0530, Archit Taneja wrote:
> > This series prepares the low level DISPC driver(dispc.c) to configure writeback
> > registers. The aim is to reuse most of the code as most of its registers are
> > like overlay or manager registers, and are configured in the same way in most
> > cases. The first few patches rename dispc_ovl_* functions to dispc_plane_*
>
> I'm not sure if the renaming causes more confusion than clarity... It
> kinda creates a mishmash of ovl/plane names, and the term "plane"
> doesn't really sound like it's a base for both overlays and wb. Could we
> consider the wb as a special case, and keep the ovl name for most of the
> things and have "wb" used for wb specific things?
And while WB is a combination of overlays and ovl managers, do you think
it'd be difficult to consider WB as a special, extended overlay? So just
call it an overlay, and consider it as an overlay with special features,
at least inside dispc.c. We probably need to have it as a totally
different entity from user's point of view (i.e. the list of overlays
wouldn't return WB, etc).
Tomi
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox