msm: sde: Add support for 1.5x downscale in rotator

msmcobalt v2 supports 1.5x downscaling in the rotator.

CRs-Fixed: 1055035
Change-Id: Icd71fd6d53783a7972305d1256acb209698e575d
Signed-off-by: Benjamin Chan <bkchan@codeaurora.org>
This commit is contained in:
Benjamin Chan 2016-08-16 17:21:01 -04:00 committed by Gerrit - the friendly Code Review server
parent 008f057bba
commit 5658702aa3
4 changed files with 76 additions and 7 deletions

View file

@ -62,9 +62,27 @@ enum sde_qos_settings {
SDE_QOS_MAX, SDE_QOS_MAX,
}; };
/**
* enum sde_rot_type: SDE rotator HW version
* @SDE_ROT_TYPE_V1_0: V1.0 HW version
* @SDE_ROT_TYPE_V1_1: V1.1 HW version
*/
enum sde_rot_type {
SDE_ROT_TYPE_V1_0 = 0x10000000,
SDE_ROT_TYPE_V1_1 = 0x10010000,
SDE_ROT_TYPE_MAX,
};
/**
* enum sde_caps_settings: SDE rotator capability definition
* @SDE_CAPS_R1_WB: MDSS V1.x WB block
* @SDE_CAPS_R3_WB: MDSS V3.x WB block
* @SDE_CAPS_R3_1P5_DOWNSCALE: 1.5x downscale rotator support
*/
enum sde_caps_settings { enum sde_caps_settings {
SDE_CAPS_R1_WB, SDE_CAPS_R1_WB,
SDE_CAPS_R3_WB, SDE_CAPS_R3_WB,
SDE_CAPS_R3_1P5_DOWNSCALE,
SDE_CAPS_MAX, SDE_CAPS_MAX,
}; };

View file

