drm/amd/display: moving cursor functions from ipp to mem_input
Signed-off-by: Yue Hin Lau <Yuehin.Lau@amd.com> Reviewed-by: Tony Cheng <Tony.Cheng@amd.com> Acked-by: Harry Wentland <Harry.Wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
60d671db1c
commit
b87d78d6aa
@ -195,13 +195,23 @@ bool dc_stream_set_cursor_attributes(
|
|||||||
for (i = 0; i < MAX_PIPES; i++) {
|
for (i = 0; i < MAX_PIPES; i++) {
|
||||||
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
|
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
|
||||||
|
|
||||||
if (pipe_ctx->stream != stream || !pipe_ctx->plane_res.ipp)
|
if (pipe_ctx->stream != stream || !pipe_ctx->plane_res.mi || !pipe_ctx->plane_res.xfm)
|
||||||
continue;
|
continue;
|
||||||
if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
|
if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
if (pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes != NULL)
|
||||||
pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
|
pipe_ctx->plane_res.ipp->funcs->ipp_cursor_set_attributes(
|
||||||
pipe_ctx->plane_res.ipp, attributes);
|
pipe_ctx->plane_res.ipp, attributes);
|
||||||
|
|
||||||
|
if (pipe_ctx->plane_res.mi->funcs->set_cursor_attributes != NULL)
|
||||||
|
pipe_ctx->plane_res.mi->funcs->set_cursor_attributes(
|
||||||
|
pipe_ctx->plane_res.mi, attributes);
|
||||||
|
|
||||||
|
if (pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes != NULL)
|
||||||
|
pipe_ctx->plane_res.xfm->funcs->set_cursor_attributes(
|
||||||
|
pipe_ctx->plane_res.xfm, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -231,6 +241,8 @@ bool dc_stream_set_cursor_position(
|
|||||||
for (i = 0; i < MAX_PIPES; i++) {
|
for (i = 0; i < MAX_PIPES; i++) {
|
||||||
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
|
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
|
||||||
struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
|
struct input_pixel_processor *ipp = pipe_ctx->plane_res.ipp;
|
||||||
|
struct mem_input *mi = pipe_ctx->plane_res.mi;
|
||||||
|
struct transform *xfm = pipe_ctx->plane_res.xfm;
|
||||||
struct dc_cursor_position pos_cpy = *position;
|
struct dc_cursor_position pos_cpy = *position;
|
||||||
struct dc_cursor_mi_param param = {
|
struct dc_cursor_mi_param param = {
|
||||||
.pixel_clk_khz = stream->timing.pix_clk_khz,
|
.pixel_clk_khz = stream->timing.pix_clk_khz,
|
||||||
@ -241,7 +253,9 @@ bool dc_stream_set_cursor_position(
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (pipe_ctx->stream != stream ||
|
if (pipe_ctx->stream != stream ||
|
||||||
!pipe_ctx->plane_res.ipp || !pipe_ctx->plane_state)
|
!pipe_ctx->plane_res.mi ||
|
||||||
|
!pipe_ctx->plane_state ||
|
||||||
|
!pipe_ctx->plane_res.xfm)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (pipe_ctx->plane_state->address.type
|
if (pipe_ctx->plane_state->address.type
|
||||||
@ -251,7 +265,15 @@ bool dc_stream_set_cursor_position(
|
|||||||
if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
|
if (pipe_ctx->top_pipe && pipe_ctx->plane_state != pipe_ctx->top_pipe->plane_state)
|
||||||
pos_cpy.enable = false;
|
pos_cpy.enable = false;
|
||||||
|
|
||||||
|
|
||||||
|
if (ipp->funcs->ipp_cursor_set_position != NULL)
|
||||||
ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m);
|
ipp->funcs->ipp_cursor_set_position(ipp, &pos_cpy, ¶m);
|
||||||
|
|
||||||
|
if (mi->funcs->set_cursor_attributes != NULL)
|
||||||
|
mi->funcs->set_cursor_position(mi, &pos_cpy, ¶m);
|
||||||
|
|
||||||
|
if (xfm->funcs->set_cursor_attributes != NULL)
|
||||||
|
xfm->funcs->set_cursor_position(xfm, &pos_cpy, ¶m, mi->curs_attr.width);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#define CTX \
|
#define CTX \
|
||||||
ipp_dce->base.ctx
|
ipp_dce->base.ctx
|
||||||
|
|
||||||
|
|
||||||
static void dce_ipp_cursor_set_position(
|
static void dce_ipp_cursor_set_position(
|
||||||
struct input_pixel_processor *ipp,
|
struct input_pixel_processor *ipp,
|
||||||
const struct dc_cursor_position *position,
|
const struct dc_cursor_position *position,
|
||||||
@ -133,6 +134,7 @@ static void dce_ipp_cursor_set_attributes(
|
|||||||
REG_UPDATE(CUR_UPDATE, CURSOR_UPDATE_LOCK, false);
|
REG_UPDATE(CUR_UPDATE, CURSOR_UPDATE_LOCK, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void dce_ipp_program_prescale(
|
static void dce_ipp_program_prescale(
|
||||||
struct input_pixel_processor *ipp,
|
struct input_pixel_processor *ipp,
|
||||||
struct ipp_prescale_params *params)
|
struct ipp_prescale_params *params)
|
||||||
|
@ -372,6 +372,55 @@ void ippn10_cnv_setup (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dcn10_set_cursor_attributes(
|
||||||
|
struct transform *xfm_base,
|
||||||
|
const struct dc_cursor_attributes *attr)
|
||||||
|
{
|
||||||
|
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
|
||||||
|
enum dc_cursor_color_format color_format = attr->color_format;
|
||||||
|
|
||||||
|
REG_UPDATE_2(CURSOR0_CONTROL,
|
||||||
|
CUR0_MODE, color_format,
|
||||||
|
CUR0_EXPANSION_MODE, 0);
|
||||||
|
|
||||||
|
if (color_format == CURSOR_MODE_MONO) {
|
||||||
|
/* todo: clarify what to program these to */
|
||||||
|
REG_UPDATE(CURSOR0_COLOR0,
|
||||||
|
CUR0_COLOR0, 0x00000000);
|
||||||
|
REG_UPDATE(CURSOR0_COLOR1,
|
||||||
|
CUR0_COLOR1, 0xFFFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: Fixed vs float */
|
||||||
|
|
||||||
|
REG_UPDATE_3(FORMAT_CONTROL,
|
||||||
|
CNVC_BYPASS, 0,
|
||||||
|
FORMAT_CONTROL__ALPHA_EN, 1,
|
||||||
|
FORMAT_EXPANSION_MODE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void dcn10_set_cursor_position(
|
||||||
|
struct transform *xfm_base,
|
||||||
|
const struct dc_cursor_position *pos,
|
||||||
|
const struct dc_cursor_mi_param *param,
|
||||||
|
uint32_t width)
|
||||||
|
{
|
||||||
|
struct dcn10_dpp *xfm = TO_DCN10_DPP(xfm_base);
|
||||||
|
int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
|
||||||
|
uint32_t cur_en = pos->enable ? 1 : 0;
|
||||||
|
|
||||||
|
if (src_x_offset >= (int)param->viewport_width)
|
||||||
|
cur_en = 0; /* not visible beyond right edge*/
|
||||||
|
|
||||||
|
if (src_x_offset + (int)width < 0)
|
||||||
|
cur_en = 0; /* not visible beyond left edge*/
|
||||||
|
|
||||||
|
REG_UPDATE(CURSOR0_CONTROL,
|
||||||
|
CUR0_ENABLE, cur_en);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static const struct transform_funcs dcn10_dpp_funcs = {
|
static const struct transform_funcs dcn10_dpp_funcs = {
|
||||||
.transform_reset = dpp_reset,
|
.transform_reset = dpp_reset,
|
||||||
.transform_set_scaler = dcn10_dpp_dscl_set_scaler_manual_scale,
|
.transform_set_scaler = dcn10_dpp_dscl_set_scaler_manual_scale,
|
||||||
@ -391,6 +440,8 @@ static const struct transform_funcs dcn10_dpp_funcs = {
|
|||||||
.ipp_program_degamma_pwl = ippn10_set_degamma_pwl,
|
.ipp_program_degamma_pwl = ippn10_set_degamma_pwl,
|
||||||
.ipp_setup = ippn10_cnv_setup,
|
.ipp_setup = ippn10_cnv_setup,
|
||||||
.ipp_full_bypass = ippn10_full_bypass,
|
.ipp_full_bypass = ippn10_full_bypass,
|
||||||
|
.set_cursor_attributes = dcn10_set_cursor_attributes,
|
||||||
|
.set_cursor_position = dcn10_set_cursor_position,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,7 +112,10 @@
|
|||||||
SRI(CM_DGAM_CONTROL, CM, id), \
|
SRI(CM_DGAM_CONTROL, CM, id), \
|
||||||
SRI(FORMAT_CONTROL, CNVC_CFG, id), \
|
SRI(FORMAT_CONTROL, CNVC_CFG, id), \
|
||||||
SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \
|
SRI(CNVC_SURFACE_PIXEL_FORMAT, CNVC_CFG, id), \
|
||||||
SRI(CURSOR0_CONTROL, CNVC_CUR, id)
|
SRI(CURSOR0_CONTROL, CNVC_CUR, id), \
|
||||||
|
SRI(CURSOR0_CONTROL, CNVC_CUR, id), \
|
||||||
|
SRI(CURSOR0_COLOR0, CNVC_CUR, id), \
|
||||||
|
SRI(CURSOR0_COLOR1, CNVC_CUR, id)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -302,7 +305,9 @@
|
|||||||
TF_SF(CNVC_CFG0_CNVC_SURFACE_PIXEL_FORMAT, CNVC_SURFACE_PIXEL_FORMAT, mask_sh), \
|
TF_SF(CNVC_CFG0_CNVC_SURFACE_PIXEL_FORMAT, CNVC_SURFACE_PIXEL_FORMAT, mask_sh), \
|
||||||
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_MODE, mask_sh), \
|
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_MODE, mask_sh), \
|
||||||
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_EXPANSION_MODE, mask_sh), \
|
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_EXPANSION_MODE, mask_sh), \
|
||||||
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh)
|
TF_SF(CNVC_CUR0_CURSOR0_CONTROL, CUR0_ENABLE, mask_sh), \
|
||||||
|
TF_SF(CNVC_CUR0_CURSOR0_COLOR0, CUR0_COLOR0, mask_sh), \
|
||||||
|
TF_SF(CNVC_CUR0_CURSOR0_COLOR1, CUR0_COLOR1, mask_sh)
|
||||||
|
|
||||||
#define TF_REG_LIST_SH_MASK_DCN10(mask_sh)\
|
#define TF_REG_LIST_SH_MASK_DCN10(mask_sh)\
|
||||||
TF_REG_LIST_SH_MASK_DCN(mask_sh),\
|
TF_REG_LIST_SH_MASK_DCN(mask_sh),\
|
||||||
@ -989,7 +994,9 @@
|
|||||||
type CUR0_EXPANSION_MODE; \
|
type CUR0_EXPANSION_MODE; \
|
||||||
type CUR0_ENABLE; \
|
type CUR0_ENABLE; \
|
||||||
type CM_BYPASS; \
|
type CM_BYPASS; \
|
||||||
type FORMAT_CONTROL__ALPHA_EN
|
type FORMAT_CONTROL__ALPHA_EN; \
|
||||||
|
type CUR0_COLOR0; \
|
||||||
|
type CUR0_COLOR1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -1237,6 +1244,8 @@ struct dcn_dpp_registers {
|
|||||||
uint32_t CNVC_SURFACE_PIXEL_FORMAT;
|
uint32_t CNVC_SURFACE_PIXEL_FORMAT;
|
||||||
uint32_t CURSOR_CONTROL;
|
uint32_t CURSOR_CONTROL;
|
||||||
uint32_t CURSOR0_CONTROL;
|
uint32_t CURSOR0_CONTROL;
|
||||||
|
uint32_t CURSOR0_COLOR0;
|
||||||
|
uint32_t CURSOR0_COLOR1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dcn10_dpp {
|
struct dcn10_dpp {
|
||||||
|
@ -37,188 +37,6 @@
|
|||||||
#define CTX \
|
#define CTX \
|
||||||
ippn10->base.ctx
|
ippn10->base.ctx
|
||||||
|
|
||||||
static bool ippn10_cursor_program_control(
|
|
||||||
struct dcn10_ipp *ippn10,
|
|
||||||
bool pixel_data_invert,
|
|
||||||
enum dc_cursor_color_format color_format)
|
|
||||||
{
|
|
||||||
if (REG(CURSOR_SETTINS))
|
|
||||||
REG_SET_2(CURSOR_SETTINS, 0,
|
|
||||||
/* no shift of the cursor HDL schedule */
|
|
||||||
CURSOR0_DST_Y_OFFSET, 0,
|
|
||||||
/* used to shift the cursor chunk request deadline */
|
|
||||||
CURSOR0_CHUNK_HDL_ADJUST, 3);
|
|
||||||
else
|
|
||||||
REG_SET_2(CURSOR_SETTINGS, 0,
|
|
||||||
/* no shift of the cursor HDL schedule */
|
|
||||||
CURSOR0_DST_Y_OFFSET, 0,
|
|
||||||
/* used to shift the cursor chunk request deadline */
|
|
||||||
CURSOR0_CHUNK_HDL_ADJUST, 3);
|
|
||||||
|
|
||||||
REG_UPDATE_2(CURSOR0_CONTROL,
|
|
||||||
CUR0_MODE, color_format,
|
|
||||||
CUR0_EXPANSION_MODE, 0);
|
|
||||||
|
|
||||||
if (color_format == CURSOR_MODE_MONO) {
|
|
||||||
/* todo: clarify what to program these to */
|
|
||||||
REG_UPDATE(CURSOR0_COLOR0,
|
|
||||||
CUR0_COLOR0, 0x00000000);
|
|
||||||
REG_UPDATE(CURSOR0_COLOR1,
|
|
||||||
CUR0_COLOR1, 0xFFFFFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Fixed vs float */
|
|
||||||
|
|
||||||
REG_UPDATE_3(FORMAT_CONTROL,
|
|
||||||
CNVC_BYPASS, 0,
|
|
||||||
ALPHA_EN, 1,
|
|
||||||
FORMAT_EXPANSION_MODE, 0);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum cursor_pitch {
|
|
||||||
CURSOR_PITCH_64_PIXELS = 0,
|
|
||||||
CURSOR_PITCH_128_PIXELS,
|
|
||||||
CURSOR_PITCH_256_PIXELS
|
|
||||||
};
|
|
||||||
|
|
||||||
enum cursor_lines_per_chunk {
|
|
||||||
CURSOR_LINE_PER_CHUNK_2 = 1,
|
|
||||||
CURSOR_LINE_PER_CHUNK_4,
|
|
||||||
CURSOR_LINE_PER_CHUNK_8,
|
|
||||||
CURSOR_LINE_PER_CHUNK_16
|
|
||||||
};
|
|
||||||
|
|
||||||
static enum cursor_pitch ippn10_get_cursor_pitch(
|
|
||||||
unsigned int pitch)
|
|
||||||
{
|
|
||||||
enum cursor_pitch hw_pitch;
|
|
||||||
|
|
||||||
switch (pitch) {
|
|
||||||
case 64:
|
|
||||||
hw_pitch = CURSOR_PITCH_64_PIXELS;
|
|
||||||
break;
|
|
||||||
case 128:
|
|
||||||
hw_pitch = CURSOR_PITCH_128_PIXELS;
|
|
||||||
break;
|
|
||||||
case 256:
|
|
||||||
hw_pitch = CURSOR_PITCH_256_PIXELS;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DC_ERR("Invalid cursor pitch of %d. "
|
|
||||||
"Only 64/128/256 is supported on DCN.\n", pitch);
|
|
||||||
hw_pitch = CURSOR_PITCH_64_PIXELS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return hw_pitch;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk(
|
|
||||||
unsigned int cur_width,
|
|
||||||
enum dc_cursor_color_format format)
|
|
||||||
{
|
|
||||||
enum cursor_lines_per_chunk line_per_chunk;
|
|
||||||
|
|
||||||
if (format == CURSOR_MODE_MONO)
|
|
||||||
/* impl B. expansion in CUR Buffer reader */
|
|
||||||
line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
|
|
||||||
else if (cur_width <= 32)
|
|
||||||
line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
|
|
||||||
else if (cur_width <= 64)
|
|
||||||
line_per_chunk = CURSOR_LINE_PER_CHUNK_8;
|
|
||||||
else if (cur_width <= 128)
|
|
||||||
line_per_chunk = CURSOR_LINE_PER_CHUNK_4;
|
|
||||||
else
|
|
||||||
line_per_chunk = CURSOR_LINE_PER_CHUNK_2;
|
|
||||||
|
|
||||||
return line_per_chunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ippn10_cursor_set_attributes(
|
|
||||||
struct input_pixel_processor *ipp,
|
|
||||||
const struct dc_cursor_attributes *attr)
|
|
||||||
{
|
|
||||||
struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp);
|
|
||||||
enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch);
|
|
||||||
enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk(
|
|
||||||
attr->width, attr->color_format);
|
|
||||||
|
|
||||||
ippn10->curs_attr = *attr;
|
|
||||||
|
|
||||||
REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH,
|
|
||||||
CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part);
|
|
||||||
REG_UPDATE(CURSOR_SURFACE_ADDRESS,
|
|
||||||
CURSOR_SURFACE_ADDRESS, attr->address.low_part);
|
|
||||||
|
|
||||||
REG_UPDATE_2(CURSOR_SIZE,
|
|
||||||
CURSOR_WIDTH, attr->width,
|
|
||||||
CURSOR_HEIGHT, attr->height);
|
|
||||||
REG_UPDATE_3(CURSOR_CONTROL,
|
|
||||||
CURSOR_MODE, attr->color_format,
|
|
||||||
CURSOR_PITCH, hw_pitch,
|
|
||||||
CURSOR_LINES_PER_CHUNK, lpc);
|
|
||||||
ippn10_cursor_program_control(ippn10,
|
|
||||||
attr->attribute_flags.bits.INVERT_PIXEL_DATA,
|
|
||||||
attr->color_format);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ippn10_cursor_set_position(
|
|
||||||
struct input_pixel_processor *ipp,
|
|
||||||
const struct dc_cursor_position *pos,
|
|
||||||
const struct dc_cursor_mi_param *param)
|
|
||||||
{
|
|
||||||
struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp);
|
|
||||||
int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
|
|
||||||
uint32_t cur_en = pos->enable ? 1 : 0;
|
|
||||||
uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Guard aganst cursor_set_position() from being called with invalid
|
|
||||||
* attributes
|
|
||||||
*
|
|
||||||
* TODO: Look at combining cursor_set_position() and
|
|
||||||
* cursor_set_attributes() into cursor_update()
|
|
||||||
*/
|
|
||||||
if (ippn10->curs_attr.address.quad_part == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dst_x_offset *= param->ref_clk_khz;
|
|
||||||
dst_x_offset /= param->pixel_clk_khz;
|
|
||||||
|
|
||||||
ASSERT(param->h_scale_ratio.value);
|
|
||||||
|
|
||||||
if (param->h_scale_ratio.value)
|
|
||||||
dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div(
|
|
||||||
dal_fixed31_32_from_int(dst_x_offset),
|
|
||||||
param->h_scale_ratio));
|
|
||||||
|
|
||||||
if (src_x_offset >= (int)param->viewport_width)
|
|
||||||
cur_en = 0; /* not visible beyond right edge*/
|
|
||||||
|
|
||||||
if (src_x_offset + (int)ippn10->curs_attr.width < 0)
|
|
||||||
cur_en = 0; /* not visible beyond left edge*/
|
|
||||||
|
|
||||||
if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
|
|
||||||
ippn10_cursor_set_attributes(ipp, &ippn10->curs_attr);
|
|
||||||
REG_UPDATE(CURSOR_CONTROL,
|
|
||||||
CURSOR_ENABLE, cur_en);
|
|
||||||
REG_UPDATE(CURSOR0_CONTROL,
|
|
||||||
CUR0_ENABLE, cur_en);
|
|
||||||
|
|
||||||
REG_SET_2(CURSOR_POSITION, 0,
|
|
||||||
CURSOR_X_POSITION, pos->x,
|
|
||||||
CURSOR_Y_POSITION, pos->y);
|
|
||||||
|
|
||||||
REG_SET_2(CURSOR_HOT_SPOT, 0,
|
|
||||||
CURSOR_HOT_SPOT_X, pos->x_hotspot,
|
|
||||||
CURSOR_HOT_SPOT_Y, pos->y_hotspot);
|
|
||||||
|
|
||||||
REG_SET(CURSOR_DST_OFFSET, 0,
|
|
||||||
CURSOR_DST_X_OFFSET, dst_x_offset);
|
|
||||||
/* TODO Handle surface pixel formats other than 4:4:4 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
/* Constructor, Destructor */
|
/* Constructor, Destructor */
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
@ -230,13 +48,6 @@ static void dcn10_ipp_destroy(struct input_pixel_processor **ipp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct ipp_funcs dcn10_ipp_funcs = {
|
static const struct ipp_funcs dcn10_ipp_funcs = {
|
||||||
.ipp_cursor_set_attributes = ippn10_cursor_set_attributes,
|
|
||||||
.ipp_cursor_set_position = ippn10_cursor_set_position,
|
|
||||||
.ipp_set_degamma = NULL,
|
|
||||||
.ipp_program_input_lut = NULL,
|
|
||||||
.ipp_full_bypass = NULL,
|
|
||||||
.ipp_setup = NULL,
|
|
||||||
.ipp_program_degamma_pwl = NULL,
|
|
||||||
.ipp_destroy = dcn10_ipp_destroy
|
.ipp_destroy = dcn10_ipp_destroy
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -766,6 +766,167 @@ void dcn10_mem_input_read_state(struct dcn10_mem_input *mi,
|
|||||||
QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm);
|
QoS_LEVEL_HIGH_WM, &s->qos_level_high_wm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum cursor_pitch {
|
||||||
|
CURSOR_PITCH_64_PIXELS = 0,
|
||||||
|
CURSOR_PITCH_128_PIXELS,
|
||||||
|
CURSOR_PITCH_256_PIXELS
|
||||||
|
};
|
||||||
|
|
||||||
|
enum cursor_lines_per_chunk {
|
||||||
|
CURSOR_LINE_PER_CHUNK_2 = 1,
|
||||||
|
CURSOR_LINE_PER_CHUNK_4,
|
||||||
|
CURSOR_LINE_PER_CHUNK_8,
|
||||||
|
CURSOR_LINE_PER_CHUNK_16
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool ippn10_cursor_program_control(
|
||||||
|
struct dcn10_mem_input *mi,
|
||||||
|
bool pixel_data_invert,
|
||||||
|
enum dc_cursor_color_format color_format)
|
||||||
|
{
|
||||||
|
if (REG(CURSOR_SETTINS))
|
||||||
|
REG_SET_2(CURSOR_SETTINS, 0,
|
||||||
|
/* no shift of the cursor HDL schedule */
|
||||||
|
CURSOR0_DST_Y_OFFSET, 0,
|
||||||
|
/* used to shift the cursor chunk request deadline */
|
||||||
|
CURSOR0_CHUNK_HDL_ADJUST, 3);
|
||||||
|
else
|
||||||
|
REG_SET_2(CURSOR_SETTINGS, 0,
|
||||||
|
/* no shift of the cursor HDL schedule */
|
||||||
|
CURSOR0_DST_Y_OFFSET, 0,
|
||||||
|
/* used to shift the cursor chunk request deadline */
|
||||||
|
CURSOR0_CHUNK_HDL_ADJUST, 3);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum cursor_pitch ippn10_get_cursor_pitch(
|
||||||
|
unsigned int pitch)
|
||||||
|
{
|
||||||
|
enum cursor_pitch hw_pitch;
|
||||||
|
|
||||||
|
switch (pitch) {
|
||||||
|
case 64:
|
||||||
|
hw_pitch = CURSOR_PITCH_64_PIXELS;
|
||||||
|
break;
|
||||||
|
case 128:
|
||||||
|
hw_pitch = CURSOR_PITCH_128_PIXELS;
|
||||||
|
break;
|
||||||
|
case 256:
|
||||||
|
hw_pitch = CURSOR_PITCH_256_PIXELS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DC_ERR("Invalid cursor pitch of %d. "
|
||||||
|
"Only 64/128/256 is supported on DCN.\n", pitch);
|
||||||
|
hw_pitch = CURSOR_PITCH_64_PIXELS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return hw_pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk(
|
||||||
|
unsigned int cur_width,
|
||||||
|
enum dc_cursor_color_format format)
|
||||||
|
{
|
||||||
|
enum cursor_lines_per_chunk line_per_chunk;
|
||||||
|
|
||||||
|
if (format == CURSOR_MODE_MONO)
|
||||||
|
/* impl B. expansion in CUR Buffer reader */
|
||||||
|
line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
|
||||||
|
else if (cur_width <= 32)
|
||||||
|
line_per_chunk = CURSOR_LINE_PER_CHUNK_16;
|
||||||
|
else if (cur_width <= 64)
|
||||||
|
line_per_chunk = CURSOR_LINE_PER_CHUNK_8;
|
||||||
|
else if (cur_width <= 128)
|
||||||
|
line_per_chunk = CURSOR_LINE_PER_CHUNK_4;
|
||||||
|
else
|
||||||
|
line_per_chunk = CURSOR_LINE_PER_CHUNK_2;
|
||||||
|
|
||||||
|
return line_per_chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ippn10_cursor_set_attributes(
|
||||||
|
struct mem_input *mem_input,
|
||||||
|
const struct dc_cursor_attributes *attr)
|
||||||
|
{
|
||||||
|
struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
|
||||||
|
enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch);
|
||||||
|
enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk(
|
||||||
|
attr->width, attr->color_format);
|
||||||
|
|
||||||
|
mem_input->curs_attr = *attr;
|
||||||
|
|
||||||
|
REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH,
|
||||||
|
CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part);
|
||||||
|
REG_UPDATE(CURSOR_SURFACE_ADDRESS,
|
||||||
|
CURSOR_SURFACE_ADDRESS, attr->address.low_part);
|
||||||
|
|
||||||
|
REG_UPDATE_2(CURSOR_SIZE,
|
||||||
|
CURSOR_WIDTH, attr->width,
|
||||||
|
CURSOR_HEIGHT, attr->height);
|
||||||
|
REG_UPDATE_3(CURSOR_CONTROL,
|
||||||
|
CURSOR_MODE, attr->color_format,
|
||||||
|
CURSOR_PITCH, hw_pitch,
|
||||||
|
CURSOR_LINES_PER_CHUNK, lpc);
|
||||||
|
ippn10_cursor_program_control(mi,
|
||||||
|
attr->attribute_flags.bits.INVERT_PIXEL_DATA,
|
||||||
|
attr->color_format);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ippn10_cursor_set_position(
|
||||||
|
struct mem_input *mem_input,
|
||||||
|
const struct dc_cursor_position *pos,
|
||||||
|
const struct dc_cursor_mi_param *param)
|
||||||
|
{
|
||||||
|
struct dcn10_mem_input *mi = TO_DCN10_MEM_INPUT(mem_input);
|
||||||
|
int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start;
|
||||||
|
uint32_t cur_en = pos->enable ? 1 : 0;
|
||||||
|
uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Guard aganst cursor_set_position() from being called with invalid
|
||||||
|
* attributes
|
||||||
|
*
|
||||||
|
* TODO: Look at combining cursor_set_position() and
|
||||||
|
* cursor_set_attributes() into cursor_update()
|
||||||
|
*/
|
||||||
|
if (mem_input->curs_attr.address.quad_part == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
dst_x_offset *= param->ref_clk_khz;
|
||||||
|
dst_x_offset /= param->pixel_clk_khz;
|
||||||
|
|
||||||
|
ASSERT(param->h_scale_ratio.value);
|
||||||
|
|
||||||
|
if (param->h_scale_ratio.value)
|
||||||
|
dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div(
|
||||||
|
dal_fixed31_32_from_int(dst_x_offset),
|
||||||
|
param->h_scale_ratio));
|
||||||
|
|
||||||
|
if (src_x_offset >= (int)param->viewport_width)
|
||||||
|
cur_en = 0; /* not visible beyond right edge*/
|
||||||
|
|
||||||
|
if (src_x_offset + (int)mem_input->curs_attr.width < 0)
|
||||||
|
cur_en = 0; /* not visible beyond left edge*/
|
||||||
|
|
||||||
|
if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0)
|
||||||
|
ippn10_cursor_set_attributes(mem_input, &mem_input->curs_attr);
|
||||||
|
REG_UPDATE(CURSOR_CONTROL,
|
||||||
|
CURSOR_ENABLE, cur_en);
|
||||||
|
|
||||||
|
REG_SET_2(CURSOR_POSITION, 0,
|
||||||
|
CURSOR_X_POSITION, pos->x,
|
||||||
|
CURSOR_Y_POSITION, pos->y);
|
||||||
|
|
||||||
|
REG_SET_2(CURSOR_HOT_SPOT, 0,
|
||||||
|
CURSOR_HOT_SPOT_X, pos->x_hotspot,
|
||||||
|
CURSOR_HOT_SPOT_Y, pos->y_hotspot);
|
||||||
|
|
||||||
|
REG_SET(CURSOR_DST_OFFSET, 0,
|
||||||
|
CURSOR_DST_X_OFFSET, dst_x_offset);
|
||||||
|
/* TODO Handle surface pixel formats other than 4:4:4 */
|
||||||
|
}
|
||||||
|
|
||||||
static struct mem_input_funcs dcn10_mem_input_funcs = {
|
static struct mem_input_funcs dcn10_mem_input_funcs = {
|
||||||
.mem_input_program_display_marks = min10_program_display_marks,
|
.mem_input_program_display_marks = min10_program_display_marks,
|
||||||
.mem_input_program_surface_flip_and_addr =
|
.mem_input_program_surface_flip_and_addr =
|
||||||
@ -780,6 +941,8 @@ static struct mem_input_funcs dcn10_mem_input_funcs = {
|
|||||||
.dcc_control = min10_dcc_control,
|
.dcc_control = min10_dcc_control,
|
||||||
.mem_program_viewport = min_set_viewport,
|
.mem_program_viewport = min_set_viewport,
|
||||||
.set_hubp_blank_en = min10_set_hubp_blank_en,
|
.set_hubp_blank_en = min10_set_hubp_blank_en,
|
||||||
|
.set_cursor_attributes = ippn10_cursor_set_attributes,
|
||||||
|
.set_cursor_position = ippn10_cursor_set_position,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*****************************************/
|
/*****************************************/
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
#define TO_DCN10_MEM_INPUT(mi)\
|
#define TO_DCN10_MEM_INPUT(mi)\
|
||||||
container_of(mi, struct dcn10_mem_input, base)
|
container_of(mi, struct dcn10_mem_input, base)
|
||||||
|
|
||||||
|
|
||||||
#define MI_REG_LIST_DCN(id)\
|
#define MI_REG_LIST_DCN(id)\
|
||||||
SRI(DCHUBP_CNTL, HUBP, id),\
|
SRI(DCHUBP_CNTL, HUBP, id),\
|
||||||
SRI(HUBPREQ_DEBUG_DB, HUBP, id),\
|
SRI(HUBPREQ_DEBUG_DB, HUBP, id),\
|
||||||
@ -118,7 +117,15 @@
|
|||||||
SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, HUBPREQ, id),\
|
SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_MSB, HUBPREQ, id),\
|
||||||
SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, HUBPREQ, id),\
|
SRI(DCN_VM_SYSTEM_APERTURE_HIGH_ADDR_LSB, HUBPREQ, id),\
|
||||||
SR(DCHUBBUB_SDPIF_FB_BASE),\
|
SR(DCHUBBUB_SDPIF_FB_BASE),\
|
||||||
SR(DCHUBBUB_SDPIF_FB_OFFSET)
|
SR(DCHUBBUB_SDPIF_FB_OFFSET),\
|
||||||
|
SRI(CURSOR_SETTINS, HUBPREQ, id), \
|
||||||
|
SRI(CURSOR_SURFACE_ADDRESS_HIGH, CURSOR, id), \
|
||||||
|
SRI(CURSOR_SURFACE_ADDRESS, CURSOR, id), \
|
||||||
|
SRI(CURSOR_SIZE, CURSOR, id), \
|
||||||
|
SRI(CURSOR_CONTROL, CURSOR, id), \
|
||||||
|
SRI(CURSOR_POSITION, CURSOR, id), \
|
||||||
|
SRI(CURSOR_HOT_SPOT, CURSOR, id), \
|
||||||
|
SRI(CURSOR_DST_OFFSET, CURSOR, id)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -217,6 +224,15 @@ struct dcn_mi_registers {
|
|||||||
uint32_t DCN_VM_AGP_BASE;
|
uint32_t DCN_VM_AGP_BASE;
|
||||||
uint32_t DCN_VM_AGP_BOT;
|
uint32_t DCN_VM_AGP_BOT;
|
||||||
uint32_t DCN_VM_AGP_TOP;
|
uint32_t DCN_VM_AGP_TOP;
|
||||||
|
uint32_t CURSOR_SETTINS;
|
||||||
|
uint32_t CURSOR_SETTINGS;
|
||||||
|
uint32_t CURSOR_SURFACE_ADDRESS_HIGH;
|
||||||
|
uint32_t CURSOR_SURFACE_ADDRESS;
|
||||||
|
uint32_t CURSOR_SIZE;
|
||||||
|
uint32_t CURSOR_CONTROL;
|
||||||
|
uint32_t CURSOR_POSITION;
|
||||||
|
uint32_t CURSOR_HOT_SPOT;
|
||||||
|
uint32_t CURSOR_DST_OFFSET;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MI_SF(reg_name, field_name, post_fix)\
|
#define MI_SF(reg_name, field_name, post_fix)\
|
||||||
@ -362,7 +378,23 @@ struct dcn_mi_registers {
|
|||||||
MI_SF(DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, mask_sh),\
|
MI_SF(DCHUBBUB_SDPIF_FB_OFFSET, SDPIF_FB_OFFSET, mask_sh),\
|
||||||
MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, mask_sh),\
|
MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_SYSTEM, mask_sh),\
|
||||||
MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mask_sh),\
|
MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_MSB, mask_sh),\
|
||||||
MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mask_sh)
|
MI_SF(HUBPREQ0_DCN_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR_LSB, mask_sh),\
|
||||||
|
MI_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_DST_Y_OFFSET, mask_sh), \
|
||||||
|
MI_SF(HUBPREQ0_CURSOR_SETTINS, CURSOR0_CHUNK_HDL_ADJUST, mask_sh), \
|
||||||
|
MI_SF(CURSOR0_CURSOR_SURFACE_ADDRESS_HIGH, CURSOR_SURFACE_ADDRESS_HIGH, mask_sh), \
|
||||||
|
MI_SF(CURSOR0_CURSOR_SURFACE_ADDRESS, CURSOR_SURFACE_ADDRESS, mask_sh), \
|
||||||
|
MI_SF(CURSOR0_CURSOR_SIZE, CURSOR_WIDTH, mask_sh), \
|
||||||
|
MI_SF(CURSOR0_CURSOR_SIZE, CURSOR_HEIGHT, mask_sh), \
|
||||||
|
MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_MODE, mask_sh), \
|
||||||
|
MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_2X_MAGNIFY, mask_sh), \
|
||||||
|
MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_PITCH, mask_sh), \
|
||||||
|
MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_LINES_PER_CHUNK, mask_sh), \
|
||||||
|
MI_SF(CURSOR0_CURSOR_CONTROL, CURSOR_ENABLE, mask_sh), \
|
||||||
|
MI_SF(CURSOR0_CURSOR_POSITION, CURSOR_X_POSITION, mask_sh), \
|
||||||
|
MI_SF(CURSOR0_CURSOR_POSITION, CURSOR_Y_POSITION, mask_sh), \
|
||||||
|
MI_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_X, mask_sh), \
|
||||||
|
MI_SF(CURSOR0_CURSOR_HOT_SPOT, CURSOR_HOT_SPOT_Y, mask_sh), \
|
||||||
|
MI_SF(CURSOR0_CURSOR_DST_OFFSET, CURSOR_DST_X_OFFSET, mask_sh)
|
||||||
|
|
||||||
#define DCN_MI_REG_FIELD_LIST(type) \
|
#define DCN_MI_REG_FIELD_LIST(type) \
|
||||||
type HUBP_BLANK_EN;\
|
type HUBP_BLANK_EN;\
|
||||||
@ -523,7 +555,24 @@ struct dcn_mi_registers {
|
|||||||
type PHYSICAL_PAGE_ADDR_LO32;\
|
type PHYSICAL_PAGE_ADDR_LO32;\
|
||||||
type PHYSICAL_PAGE_NUMBER_MSB;\
|
type PHYSICAL_PAGE_NUMBER_MSB;\
|
||||||
type PHYSICAL_PAGE_NUMBER_LSB;\
|
type PHYSICAL_PAGE_NUMBER_LSB;\
|
||||||
type LOGICAL_ADDR
|
type LOGICAL_ADDR;\
|
||||||
|
type CURSOR0_DST_Y_OFFSET; \
|
||||||
|
type CURSOR0_CHUNK_HDL_ADJUST; \
|
||||||
|
type CURSOR_SURFACE_ADDRESS_HIGH; \
|
||||||
|
type CURSOR_SURFACE_ADDRESS; \
|
||||||
|
type CURSOR_WIDTH; \
|
||||||
|
type CURSOR_HEIGHT; \
|
||||||
|
type CURSOR_MODE; \
|
||||||
|
type CURSOR_2X_MAGNIFY; \
|
||||||
|
type CURSOR_PITCH; \
|
||||||
|
type CURSOR_LINES_PER_CHUNK; \
|
||||||
|
type CURSOR_ENABLE; \
|
||||||
|
type CURSOR_X_POSITION; \
|
||||||
|
type CURSOR_Y_POSITION; \
|
||||||
|
type CURSOR_HOT_SPOT_X; \
|
||||||
|
type CURSOR_HOT_SPOT_Y; \
|
||||||
|
type CURSOR_DST_X_OFFSET; \
|
||||||
|
type OUTPUT_FP
|
||||||
|
|
||||||
struct dcn_mi_shift {
|
struct dcn_mi_shift {
|
||||||
DCN_MI_REG_FIELD_LIST(uint8_t);
|
DCN_MI_REG_FIELD_LIST(uint8_t);
|
||||||
|
@ -72,6 +72,7 @@ struct mem_input {
|
|||||||
int opp_id;
|
int opp_id;
|
||||||
int mpcc_id;
|
int mpcc_id;
|
||||||
struct stutter_modes stutter_mode;
|
struct stutter_modes stutter_mode;
|
||||||
|
struct dc_cursor_attributes curs_attr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vm_system_aperture_param {
|
struct vm_system_aperture_param {
|
||||||
@ -163,6 +164,15 @@ struct mem_input_funcs {
|
|||||||
void (*set_blank)(struct mem_input *mi, bool blank);
|
void (*set_blank)(struct mem_input *mi, bool blank);
|
||||||
void (*set_hubp_blank_en)(struct mem_input *mi, bool blank);
|
void (*set_hubp_blank_en)(struct mem_input *mi, bool blank);
|
||||||
|
|
||||||
|
void (*set_cursor_attributes)(
|
||||||
|
struct mem_input *mem_input,
|
||||||
|
const struct dc_cursor_attributes *attr);
|
||||||
|
|
||||||
|
void (*set_cursor_position)(
|
||||||
|
struct mem_input *mem_input,
|
||||||
|
const struct dc_cursor_position *pos,
|
||||||
|
const struct dc_cursor_mi_param *param);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -238,6 +238,17 @@ struct transform_funcs {
|
|||||||
|
|
||||||
void (*ipp_full_bypass)(struct transform *xfm_base);
|
void (*ipp_full_bypass)(struct transform *xfm_base);
|
||||||
|
|
||||||
|
void (*set_cursor_attributes)(
|
||||||
|
struct transform *xfm_base,
|
||||||
|
const struct dc_cursor_attributes *attr);
|
||||||
|
|
||||||
|
void (*set_cursor_position)(
|
||||||
|
struct transform *xfm_base,
|
||||||
|
const struct dc_cursor_position *pos,
|
||||||
|
const struct dc_cursor_mi_param *param,
|
||||||
|
uint32_t width
|
||||||
|
);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint16_t *get_filter_2tap_16p(void);
|
const uint16_t *get_filter_2tap_16p(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user