170ccab60SHarry Wentland /* 270ccab60SHarry Wentland * Copyright 2017 Advanced Micro Devices, Inc. 370ccab60SHarry Wentland * 470ccab60SHarry Wentland * Permission is hereby granted, free of charge, to any person obtaining a 570ccab60SHarry Wentland * copy of this software and associated documentation files (the "Software"), 670ccab60SHarry Wentland * to deal in the Software without restriction, including without limitation 770ccab60SHarry Wentland * the rights to use, copy, modify, merge, publish, distribute, sublicense, 870ccab60SHarry Wentland * and/or sell copies of the Software, and to permit persons to whom the 970ccab60SHarry Wentland * Software is furnished to do so, subject to the following conditions: 1070ccab60SHarry Wentland * 1170ccab60SHarry Wentland * The above copyright notice and this permission notice shall be included in 1270ccab60SHarry Wentland * all copies or substantial portions of the Software. 1370ccab60SHarry Wentland * 1470ccab60SHarry Wentland * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1570ccab60SHarry Wentland * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1670ccab60SHarry Wentland * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1770ccab60SHarry Wentland * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 1870ccab60SHarry Wentland * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1970ccab60SHarry Wentland * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2070ccab60SHarry Wentland * OTHER DEALINGS IN THE SOFTWARE. 2170ccab60SHarry Wentland * 2270ccab60SHarry Wentland * Authors: AMD 2370ccab60SHarry Wentland * 2470ccab60SHarry Wentland */ 2570ccab60SHarry Wentland 2670ccab60SHarry Wentland #include "dm_services.h" 2770ccab60SHarry Wentland #include "dcn10_ipp.h" 2870ccab60SHarry Wentland #include "reg_helper.h" 2970ccab60SHarry Wentland 3070ccab60SHarry Wentland #define REG(reg) \ 3170ccab60SHarry Wentland (ippn10->regs->reg) 3270ccab60SHarry Wentland 3370ccab60SHarry Wentland #undef FN 3470ccab60SHarry Wentland #define FN(reg_name, field_name) \ 3570ccab60SHarry Wentland ippn10->ipp_shift->field_name, ippn10->ipp_mask->field_name 3670ccab60SHarry Wentland 3770ccab60SHarry Wentland #define CTX \ 3870ccab60SHarry Wentland ippn10->base.ctx 3970ccab60SHarry Wentland 4070ccab60SHarry Wentland 4170ccab60SHarry Wentland struct dcn10_input_csc_matrix { 4270ccab60SHarry Wentland enum dc_color_space color_space; 4370ccab60SHarry Wentland uint32_t regval[12]; 4470ccab60SHarry Wentland }; 4570ccab60SHarry Wentland 4670ccab60SHarry Wentland static const struct dcn10_input_csc_matrix dcn10_input_csc_matrix[] = { 4770ccab60SHarry Wentland {COLOR_SPACE_SRGB, 4870ccab60SHarry Wentland {0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} }, 4970ccab60SHarry Wentland {COLOR_SPACE_SRGB_LIMITED, 5070ccab60SHarry Wentland {0x2000, 0, 0, 0, 0, 0x2000, 0, 0, 0, 0, 0x2000, 0} }, 5170ccab60SHarry Wentland {COLOR_SPACE_YCBCR601, 5270ccab60SHarry Wentland {0x2cdd, 0x2000, 0, 0xe991, 0xe926, 0x2000, 0xf4fd, 0x10ef, 5370ccab60SHarry Wentland 0, 0x2000, 0x38b4, 0xe3a6} }, 5470ccab60SHarry Wentland {COLOR_SPACE_YCBCR601_LIMITED, 5570ccab60SHarry Wentland {0x3353, 0x2568, 0, 0xe400, 0xe5dc, 0x2568, 0xf367, 0x1108, 5670ccab60SHarry Wentland 0, 0x2568, 0x40de, 0xdd3a} }, 5770ccab60SHarry Wentland {COLOR_SPACE_YCBCR709, 5870ccab60SHarry Wentland {0x3265, 0x2000, 0, 0xe6ce, 0xf105, 0x2000, 0xfa01, 0xa7d, 0, 5970ccab60SHarry Wentland 0x2000, 0x3b61, 0xe24f} }, 6070ccab60SHarry Wentland 6170ccab60SHarry Wentland {COLOR_SPACE_YCBCR709_LIMITED, 6270ccab60SHarry Wentland {0x39a6, 0x2568, 0, 0xe0d6, 0xeedd, 0x2568, 0xf925, 0x9a8, 0, 6370ccab60SHarry Wentland 0x2568, 0x43ee, 0xdbb2} } 6470ccab60SHarry Wentland }; 6570ccab60SHarry Wentland 6670ccab60SHarry Wentland enum dcn10_input_csc_select { 6770ccab60SHarry Wentland INPUT_CSC_SELECT_BYPASS = 0, 6870ccab60SHarry Wentland INPUT_CSC_SELECT_ICSC, 6970ccab60SHarry Wentland INPUT_CSC_SELECT_COMA 7070ccab60SHarry Wentland }; 7170ccab60SHarry Wentland 7270ccab60SHarry Wentland 7370ccab60SHarry Wentland 74a3ac9dadSDmytro Laktyushkin static bool ippn10_cursor_program_control( 7570ccab60SHarry Wentland struct dcn10_ipp *ippn10, 7670ccab60SHarry Wentland bool pixel_data_invert, 7770ccab60SHarry Wentland enum dc_cursor_color_format color_format) 7870ccab60SHarry Wentland { 7951666631SDmytro Laktyushkin if (REG(CURSOR_SETTINS)) 8070ccab60SHarry Wentland REG_SET_2(CURSOR_SETTINS, 0, 8170ccab60SHarry Wentland /* no shift of the cursor HDL schedule */ 8270ccab60SHarry Wentland CURSOR0_DST_Y_OFFSET, 0, 8370ccab60SHarry Wentland /* used to shift the cursor chunk request deadline */ 8470ccab60SHarry Wentland CURSOR0_CHUNK_HDL_ADJUST, 3); 8551666631SDmytro Laktyushkin else 8651666631SDmytro Laktyushkin REG_SET_2(CURSOR_SETTINGS, 0, 8751666631SDmytro Laktyushkin /* no shift of the cursor HDL schedule */ 8851666631SDmytro Laktyushkin CURSOR0_DST_Y_OFFSET, 0, 8951666631SDmytro Laktyushkin /* used to shift the cursor chunk request deadline */ 9051666631SDmytro Laktyushkin CURSOR0_CHUNK_HDL_ADJUST, 3); 9170ccab60SHarry Wentland 9270ccab60SHarry Wentland REG_UPDATE_2(CURSOR0_CONTROL, 9370ccab60SHarry Wentland CUR0_MODE, color_format, 9435ce37d6SDmytro Laktyushkin CUR0_EXPANSION_MODE, 0); 9570ccab60SHarry Wentland 9670ccab60SHarry Wentland if (color_format == CURSOR_MODE_MONO) { 9770ccab60SHarry Wentland /* todo: clarify what to program these to */ 9870ccab60SHarry Wentland REG_UPDATE(CURSOR0_COLOR0, 9970ccab60SHarry Wentland CUR0_COLOR0, 0x00000000); 10070ccab60SHarry Wentland REG_UPDATE(CURSOR0_COLOR1, 10170ccab60SHarry Wentland CUR0_COLOR1, 0xFFFFFFFF); 10270ccab60SHarry Wentland } 10370ccab60SHarry Wentland 10470ccab60SHarry Wentland /* TODO: Fixed vs float */ 10570ccab60SHarry Wentland 10670ccab60SHarry Wentland REG_UPDATE_3(FORMAT_CONTROL, 10770ccab60SHarry Wentland CNVC_BYPASS, 0, 10870ccab60SHarry Wentland ALPHA_EN, 1, 10970ccab60SHarry Wentland FORMAT_EXPANSION_MODE, 0); 11070ccab60SHarry Wentland 11170ccab60SHarry Wentland return true; 11270ccab60SHarry Wentland } 11370ccab60SHarry Wentland 11470ccab60SHarry Wentland enum cursor_pitch { 11570ccab60SHarry Wentland CURSOR_PITCH_64_PIXELS = 0, 11670ccab60SHarry Wentland CURSOR_PITCH_128_PIXELS, 11770ccab60SHarry Wentland CURSOR_PITCH_256_PIXELS 11870ccab60SHarry Wentland }; 11970ccab60SHarry Wentland 12070ccab60SHarry Wentland enum cursor_lines_per_chunk { 12170ccab60SHarry Wentland CURSOR_LINE_PER_CHUNK_2 = 1, 12270ccab60SHarry Wentland CURSOR_LINE_PER_CHUNK_4, 12370ccab60SHarry Wentland CURSOR_LINE_PER_CHUNK_8, 12470ccab60SHarry Wentland CURSOR_LINE_PER_CHUNK_16 12570ccab60SHarry Wentland }; 12670ccab60SHarry Wentland 127a3ac9dadSDmytro Laktyushkin static enum cursor_pitch ippn10_get_cursor_pitch( 12870ccab60SHarry Wentland unsigned int pitch) 12970ccab60SHarry Wentland { 13070ccab60SHarry Wentland enum cursor_pitch hw_pitch; 13170ccab60SHarry Wentland 13270ccab60SHarry Wentland switch (pitch) { 13370ccab60SHarry Wentland case 64: 13470ccab60SHarry Wentland hw_pitch = CURSOR_PITCH_64_PIXELS; 13570ccab60SHarry Wentland break; 13670ccab60SHarry Wentland case 128: 13770ccab60SHarry Wentland hw_pitch = CURSOR_PITCH_128_PIXELS; 13870ccab60SHarry Wentland break; 13970ccab60SHarry Wentland case 256: 14070ccab60SHarry Wentland hw_pitch = CURSOR_PITCH_256_PIXELS; 14170ccab60SHarry Wentland break; 14270ccab60SHarry Wentland default: 14370ccab60SHarry Wentland DC_ERR("Invalid cursor pitch of %d. " 14470ccab60SHarry Wentland "Only 64/128/256 is supported on DCN.\n", pitch); 14570ccab60SHarry Wentland hw_pitch = CURSOR_PITCH_64_PIXELS; 14670ccab60SHarry Wentland break; 14770ccab60SHarry Wentland } 14870ccab60SHarry Wentland return hw_pitch; 14970ccab60SHarry Wentland } 15070ccab60SHarry Wentland 151a3ac9dadSDmytro Laktyushkin static enum cursor_lines_per_chunk ippn10_get_lines_per_chunk( 15270ccab60SHarry Wentland unsigned int cur_width, 15370ccab60SHarry Wentland enum dc_cursor_color_format format) 15470ccab60SHarry Wentland { 15570ccab60SHarry Wentland enum cursor_lines_per_chunk line_per_chunk; 15670ccab60SHarry Wentland 15770ccab60SHarry Wentland if (format == CURSOR_MODE_MONO) 15870ccab60SHarry Wentland /* impl B. expansion in CUR Buffer reader */ 15970ccab60SHarry Wentland line_per_chunk = CURSOR_LINE_PER_CHUNK_16; 16070ccab60SHarry Wentland else if (cur_width <= 32) 16170ccab60SHarry Wentland line_per_chunk = CURSOR_LINE_PER_CHUNK_16; 16270ccab60SHarry Wentland else if (cur_width <= 64) 16370ccab60SHarry Wentland line_per_chunk = CURSOR_LINE_PER_CHUNK_8; 16470ccab60SHarry Wentland else if (cur_width <= 128) 16570ccab60SHarry Wentland line_per_chunk = CURSOR_LINE_PER_CHUNK_4; 16670ccab60SHarry Wentland else 16770ccab60SHarry Wentland line_per_chunk = CURSOR_LINE_PER_CHUNK_2; 16870ccab60SHarry Wentland 16970ccab60SHarry Wentland return line_per_chunk; 17070ccab60SHarry Wentland } 17170ccab60SHarry Wentland 172a3ac9dadSDmytro Laktyushkin static void ippn10_cursor_set_attributes( 17370ccab60SHarry Wentland struct input_pixel_processor *ipp, 17470ccab60SHarry Wentland const struct dc_cursor_attributes *attr) 17570ccab60SHarry Wentland { 17670ccab60SHarry Wentland struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); 177a3ac9dadSDmytro Laktyushkin enum cursor_pitch hw_pitch = ippn10_get_cursor_pitch(attr->pitch); 178a3ac9dadSDmytro Laktyushkin enum cursor_lines_per_chunk lpc = ippn10_get_lines_per_chunk( 17970ccab60SHarry Wentland attr->width, attr->color_format); 18070ccab60SHarry Wentland 18170ccab60SHarry Wentland ippn10->curs_attr = *attr; 18270ccab60SHarry Wentland 18370ccab60SHarry Wentland REG_UPDATE(CURSOR_SURFACE_ADDRESS_HIGH, 18470ccab60SHarry Wentland CURSOR_SURFACE_ADDRESS_HIGH, attr->address.high_part); 18570ccab60SHarry Wentland REG_UPDATE(CURSOR_SURFACE_ADDRESS, 18670ccab60SHarry Wentland CURSOR_SURFACE_ADDRESS, attr->address.low_part); 18770ccab60SHarry Wentland 18870ccab60SHarry Wentland REG_UPDATE_2(CURSOR_SIZE, 18970ccab60SHarry Wentland CURSOR_WIDTH, attr->width, 19070ccab60SHarry Wentland CURSOR_HEIGHT, attr->height); 19170ccab60SHarry Wentland 19270ccab60SHarry Wentland REG_UPDATE_3(CURSOR_CONTROL, 19370ccab60SHarry Wentland CURSOR_MODE, attr->color_format, 19470ccab60SHarry Wentland CURSOR_PITCH, hw_pitch, 19570ccab60SHarry Wentland CURSOR_LINES_PER_CHUNK, lpc); 19670ccab60SHarry Wentland 197a3ac9dadSDmytro Laktyushkin ippn10_cursor_program_control(ippn10, 19870ccab60SHarry Wentland attr->attribute_flags.bits.INVERT_PIXEL_DATA, 19970ccab60SHarry Wentland attr->color_format); 20070ccab60SHarry Wentland } 20170ccab60SHarry Wentland 202a3ac9dadSDmytro Laktyushkin static void ippn10_cursor_set_position( 20370ccab60SHarry Wentland struct input_pixel_processor *ipp, 20470ccab60SHarry Wentland const struct dc_cursor_position *pos, 20570ccab60SHarry Wentland const struct dc_cursor_mi_param *param) 20670ccab60SHarry Wentland { 20770ccab60SHarry Wentland struct dcn10_ipp *ippn10 = TO_DCN10_IPP(ipp); 20870ccab60SHarry Wentland int src_x_offset = pos->x - pos->x_hotspot - param->viewport_x_start; 20970ccab60SHarry Wentland uint32_t cur_en = pos->enable ? 1 : 0; 21070ccab60SHarry Wentland uint32_t dst_x_offset = (src_x_offset >= 0) ? src_x_offset : 0; 21170ccab60SHarry Wentland 212d3ec0562SLeo (Sunpeng) Li /* 213d3ec0562SLeo (Sunpeng) Li * Guard aganst cursor_set_position() from being called with invalid 214d3ec0562SLeo (Sunpeng) Li * attributes 215d3ec0562SLeo (Sunpeng) Li * 216d3ec0562SLeo (Sunpeng) Li * TODO: Look at combining cursor_set_position() and 217d3ec0562SLeo (Sunpeng) Li * cursor_set_attributes() into cursor_update() 218d3ec0562SLeo (Sunpeng) Li */ 219d3ec0562SLeo (Sunpeng) Li if (ippn10->curs_attr.address.quad_part == 0) 220d3ec0562SLeo (Sunpeng) Li return; 221d3ec0562SLeo (Sunpeng) Li 22270ccab60SHarry Wentland dst_x_offset *= param->ref_clk_khz; 22370ccab60SHarry Wentland dst_x_offset /= param->pixel_clk_khz; 22470ccab60SHarry Wentland 22570ccab60SHarry Wentland ASSERT(param->h_scale_ratio.value); 22670ccab60SHarry Wentland 22770ccab60SHarry Wentland if (param->h_scale_ratio.value) 22870ccab60SHarry Wentland dst_x_offset = dal_fixed31_32_floor(dal_fixed31_32_div( 22970ccab60SHarry Wentland dal_fixed31_32_from_int(dst_x_offset), 23070ccab60SHarry Wentland param->h_scale_ratio)); 23170ccab60SHarry Wentland 23270ccab60SHarry Wentland if (src_x_offset >= (int)param->viewport_width) 23370ccab60SHarry Wentland cur_en = 0; /* not visible beyond right edge*/ 23470ccab60SHarry Wentland 23570ccab60SHarry Wentland if (src_x_offset + (int)ippn10->curs_attr.width < 0) 23670ccab60SHarry Wentland cur_en = 0; /* not visible beyond left edge*/ 23770ccab60SHarry Wentland 23870ccab60SHarry Wentland if (cur_en && REG_READ(CURSOR_SURFACE_ADDRESS) == 0) 239a3ac9dadSDmytro Laktyushkin ippn10_cursor_set_attributes(ipp, &ippn10->curs_attr); 24070ccab60SHarry Wentland REG_UPDATE(CURSOR_CONTROL, 24170ccab60SHarry Wentland CURSOR_ENABLE, cur_en); 24270ccab60SHarry Wentland REG_UPDATE(CURSOR0_CONTROL, 24370ccab60SHarry Wentland CUR0_ENABLE, cur_en); 24470ccab60SHarry Wentland 24570ccab60SHarry Wentland REG_SET_2(CURSOR_POSITION, 0, 24670ccab60SHarry Wentland CURSOR_X_POSITION, pos->x, 24770ccab60SHarry Wentland CURSOR_Y_POSITION, pos->y); 24870ccab60SHarry Wentland 24970ccab60SHarry Wentland REG_SET_2(CURSOR_HOT_SPOT, 0, 25070ccab60SHarry Wentland CURSOR_HOT_SPOT_X, pos->x_hotspot, 25170ccab60SHarry Wentland CURSOR_HOT_SPOT_Y, pos->y_hotspot); 25270ccab60SHarry Wentland 25370ccab60SHarry Wentland REG_SET(CURSOR_DST_OFFSET, 0, 25470ccab60SHarry Wentland CURSOR_DST_X_OFFSET, dst_x_offset); 25570ccab60SHarry Wentland /* TODO Handle surface pixel formats other than 4:4:4 */ 25670ccab60SHarry Wentland } 25770ccab60SHarry Wentland 25870ccab60SHarry Wentland enum pixel_format_description { 25970ccab60SHarry Wentland PIXEL_FORMAT_FIXED = 0, 26070ccab60SHarry Wentland PIXEL_FORMAT_FIXED16, 26170ccab60SHarry Wentland PIXEL_FORMAT_FLOAT 26270ccab60SHarry Wentland 26370ccab60SHarry Wentland }; 26470ccab60SHarry Wentland 26570ccab60SHarry Wentland /*****************************************/ 26670ccab60SHarry Wentland /* Constructor, Destructor */ 26770ccab60SHarry Wentland /*****************************************/ 26870ccab60SHarry Wentland 26970ccab60SHarry Wentland static void dcn10_ipp_destroy(struct input_pixel_processor **ipp) 27070ccab60SHarry Wentland { 27170ccab60SHarry Wentland dm_free(TO_DCN10_IPP(*ipp)); 27270ccab60SHarry Wentland *ipp = NULL; 27370ccab60SHarry Wentland } 27470ccab60SHarry Wentland 27570ccab60SHarry Wentland static const struct ipp_funcs dcn10_ipp_funcs = { 276a3ac9dadSDmytro Laktyushkin .ipp_cursor_set_attributes = ippn10_cursor_set_attributes, 277a3ac9dadSDmytro Laktyushkin .ipp_cursor_set_position = ippn10_cursor_set_position, 278b3c340faSYue Hin Lau .ipp_set_degamma = NULL, 279b3c340faSYue Hin Lau .ipp_program_input_lut = NULL, 280b3c340faSYue Hin Lau .ipp_full_bypass = NULL, 281b3c340faSYue Hin Lau .ipp_setup = NULL, 282b3c340faSYue Hin Lau .ipp_program_degamma_pwl = NULL, 28370ccab60SHarry Wentland .ipp_destroy = dcn10_ipp_destroy 28470ccab60SHarry Wentland }; 28570ccab60SHarry Wentland 28670ccab60SHarry Wentland void dcn10_ipp_construct( 28770ccab60SHarry Wentland struct dcn10_ipp *ippn10, 28870ccab60SHarry Wentland struct dc_context *ctx, 28970ccab60SHarry Wentland int inst, 29070ccab60SHarry Wentland const struct dcn10_ipp_registers *regs, 29170ccab60SHarry Wentland const struct dcn10_ipp_shift *ipp_shift, 29270ccab60SHarry Wentland const struct dcn10_ipp_mask *ipp_mask) 29370ccab60SHarry Wentland { 29470ccab60SHarry Wentland ippn10->base.ctx = ctx; 29570ccab60SHarry Wentland ippn10->base.inst = inst; 29670ccab60SHarry Wentland ippn10->base.funcs = &dcn10_ipp_funcs; 29770ccab60SHarry Wentland 29870ccab60SHarry Wentland ippn10->regs = regs; 29970ccab60SHarry Wentland ippn10->ipp_shift = ipp_shift; 30070ccab60SHarry Wentland ippn10->ipp_mask = ipp_mask; 30170ccab60SHarry Wentland } 302a3ac9dadSDmytro Laktyushkin 303