@ -337,16 +337,19 @@ static void sde_hw_rotator_setup_timestamp_packet(
* @cfg: Fetch configuration * @cfg: Fetch configuration
* @danger_lut: real-time QoS LUT for danger setting (not used) * @danger_lut: real-time QoS LUT for danger setting (not used)
* @safe_lut: real-time QoS LUT for safe setting (not used) * @safe_lut: real-time QoS LUT for safe setting (not used)
* @dnsc_factor_w: downscale factor for width
* @dnsc_factor_h: downscale factor for height
* @flags: Control flag * @flags: Control flag
*/ */
static void sde_hw_rotator_setup_fetchengine(struct sde_hw_rotator_context *ctx, static void sde_hw_rotator_setup_fetchengine(struct sde_hw_rotator_context *ctx,
enum sde_rot_queue_prio queue_id, enum sde_rot_queue_prio queue_id,
struct sde_hw_rot_sspp_cfg *cfg, u32 danger_lut, u32 safe_lut, struct sde_hw_rot_sspp_cfg *cfg, u32 danger_lut, u32 safe_lut,
u32 flags) u32 dnsc_factor_w, u32 dnsc_factor_h, u32 flags)
{ {
struct sde_hw_rotator *rot = ctx->rot; struct sde_hw_rotator *rot = ctx->rot;
struct sde_mdp_format_params *fmt; struct sde_mdp_format_params *fmt;
struct sde_mdp_data *data; struct sde_mdp_data *data;
struct sde_rot_data_type *mdata = sde_rot_get_mdata();
u32 *wrptr; u32 *wrptr;
u32 opmode = 0; u32 opmode = 0;
u32 chroma_samp = 0; u32 chroma_samp = 0;
@ -465,10 +468,19 @@ static void sde_hw_rotator_setup_fetchengine(struct sde_hw_rotator_context *ctx,
SDE_REGDMA_BLKWRITE_DATA(wrptr, opmode); SDE_REGDMA_BLKWRITE_DATA(wrptr, opmode);
/* setup source fetch config, TP10 uses different block size */ /* setup source fetch config, TP10 uses different block size */
if (sde_mdp_is_tp10_format(fmt)) if (test_bit(SDE_CAPS_R3_1P5_DOWNSCALE, mdata->sde_caps_map) &&
fetch_blocksize = SDE_ROT_SSPP_FETCH_BLOCKSIZE_96; (dnsc_factor_w == 1) && (dnsc_factor_h == 1)) {
else if (sde_mdp_is_tp10_format(fmt))
fetch_blocksize = SDE_ROT_SSPP_FETCH_BLOCKSIZE_128; fetch_blocksize = SDE_ROT_SSPP_FETCH_BLOCKSIZE_144_EXT;
else
fetch_blocksize = SDE_ROT_SSPP_FETCH_BLOCKSIZE_192_EXT;
} else {
if (sde_mdp_is_tp10_format(fmt))
fetch_blocksize = SDE_ROT_SSPP_FETCH_BLOCKSIZE_96;
else
fetch_blocksize = SDE_ROT_SSPP_FETCH_BLOCKSIZE_128;
}
SDE_REGDMA_WRITE(wrptr, ROT_SSPP_FETCH_CONFIG, SDE_REGDMA_WRITE(wrptr, ROT_SSPP_FETCH_CONFIG,
fetch_blocksize | fetch_blocksize |
SDE_ROT_SSPP_FETCH_CONFIG_RESET_VALUE | SDE_ROT_SSPP_FETCH_CONFIG_RESET_VALUE |
@ -1306,7 +1318,8 @@ static int sde_hw_rotator_config(struct sde_rot_hw_resource *hw,
true : false); true : false);
rot->ops.setup_rotator_fetchengine(ctx, ctx->q_id, rot->ops.setup_rotator_fetchengine(ctx, ctx->q_id,
&sspp_cfg, danger_lut, safe_lut, flags); &sspp_cfg, danger_lut, safe_lut,
entry->dnsc_factor_w, entry->dnsc_factor_h, flags);
wb_cfg.img_width = item->output.width; wb_cfg.img_width = item->output.width;
wb_cfg.img_height = item->output.height; wb_cfg.img_height = item->output.height;
@ -1522,6 +1535,11 @@ static int sde_rotator_hw_rev_init(struct sde_hw_rotator *rot)
set_bit(SDE_CAPS_R3_WB, mdata->sde_caps_map); set_bit(SDE_CAPS_R3_WB, mdata->sde_caps_map);
if (hw_version != SDE_ROT_TYPE_V1_0) {
SDEROT_DBG("Supporting 1.5 downscale for SDE Rotator\n");
set_bit(SDE_CAPS_R3_1P5_DOWNSCALE, mdata->sde_caps_map);
}
return 0; return 0;
} }
@ -1674,6 +1692,7 @@ static irqreturn_t sde_hw_rotator_regdmairq_handler(int irq, void *ptr)
static int sde_hw_rotator_validate_entry(struct sde_rot_mgr *mgr, static int sde_hw_rotator_validate_entry(struct sde_rot_mgr *mgr,
struct sde_rot_entry *entry) struct sde_rot_entry *entry)
{ {
struct sde_rot_data_type *mdata = sde_rot_get_mdata();
int ret = 0; int ret = 0;
u16 src_w, src_h, dst_w, dst_h; u16 src_w, src_h, dst_w, dst_h;
struct sde_rotation_item *item = &entry->item; struct sde_rotation_item *item = &entry->item;
@ -1697,7 +1716,7 @@ static int sde_hw_rotator_validate_entry(struct sde_rot_mgr *mgr,
if ((src_w % dst_w) || (src_h % dst_h)) { if ((src_w % dst_w) || (src_h % dst_h)) {
SDEROT_DBG("non integral scale not support\n"); SDEROT_DBG("non integral scale not support\n");
ret = -EINVAL; ret = -EINVAL;
goto dnsc_err; goto dnsc_1p5_check;
} }
entry->dnsc_factor_w = src_w / dst_w; entry->dnsc_factor_w = src_w / dst_w;
if ((entry->dnsc_factor_w & (entry->dnsc_factor_w - 1)) || if ((entry->dnsc_factor_w & (entry->dnsc_factor_w - 1)) ||
@ -1726,6 +1745,32 @@ static int sde_hw_rotator_validate_entry(struct sde_rot_mgr *mgr,
SDEROT_DBG("downscale with ubwc cannot be more than 2\n"); SDEROT_DBG("downscale with ubwc cannot be more than 2\n");
ret = -EINVAL; ret = -EINVAL;
} }
goto dnsc_err;
dnsc_1p5_check:
/* Check for 1.5 downscale that only applies to V2 HW */
if (test_bit(SDE_CAPS_R3_1P5_DOWNSCALE, mdata->sde_caps_map)) {
entry->dnsc_factor_w = src_w / dst_w;
if ((entry->dnsc_factor_w != 1) ||
((dst_w * 3) != (src_w * 2))) {
SDEROT_DBG(
"No supporting non 1.5 downscale width ratio, src_w:%d, dst_w:%d\n",
src_w, dst_w);
ret = -EINVAL;
goto dnsc_err;
}
entry->dnsc_factor_h = src_h / dst_h;
if ((entry->dnsc_factor_h != 1) ||
((dst_h * 3) != (src_h * 2))) {
SDEROT_DBG(
"Not supporting non 1.5 downscale height ratio, src_h:%d, dst_h:%d\n",
src_h, dst_h);
ret = -EINVAL;
goto dnsc_err;
}
ret = 0;
}
dnsc_err: dnsc_err:
/* Downscaler does not support asymmetrical dnsc */ /* Downscaler does not support asymmetrical dnsc */

View file

@ -128,6 +128,8 @@
#define SDE_ROT_SSPP_FETCH_CONFIG_RESET_VALUE 0x00087 #define SDE_ROT_SSPP_FETCH_CONFIG_RESET_VALUE 0x00087
#define SDE_ROT_SSPP_FETCH_BLOCKSIZE_128 (0 << 16) #define SDE_ROT_SSPP_FETCH_BLOCKSIZE_128 (0 << 16)
#define SDE_ROT_SSPP_FETCH_BLOCKSIZE_96 (2 << 16) #define SDE_ROT_SSPP_FETCH_BLOCKSIZE_96 (2 << 16)
#define SDE_ROT_SSPP_FETCH_BLOCKSIZE_192_EXT ((0 << 16) | (1 << 15))
#define SDE_ROT_SSPP_FETCH_BLOCKSIZE_144_EXT ((2 << 16) | (1 << 15))
/* SDE_ROT_WB: /* SDE_ROT_WB:

View file

@ -116,6 +116,8 @@ struct sde_hw_rotator_ops {
* @cfg: Rotator Fetch engine configuration parameters * @cfg: Rotator Fetch engine configuration parameters
* @danger_lut: Danger LUT setting * @danger_lut: Danger LUT setting
* @safe_lut: Safe LUT setting * @safe_lut: Safe LUT setting
* @dnsc_factor_w: Downscale factor for width
* @dnsc_factor_h: Downscale factor for height
* @flags: Specific config flag, see SDE_ROT_FLAG_ for details * @flags: Specific config flag, see SDE_ROT_FLAG_ for details
*/ */
void (*setup_rotator_fetchengine)( void (*setup_rotator_fetchengine)(
@ -124,6 +126,8 @@ struct sde_hw_rotator_ops {
struct sde_hw_rot_sspp_cfg *cfg, struct sde_hw_rot_sspp_cfg *cfg,
u32 danger_lut, u32 danger_lut,
u32 safe_lut, u32 safe_lut,
u32 dnsc_factor_w,
u32 dnsc_factor_h,
u32 flags); u32 flags);
/** /**