cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dcn20_dpp_cm.c (36787B)


      1/*
      2 * Copyright 2016 Advanced Micro Devices, Inc.
      3 *
      4 * Permission is hereby granted, free of charge, to any person obtaining a
      5 * copy of this software and associated documentation files (the "Software"),
      6 * to deal in the Software without restriction, including without limitation
      7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 * and/or sell copies of the Software, and to permit persons to whom the
      9 * Software is furnished to do so, subject to the following conditions:
     10 *
     11 * The above copyright notice and this permission notice shall be included in
     12 * all copies or substantial portions of the Software.
     13 *
     14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20 * OTHER DEALINGS IN THE SOFTWARE.
     21 *
     22 * Authors: AMD
     23 *
     24 */
     25
     26#include "dm_services.h"
     27
     28#include "core_types.h"
     29
     30#include "reg_helper.h"
     31#include "dcn20_dpp.h"
     32#include "basics/conversion.h"
     33
     34#include "dcn10/dcn10_cm_common.h"
     35
     36#define REG(reg)\
     37	dpp->tf_regs->reg
     38
     39#define IND_REG(index) \
     40	(index)
     41
     42#define CTX \
     43	dpp->base.ctx
     44
     45#undef FN
     46#define FN(reg_name, field_name) \
     47	dpp->tf_shift->field_name, dpp->tf_mask->field_name
     48
     49
     50static void dpp2_enable_cm_block(
     51		struct dpp *dpp_base)
     52{
     53	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
     54
     55	unsigned int cm_bypass_mode = 0;
     56	//Temp, put CM in bypass mode
     57	if (dpp_base->ctx->dc->debug.cm_in_bypass)
     58		cm_bypass_mode = 1;
     59
     60	REG_UPDATE(CM_CONTROL, CM_BYPASS, cm_bypass_mode);
     61}
     62
     63
     64static bool dpp2_degamma_ram_inuse(
     65		struct dpp *dpp_base,
     66		bool *ram_a_inuse)
     67{
     68	bool ret = false;
     69	uint32_t status_reg = 0;
     70	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
     71
     72	REG_GET(CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_CONFIG_STATUS,
     73			&status_reg);
     74
     75	if (status_reg == 3) {
     76		*ram_a_inuse = true;
     77		ret = true;
     78	} else if (status_reg == 4) {
     79		*ram_a_inuse = false;
     80		ret = true;
     81	}
     82	return ret;
     83}
     84
     85static void dpp2_program_degamma_lut(
     86		struct dpp *dpp_base,
     87		const struct pwl_result_data *rgb,
     88		uint32_t num,
     89		bool is_ram_a)
     90{
     91	uint32_t i;
     92
     93	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
     94	REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK,
     95				CM_DGAM_LUT_WRITE_EN_MASK, 7);
     96	REG_UPDATE(CM_DGAM_LUT_WRITE_EN_MASK, CM_DGAM_LUT_WRITE_SEL,
     97					is_ram_a == true ? 0:1);
     98
     99	REG_SET(CM_DGAM_LUT_INDEX, 0, CM_DGAM_LUT_INDEX, 0);
    100	for (i = 0 ; i < num; i++) {
    101		REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].red_reg);
    102		REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].green_reg);
    103		REG_SET(CM_DGAM_LUT_DATA, 0, CM_DGAM_LUT_DATA, rgb[i].blue_reg);
    104
    105		REG_SET(CM_DGAM_LUT_DATA, 0,
    106				CM_DGAM_LUT_DATA, rgb[i].delta_red_reg);
    107		REG_SET(CM_DGAM_LUT_DATA, 0,
    108				CM_DGAM_LUT_DATA, rgb[i].delta_green_reg);
    109		REG_SET(CM_DGAM_LUT_DATA, 0,
    110				CM_DGAM_LUT_DATA, rgb[i].delta_blue_reg);
    111
    112	}
    113
    114}
    115
    116void dpp2_set_degamma_pwl(
    117		struct dpp *dpp_base,
    118		const struct pwl_params *params)
    119{
    120	bool is_ram_a = true;
    121
    122	dpp1_power_on_degamma_lut(dpp_base, true);
    123	dpp2_enable_cm_block(dpp_base);
    124	dpp2_degamma_ram_inuse(dpp_base, &is_ram_a);
    125	if (is_ram_a == true)
    126		dpp1_program_degamma_lutb_settings(dpp_base, params);
    127	else
    128		dpp1_program_degamma_luta_settings(dpp_base, params);
    129
    130	dpp2_program_degamma_lut(dpp_base, params->rgb_resulted, params->hw_points_num, !is_ram_a);
    131	dpp1_degamma_ram_select(dpp_base, !is_ram_a);
    132}
    133
    134void dpp2_set_degamma(
    135		struct dpp *dpp_base,
    136		enum ipp_degamma_mode mode)
    137{
    138	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    139	dpp2_enable_cm_block(dpp_base);
    140
    141	switch (mode) {
    142	case IPP_DEGAMMA_MODE_BYPASS:
    143		/* Setting de gamma bypass for now */
    144		REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 0);
    145		break;
    146	case IPP_DEGAMMA_MODE_HW_sRGB:
    147		REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 1);
    148		break;
    149	case IPP_DEGAMMA_MODE_HW_xvYCC:
    150		REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 2);
    151			break;
    152	case IPP_DEGAMMA_MODE_USER_PWL:
    153		REG_UPDATE(CM_DGAM_CONTROL, CM_DGAM_LUT_MODE, 3);
    154		break;
    155	default:
    156		BREAK_TO_DEBUGGER();
    157		break;
    158	}
    159}
    160
    161static void program_gamut_remap(
    162		struct dcn20_dpp *dpp,
    163		const uint16_t *regval,
    164		enum dcn20_gamut_remap_select select)
    165{
    166	uint32_t cur_select = 0;
    167	struct color_matrices_reg gam_regs;
    168
    169	if (regval == NULL || select == DCN2_GAMUT_REMAP_BYPASS) {
    170		REG_SET(CM_GAMUT_REMAP_CONTROL, 0,
    171				CM_GAMUT_REMAP_MODE, 0);
    172		return;
    173	}
    174
    175	/* determine which gamut_remap coefficients (A or B) we are using
    176	 * currently. select the alternate set to double buffer
    177	 * the update so gamut_remap is updated on frame boundary
    178	 */
    179	IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA,
    180					CM_TEST_DEBUG_DATA_STATUS_IDX,
    181					CM_TEST_DEBUG_DATA_GAMUT_REMAP_MODE, &cur_select);
    182
    183	/* value stored in dbg reg will be 1 greater than mode we want */
    184	if (cur_select != DCN2_GAMUT_REMAP_COEF_A)
    185		select = DCN2_GAMUT_REMAP_COEF_A;
    186	else
    187		select = DCN2_GAMUT_REMAP_COEF_B;
    188
    189	gam_regs.shifts.csc_c11 = dpp->tf_shift->CM_GAMUT_REMAP_C11;
    190	gam_regs.masks.csc_c11  = dpp->tf_mask->CM_GAMUT_REMAP_C11;
    191	gam_regs.shifts.csc_c12 = dpp->tf_shift->CM_GAMUT_REMAP_C12;
    192	gam_regs.masks.csc_c12 = dpp->tf_mask->CM_GAMUT_REMAP_C12;
    193
    194	if (select == DCN2_GAMUT_REMAP_COEF_A) {
    195		gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_C11_C12);
    196		gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_C33_C34);
    197	} else {
    198		gam_regs.csc_c11_c12 = REG(CM_GAMUT_REMAP_B_C11_C12);
    199		gam_regs.csc_c33_c34 = REG(CM_GAMUT_REMAP_B_C33_C34);
    200	}
    201
    202	cm_helper_program_color_matrices(
    203				dpp->base.ctx,
    204				regval,
    205				&gam_regs);
    206
    207	REG_SET(
    208			CM_GAMUT_REMAP_CONTROL, 0,
    209			CM_GAMUT_REMAP_MODE, select);
    210
    211}
    212
    213void dpp2_cm_set_gamut_remap(
    214	struct dpp *dpp_base,
    215	const struct dpp_grph_csc_adjustment *adjust)
    216{
    217	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    218	int i = 0;
    219
    220	if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW)
    221		/* Bypass if type is bypass or hw */
    222		program_gamut_remap(dpp, NULL, DCN2_GAMUT_REMAP_BYPASS);
    223	else {
    224		struct fixed31_32 arr_matrix[12];
    225		uint16_t arr_reg_val[12];
    226
    227		for (i = 0; i < 12; i++)
    228			arr_matrix[i] = adjust->temperature_matrix[i];
    229
    230		convert_float_matrix(
    231			arr_reg_val, arr_matrix, 12);
    232
    233		program_gamut_remap(dpp, arr_reg_val, DCN2_GAMUT_REMAP_COEF_A);
    234	}
    235}
    236
    237void dpp2_program_input_csc(
    238		struct dpp *dpp_base,
    239		enum dc_color_space color_space,
    240		enum dcn20_input_csc_select input_select,
    241		const struct out_csc_color_matrix *tbl_entry)
    242{
    243	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    244	int i;
    245	int arr_size = sizeof(dpp_input_csc_matrix)/sizeof(struct dpp_input_csc_matrix);
    246	const uint16_t *regval = NULL;
    247	uint32_t cur_select = 0;
    248	enum dcn20_input_csc_select select;
    249	struct color_matrices_reg icsc_regs;
    250
    251	if (input_select == DCN2_ICSC_SELECT_BYPASS) {
    252		REG_SET(CM_ICSC_CONTROL, 0, CM_ICSC_MODE, 0);
    253		return;
    254	}
    255
    256	if (tbl_entry == NULL) {
    257		for (i = 0; i < arr_size; i++)
    258			if (dpp_input_csc_matrix[i].color_space == color_space) {
    259				regval = dpp_input_csc_matrix[i].regval;
    260				break;
    261			}
    262
    263		if (regval == NULL) {
    264			BREAK_TO_DEBUGGER();
    265			return;
    266		}
    267	} else {
    268		regval = tbl_entry->regval;
    269	}
    270
    271	/* determine which CSC coefficients (A or B) we are using
    272	 * currently.  select the alternate set to double buffer
    273	 * the CSC update so CSC is updated on frame boundary
    274	 */
    275	IX_REG_GET(CM_TEST_DEBUG_INDEX, CM_TEST_DEBUG_DATA,
    276					CM_TEST_DEBUG_DATA_STATUS_IDX,
    277					CM_TEST_DEBUG_DATA_ICSC_MODE, &cur_select);
    278
    279	if (cur_select != DCN2_ICSC_SELECT_ICSC_A)
    280		select = DCN2_ICSC_SELECT_ICSC_A;
    281	else
    282		select = DCN2_ICSC_SELECT_ICSC_B;
    283
    284	icsc_regs.shifts.csc_c11 = dpp->tf_shift->CM_ICSC_C11;
    285	icsc_regs.masks.csc_c11  = dpp->tf_mask->CM_ICSC_C11;
    286	icsc_regs.shifts.csc_c12 = dpp->tf_shift->CM_ICSC_C12;
    287	icsc_regs.masks.csc_c12 = dpp->tf_mask->CM_ICSC_C12;
    288
    289	if (select == DCN2_ICSC_SELECT_ICSC_A) {
    290
    291		icsc_regs.csc_c11_c12 = REG(CM_ICSC_C11_C12);
    292		icsc_regs.csc_c33_c34 = REG(CM_ICSC_C33_C34);
    293
    294	} else {
    295
    296		icsc_regs.csc_c11_c12 = REG(CM_ICSC_B_C11_C12);
    297		icsc_regs.csc_c33_c34 = REG(CM_ICSC_B_C33_C34);
    298
    299	}
    300
    301	cm_helper_program_color_matrices(
    302			dpp->base.ctx,
    303			regval,
    304			&icsc_regs);
    305
    306	REG_SET(CM_ICSC_CONTROL, 0,
    307				CM_ICSC_MODE, select);
    308}
    309
    310static void dpp20_power_on_blnd_lut(
    311	struct dpp *dpp_base,
    312	bool power_on)
    313{
    314	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    315
    316	REG_SET(CM_MEM_PWR_CTRL, 0,
    317			BLNDGAM_MEM_PWR_FORCE, power_on == true ? 0:1);
    318
    319}
    320
    321static void dpp20_configure_blnd_lut(
    322		struct dpp *dpp_base,
    323		bool is_ram_a)
    324{
    325	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    326
    327	REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK,
    328			CM_BLNDGAM_LUT_WRITE_EN_MASK, 7);
    329	REG_UPDATE(CM_BLNDGAM_LUT_WRITE_EN_MASK,
    330			CM_BLNDGAM_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
    331	REG_SET(CM_BLNDGAM_LUT_INDEX, 0, CM_BLNDGAM_LUT_INDEX, 0);
    332}
    333
    334static void dpp20_program_blnd_pwl(
    335		struct dpp *dpp_base,
    336		const struct pwl_result_data *rgb,
    337		uint32_t num)
    338{
    339	uint32_t i;
    340	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    341
    342	for (i = 0 ; i < num; i++) {
    343		REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].red_reg);
    344		REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].green_reg);
    345		REG_SET(CM_BLNDGAM_LUT_DATA, 0, CM_BLNDGAM_LUT_DATA, rgb[i].blue_reg);
    346
    347		REG_SET(CM_BLNDGAM_LUT_DATA, 0,
    348				CM_BLNDGAM_LUT_DATA, rgb[i].delta_red_reg);
    349		REG_SET(CM_BLNDGAM_LUT_DATA, 0,
    350				CM_BLNDGAM_LUT_DATA, rgb[i].delta_green_reg);
    351		REG_SET(CM_BLNDGAM_LUT_DATA, 0,
    352				CM_BLNDGAM_LUT_DATA, rgb[i].delta_blue_reg);
    353
    354	}
    355
    356}
    357
    358static void dcn20_dpp_cm_get_reg_field(
    359		struct dcn20_dpp *dpp,
    360		struct xfer_func_reg *reg)
    361{
    362	reg->shifts.exp_region0_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
    363	reg->masks.exp_region0_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_LUT_OFFSET;
    364	reg->shifts.exp_region0_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
    365	reg->masks.exp_region0_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
    366	reg->shifts.exp_region1_lut_offset = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
    367	reg->masks.exp_region1_lut_offset = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_LUT_OFFSET;
    368	reg->shifts.exp_region1_num_segments = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
    369	reg->masks.exp_region1_num_segments = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
    370
    371	reg->shifts.field_region_end = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
    372	reg->masks.field_region_end = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_B;
    373	reg->shifts.field_region_end_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
    374	reg->masks.field_region_end_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_SLOPE_B;
    375	reg->shifts.field_region_end_base = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
    376	reg->masks.field_region_end_base = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_END_BASE_B;
    377	reg->shifts.field_region_linear_slope = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B;
    378	reg->masks.field_region_linear_slope = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_LINEAR_SLOPE_B;
    379	reg->shifts.exp_region_start = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
    380	reg->masks.exp_region_start = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_B;
    381	reg->shifts.exp_resion_start_segment = dpp->tf_shift->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
    382	reg->masks.exp_resion_start_segment = dpp->tf_mask->CM_BLNDGAM_RAMA_EXP_REGION_START_SEGMENT_B;
    383}
    384
    385/*program blnd lut RAM A*/
    386static void dpp20_program_blnd_luta_settings(
    387		struct dpp *dpp_base,
    388		const struct pwl_params *params)
    389{
    390	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    391	struct xfer_func_reg gam_regs;
    392
    393	dcn20_dpp_cm_get_reg_field(dpp, &gam_regs);
    394
    395	gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMA_START_CNTL_B);
    396	gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMA_START_CNTL_G);
    397	gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMA_START_CNTL_R);
    398	gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_B);
    399	gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_G);
    400	gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMA_SLOPE_CNTL_R);
    401	gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMA_END_CNTL1_B);
    402	gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMA_END_CNTL2_B);
    403	gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMA_END_CNTL1_G);
    404	gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMA_END_CNTL2_G);
    405	gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMA_END_CNTL1_R);
    406	gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMA_END_CNTL2_R);
    407	gam_regs.region_start = REG(CM_BLNDGAM_RAMA_REGION_0_1);
    408	gam_regs.region_end = REG(CM_BLNDGAM_RAMA_REGION_32_33);
    409
    410	cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
    411}
    412
    413/*program blnd lut RAM B*/
    414static void dpp20_program_blnd_lutb_settings(
    415		struct dpp *dpp_base,
    416		const struct pwl_params *params)
    417{
    418	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    419	struct xfer_func_reg gam_regs;
    420
    421	dcn20_dpp_cm_get_reg_field(dpp, &gam_regs);
    422
    423	gam_regs.start_cntl_b = REG(CM_BLNDGAM_RAMB_START_CNTL_B);
    424	gam_regs.start_cntl_g = REG(CM_BLNDGAM_RAMB_START_CNTL_G);
    425	gam_regs.start_cntl_r = REG(CM_BLNDGAM_RAMB_START_CNTL_R);
    426	gam_regs.start_slope_cntl_b = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_B);
    427	gam_regs.start_slope_cntl_g = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_G);
    428	gam_regs.start_slope_cntl_r = REG(CM_BLNDGAM_RAMB_SLOPE_CNTL_R);
    429	gam_regs.start_end_cntl1_b = REG(CM_BLNDGAM_RAMB_END_CNTL1_B);
    430	gam_regs.start_end_cntl2_b = REG(CM_BLNDGAM_RAMB_END_CNTL2_B);
    431	gam_regs.start_end_cntl1_g = REG(CM_BLNDGAM_RAMB_END_CNTL1_G);
    432	gam_regs.start_end_cntl2_g = REG(CM_BLNDGAM_RAMB_END_CNTL2_G);
    433	gam_regs.start_end_cntl1_r = REG(CM_BLNDGAM_RAMB_END_CNTL1_R);
    434	gam_regs.start_end_cntl2_r = REG(CM_BLNDGAM_RAMB_END_CNTL2_R);
    435	gam_regs.region_start = REG(CM_BLNDGAM_RAMB_REGION_0_1);
    436	gam_regs.region_end = REG(CM_BLNDGAM_RAMB_REGION_32_33);
    437
    438	cm_helper_program_xfer_func(dpp->base.ctx, params, &gam_regs);
    439}
    440
    441static enum dc_lut_mode dpp20_get_blndgam_current(struct dpp *dpp_base)
    442{
    443	enum dc_lut_mode mode;
    444	uint32_t state_mode;
    445	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    446
    447	REG_GET(CM_BLNDGAM_LUT_WRITE_EN_MASK,
    448					CM_BLNDGAM_CONFIG_STATUS, &state_mode);
    449
    450		switch (state_mode) {
    451		case 0:
    452			mode = LUT_BYPASS;
    453			break;
    454		case 1:
    455			mode = LUT_RAM_A;
    456			break;
    457		case 2:
    458			mode = LUT_RAM_B;
    459			break;
    460		default:
    461			mode = LUT_BYPASS;
    462			break;
    463		}
    464		return mode;
    465}
    466
    467bool dpp20_program_blnd_lut(
    468	struct dpp *dpp_base, const struct pwl_params *params)
    469{
    470	enum dc_lut_mode current_mode;
    471	enum dc_lut_mode next_mode;
    472	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    473
    474	if (params == NULL) {
    475		REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE, 0);
    476		return false;
    477	}
    478	current_mode = dpp20_get_blndgam_current(dpp_base);
    479	if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
    480		next_mode = LUT_RAM_B;
    481	else
    482		next_mode = LUT_RAM_A;
    483
    484	dpp20_power_on_blnd_lut(dpp_base, true);
    485	dpp20_configure_blnd_lut(dpp_base, next_mode == LUT_RAM_A);
    486
    487	if (next_mode == LUT_RAM_A)
    488		dpp20_program_blnd_luta_settings(dpp_base, params);
    489	else
    490		dpp20_program_blnd_lutb_settings(dpp_base, params);
    491
    492	dpp20_program_blnd_pwl(
    493			dpp_base, params->rgb_resulted, params->hw_points_num);
    494
    495	REG_SET(CM_BLNDGAM_CONTROL, 0, CM_BLNDGAM_LUT_MODE,
    496			next_mode == LUT_RAM_A ? 1:2);
    497
    498	return true;
    499}
    500
    501
    502static void dpp20_program_shaper_lut(
    503		struct dpp *dpp_base,
    504		const struct pwl_result_data *rgb,
    505		uint32_t num)
    506{
    507	uint32_t i, red, green, blue;
    508	uint32_t  red_delta, green_delta, blue_delta;
    509	uint32_t  red_value, green_value, blue_value;
    510
    511	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    512
    513	for (i = 0 ; i < num; i++) {
    514
    515		red   = rgb[i].red_reg;
    516		green = rgb[i].green_reg;
    517		blue  = rgb[i].blue_reg;
    518
    519		red_delta   = rgb[i].delta_red_reg;
    520		green_delta = rgb[i].delta_green_reg;
    521		blue_delta  = rgb[i].delta_blue_reg;
    522
    523		red_value   = ((red_delta   & 0x3ff) << 14) | (red   & 0x3fff);
    524		green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff);
    525		blue_value  = ((blue_delta  & 0x3ff) << 14) | (blue  & 0x3fff);
    526
    527		REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, red_value);
    528		REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, green_value);
    529		REG_SET(CM_SHAPER_LUT_DATA, 0, CM_SHAPER_LUT_DATA, blue_value);
    530	}
    531
    532}
    533
    534static enum dc_lut_mode dpp20_get_shaper_current(struct dpp *dpp_base)
    535{
    536	enum dc_lut_mode mode;
    537	uint32_t state_mode;
    538	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    539
    540	REG_GET(CM_SHAPER_LUT_WRITE_EN_MASK,
    541			CM_SHAPER_CONFIG_STATUS, &state_mode);
    542
    543		switch (state_mode) {
    544		case 0:
    545			mode = LUT_BYPASS;
    546			break;
    547		case 1:
    548			mode = LUT_RAM_A;
    549			break;
    550		case 2:
    551			mode = LUT_RAM_B;
    552			break;
    553		default:
    554			mode = LUT_BYPASS;
    555			break;
    556		}
    557		return mode;
    558}
    559
    560static void dpp20_configure_shaper_lut(
    561		struct dpp *dpp_base,
    562		bool is_ram_a)
    563{
    564	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    565
    566	REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
    567			CM_SHAPER_LUT_WRITE_EN_MASK, 7);
    568	REG_UPDATE(CM_SHAPER_LUT_WRITE_EN_MASK,
    569			CM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
    570	REG_SET(CM_SHAPER_LUT_INDEX, 0, CM_SHAPER_LUT_INDEX, 0);
    571}
    572
    573/*program shaper RAM A*/
    574
    575static void dpp20_program_shaper_luta_settings(
    576		struct dpp *dpp_base,
    577		const struct pwl_params *params)
    578{
    579	const struct gamma_curve *curve;
    580	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    581
    582	REG_SET_2(CM_SHAPER_RAMA_START_CNTL_B, 0,
    583		CM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
    584		CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
    585	REG_SET_2(CM_SHAPER_RAMA_START_CNTL_G, 0,
    586		CM_SHAPER_RAMA_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
    587		CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_G, 0);
    588	REG_SET_2(CM_SHAPER_RAMA_START_CNTL_R, 0,
    589		CM_SHAPER_RAMA_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
    590		CM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_R, 0);
    591
    592	REG_SET_2(CM_SHAPER_RAMA_END_CNTL_B, 0,
    593		CM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
    594		CM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
    595
    596	REG_SET_2(CM_SHAPER_RAMA_END_CNTL_G, 0,
    597		CM_SHAPER_RAMA_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
    598		CM_SHAPER_RAMA_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
    599
    600	REG_SET_2(CM_SHAPER_RAMA_END_CNTL_R, 0,
    601		CM_SHAPER_RAMA_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
    602		CM_SHAPER_RAMA_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
    603
    604	curve = params->arr_curve_points;
    605	REG_SET_4(CM_SHAPER_RAMA_REGION_0_1, 0,
    606		CM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
    607		CM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
    608		CM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
    609		CM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
    610
    611	curve += 2;
    612	REG_SET_4(CM_SHAPER_RAMA_REGION_2_3, 0,
    613		CM_SHAPER_RAMA_EXP_REGION2_LUT_OFFSET, curve[0].offset,
    614		CM_SHAPER_RAMA_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
    615		CM_SHAPER_RAMA_EXP_REGION3_LUT_OFFSET, curve[1].offset,
    616		CM_SHAPER_RAMA_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
    617
    618	curve += 2;
    619	REG_SET_4(CM_SHAPER_RAMA_REGION_4_5, 0,
    620		CM_SHAPER_RAMA_EXP_REGION4_LUT_OFFSET, curve[0].offset,
    621		CM_SHAPER_RAMA_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
    622		CM_SHAPER_RAMA_EXP_REGION5_LUT_OFFSET, curve[1].offset,
    623		CM_SHAPER_RAMA_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
    624
    625	curve += 2;
    626	REG_SET_4(CM_SHAPER_RAMA_REGION_6_7, 0,
    627		CM_SHAPER_RAMA_EXP_REGION6_LUT_OFFSET, curve[0].offset,
    628		CM_SHAPER_RAMA_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
    629		CM_SHAPER_RAMA_EXP_REGION7_LUT_OFFSET, curve[1].offset,
    630		CM_SHAPER_RAMA_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
    631
    632	curve += 2;
    633	REG_SET_4(CM_SHAPER_RAMA_REGION_8_9, 0,
    634		CM_SHAPER_RAMA_EXP_REGION8_LUT_OFFSET, curve[0].offset,
    635		CM_SHAPER_RAMA_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
    636		CM_SHAPER_RAMA_EXP_REGION9_LUT_OFFSET, curve[1].offset,
    637		CM_SHAPER_RAMA_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
    638
    639	curve += 2;
    640	REG_SET_4(CM_SHAPER_RAMA_REGION_10_11, 0,
    641		CM_SHAPER_RAMA_EXP_REGION10_LUT_OFFSET, curve[0].offset,
    642		CM_SHAPER_RAMA_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
    643		CM_SHAPER_RAMA_EXP_REGION11_LUT_OFFSET, curve[1].offset,
    644		CM_SHAPER_RAMA_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
    645
    646	curve += 2;
    647	REG_SET_4(CM_SHAPER_RAMA_REGION_12_13, 0,
    648		CM_SHAPER_RAMA_EXP_REGION12_LUT_OFFSET, curve[0].offset,
    649		CM_SHAPER_RAMA_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
    650		CM_SHAPER_RAMA_EXP_REGION13_LUT_OFFSET, curve[1].offset,
    651		CM_SHAPER_RAMA_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
    652
    653	curve += 2;
    654	REG_SET_4(CM_SHAPER_RAMA_REGION_14_15, 0,
    655		CM_SHAPER_RAMA_EXP_REGION14_LUT_OFFSET, curve[0].offset,
    656		CM_SHAPER_RAMA_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
    657		CM_SHAPER_RAMA_EXP_REGION15_LUT_OFFSET, curve[1].offset,
    658		CM_SHAPER_RAMA_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
    659
    660	curve += 2;
    661	REG_SET_4(CM_SHAPER_RAMA_REGION_16_17, 0,
    662		CM_SHAPER_RAMA_EXP_REGION16_LUT_OFFSET, curve[0].offset,
    663		CM_SHAPER_RAMA_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
    664		CM_SHAPER_RAMA_EXP_REGION17_LUT_OFFSET, curve[1].offset,
    665		CM_SHAPER_RAMA_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
    666
    667	curve += 2;
    668	REG_SET_4(CM_SHAPER_RAMA_REGION_18_19, 0,
    669		CM_SHAPER_RAMA_EXP_REGION18_LUT_OFFSET, curve[0].offset,
    670		CM_SHAPER_RAMA_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
    671		CM_SHAPER_RAMA_EXP_REGION19_LUT_OFFSET, curve[1].offset,
    672		CM_SHAPER_RAMA_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
    673
    674	curve += 2;
    675	REG_SET_4(CM_SHAPER_RAMA_REGION_20_21, 0,
    676		CM_SHAPER_RAMA_EXP_REGION20_LUT_OFFSET, curve[0].offset,
    677		CM_SHAPER_RAMA_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
    678		CM_SHAPER_RAMA_EXP_REGION21_LUT_OFFSET, curve[1].offset,
    679		CM_SHAPER_RAMA_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
    680
    681	curve += 2;
    682	REG_SET_4(CM_SHAPER_RAMA_REGION_22_23, 0,
    683		CM_SHAPER_RAMA_EXP_REGION22_LUT_OFFSET, curve[0].offset,
    684		CM_SHAPER_RAMA_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
    685		CM_SHAPER_RAMA_EXP_REGION23_LUT_OFFSET, curve[1].offset,
    686		CM_SHAPER_RAMA_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
    687
    688	curve += 2;
    689	REG_SET_4(CM_SHAPER_RAMA_REGION_24_25, 0,
    690		CM_SHAPER_RAMA_EXP_REGION24_LUT_OFFSET, curve[0].offset,
    691		CM_SHAPER_RAMA_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
    692		CM_SHAPER_RAMA_EXP_REGION25_LUT_OFFSET, curve[1].offset,
    693		CM_SHAPER_RAMA_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
    694
    695	curve += 2;
    696	REG_SET_4(CM_SHAPER_RAMA_REGION_26_27, 0,
    697		CM_SHAPER_RAMA_EXP_REGION26_LUT_OFFSET, curve[0].offset,
    698		CM_SHAPER_RAMA_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
    699		CM_SHAPER_RAMA_EXP_REGION27_LUT_OFFSET, curve[1].offset,
    700		CM_SHAPER_RAMA_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
    701
    702	curve += 2;
    703	REG_SET_4(CM_SHAPER_RAMA_REGION_28_29, 0,
    704		CM_SHAPER_RAMA_EXP_REGION28_LUT_OFFSET, curve[0].offset,
    705		CM_SHAPER_RAMA_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
    706		CM_SHAPER_RAMA_EXP_REGION29_LUT_OFFSET, curve[1].offset,
    707		CM_SHAPER_RAMA_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
    708
    709	curve += 2;
    710	REG_SET_4(CM_SHAPER_RAMA_REGION_30_31, 0,
    711		CM_SHAPER_RAMA_EXP_REGION30_LUT_OFFSET, curve[0].offset,
    712		CM_SHAPER_RAMA_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
    713		CM_SHAPER_RAMA_EXP_REGION31_LUT_OFFSET, curve[1].offset,
    714		CM_SHAPER_RAMA_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
    715
    716	curve += 2;
    717	REG_SET_4(CM_SHAPER_RAMA_REGION_32_33, 0,
    718		CM_SHAPER_RAMA_EXP_REGION32_LUT_OFFSET, curve[0].offset,
    719		CM_SHAPER_RAMA_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
    720		CM_SHAPER_RAMA_EXP_REGION33_LUT_OFFSET, curve[1].offset,
    721		CM_SHAPER_RAMA_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
    722}
    723
    724/*program shaper RAM B*/
    725static void dpp20_program_shaper_lutb_settings(
    726		struct dpp *dpp_base,
    727		const struct pwl_params *params)
    728{
    729	const struct gamma_curve *curve;
    730	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    731
    732	REG_SET_2(CM_SHAPER_RAMB_START_CNTL_B, 0,
    733		CM_SHAPER_RAMB_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
    734		CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_B, 0);
    735	REG_SET_2(CM_SHAPER_RAMB_START_CNTL_G, 0,
    736		CM_SHAPER_RAMB_EXP_REGION_START_G, params->corner_points[0].green.custom_float_x,
    737		CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_G, 0);
    738	REG_SET_2(CM_SHAPER_RAMB_START_CNTL_R, 0,
    739		CM_SHAPER_RAMB_EXP_REGION_START_R, params->corner_points[0].red.custom_float_x,
    740		CM_SHAPER_RAMB_EXP_REGION_START_SEGMENT_R, 0);
    741
    742	REG_SET_2(CM_SHAPER_RAMB_END_CNTL_B, 0,
    743		CM_SHAPER_RAMB_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
    744		CM_SHAPER_RAMB_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
    745
    746	REG_SET_2(CM_SHAPER_RAMB_END_CNTL_G, 0,
    747		CM_SHAPER_RAMB_EXP_REGION_END_G, params->corner_points[1].green.custom_float_x,
    748		CM_SHAPER_RAMB_EXP_REGION_END_BASE_G, params->corner_points[1].green.custom_float_y);
    749
    750	REG_SET_2(CM_SHAPER_RAMB_END_CNTL_R, 0,
    751		CM_SHAPER_RAMB_EXP_REGION_END_R, params->corner_points[1].red.custom_float_x,
    752		CM_SHAPER_RAMB_EXP_REGION_END_BASE_R, params->corner_points[1].red.custom_float_y);
    753
    754	curve = params->arr_curve_points;
    755	REG_SET_4(CM_SHAPER_RAMB_REGION_0_1, 0,
    756		CM_SHAPER_RAMB_EXP_REGION0_LUT_OFFSET, curve[0].offset,
    757		CM_SHAPER_RAMB_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
    758		CM_SHAPER_RAMB_EXP_REGION1_LUT_OFFSET, curve[1].offset,
    759		CM_SHAPER_RAMB_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
    760
    761	curve += 2;
    762	REG_SET_4(CM_SHAPER_RAMB_REGION_2_3, 0,
    763		CM_SHAPER_RAMB_EXP_REGION2_LUT_OFFSET, curve[0].offset,
    764		CM_SHAPER_RAMB_EXP_REGION2_NUM_SEGMENTS, curve[0].segments_num,
    765		CM_SHAPER_RAMB_EXP_REGION3_LUT_OFFSET, curve[1].offset,
    766		CM_SHAPER_RAMB_EXP_REGION3_NUM_SEGMENTS, curve[1].segments_num);
    767
    768	curve += 2;
    769	REG_SET_4(CM_SHAPER_RAMB_REGION_4_5, 0,
    770		CM_SHAPER_RAMB_EXP_REGION4_LUT_OFFSET, curve[0].offset,
    771		CM_SHAPER_RAMB_EXP_REGION4_NUM_SEGMENTS, curve[0].segments_num,
    772		CM_SHAPER_RAMB_EXP_REGION5_LUT_OFFSET, curve[1].offset,
    773		CM_SHAPER_RAMB_EXP_REGION5_NUM_SEGMENTS, curve[1].segments_num);
    774
    775	curve += 2;
    776	REG_SET_4(CM_SHAPER_RAMB_REGION_6_7, 0,
    777		CM_SHAPER_RAMB_EXP_REGION6_LUT_OFFSET, curve[0].offset,
    778		CM_SHAPER_RAMB_EXP_REGION6_NUM_SEGMENTS, curve[0].segments_num,
    779		CM_SHAPER_RAMB_EXP_REGION7_LUT_OFFSET, curve[1].offset,
    780		CM_SHAPER_RAMB_EXP_REGION7_NUM_SEGMENTS, curve[1].segments_num);
    781
    782	curve += 2;
    783	REG_SET_4(CM_SHAPER_RAMB_REGION_8_9, 0,
    784		CM_SHAPER_RAMB_EXP_REGION8_LUT_OFFSET, curve[0].offset,
    785		CM_SHAPER_RAMB_EXP_REGION8_NUM_SEGMENTS, curve[0].segments_num,
    786		CM_SHAPER_RAMB_EXP_REGION9_LUT_OFFSET, curve[1].offset,
    787		CM_SHAPER_RAMB_EXP_REGION9_NUM_SEGMENTS, curve[1].segments_num);
    788
    789	curve += 2;
    790	REG_SET_4(CM_SHAPER_RAMB_REGION_10_11, 0,
    791		CM_SHAPER_RAMB_EXP_REGION10_LUT_OFFSET, curve[0].offset,
    792		CM_SHAPER_RAMB_EXP_REGION10_NUM_SEGMENTS, curve[0].segments_num,
    793		CM_SHAPER_RAMB_EXP_REGION11_LUT_OFFSET, curve[1].offset,
    794		CM_SHAPER_RAMB_EXP_REGION11_NUM_SEGMENTS, curve[1].segments_num);
    795
    796	curve += 2;
    797	REG_SET_4(CM_SHAPER_RAMB_REGION_12_13, 0,
    798		CM_SHAPER_RAMB_EXP_REGION12_LUT_OFFSET, curve[0].offset,
    799		CM_SHAPER_RAMB_EXP_REGION12_NUM_SEGMENTS, curve[0].segments_num,
    800		CM_SHAPER_RAMB_EXP_REGION13_LUT_OFFSET, curve[1].offset,
    801		CM_SHAPER_RAMB_EXP_REGION13_NUM_SEGMENTS, curve[1].segments_num);
    802
    803	curve += 2;
    804	REG_SET_4(CM_SHAPER_RAMB_REGION_14_15, 0,
    805		CM_SHAPER_RAMB_EXP_REGION14_LUT_OFFSET, curve[0].offset,
    806		CM_SHAPER_RAMB_EXP_REGION14_NUM_SEGMENTS, curve[0].segments_num,
    807		CM_SHAPER_RAMB_EXP_REGION15_LUT_OFFSET, curve[1].offset,
    808		CM_SHAPER_RAMB_EXP_REGION15_NUM_SEGMENTS, curve[1].segments_num);
    809
    810	curve += 2;
    811	REG_SET_4(CM_SHAPER_RAMB_REGION_16_17, 0,
    812		CM_SHAPER_RAMB_EXP_REGION16_LUT_OFFSET, curve[0].offset,
    813		CM_SHAPER_RAMB_EXP_REGION16_NUM_SEGMENTS, curve[0].segments_num,
    814		CM_SHAPER_RAMB_EXP_REGION17_LUT_OFFSET, curve[1].offset,
    815		CM_SHAPER_RAMB_EXP_REGION17_NUM_SEGMENTS, curve[1].segments_num);
    816
    817	curve += 2;
    818	REG_SET_4(CM_SHAPER_RAMB_REGION_18_19, 0,
    819		CM_SHAPER_RAMB_EXP_REGION18_LUT_OFFSET, curve[0].offset,
    820		CM_SHAPER_RAMB_EXP_REGION18_NUM_SEGMENTS, curve[0].segments_num,
    821		CM_SHAPER_RAMB_EXP_REGION19_LUT_OFFSET, curve[1].offset,
    822		CM_SHAPER_RAMB_EXP_REGION19_NUM_SEGMENTS, curve[1].segments_num);
    823
    824	curve += 2;
    825	REG_SET_4(CM_SHAPER_RAMB_REGION_20_21, 0,
    826		CM_SHAPER_RAMB_EXP_REGION20_LUT_OFFSET, curve[0].offset,
    827		CM_SHAPER_RAMB_EXP_REGION20_NUM_SEGMENTS, curve[0].segments_num,
    828		CM_SHAPER_RAMB_EXP_REGION21_LUT_OFFSET, curve[1].offset,
    829		CM_SHAPER_RAMB_EXP_REGION21_NUM_SEGMENTS, curve[1].segments_num);
    830
    831	curve += 2;
    832	REG_SET_4(CM_SHAPER_RAMB_REGION_22_23, 0,
    833		CM_SHAPER_RAMB_EXP_REGION22_LUT_OFFSET, curve[0].offset,
    834		CM_SHAPER_RAMB_EXP_REGION22_NUM_SEGMENTS, curve[0].segments_num,
    835		CM_SHAPER_RAMB_EXP_REGION23_LUT_OFFSET, curve[1].offset,
    836		CM_SHAPER_RAMB_EXP_REGION23_NUM_SEGMENTS, curve[1].segments_num);
    837
    838	curve += 2;
    839	REG_SET_4(CM_SHAPER_RAMB_REGION_24_25, 0,
    840		CM_SHAPER_RAMB_EXP_REGION24_LUT_OFFSET, curve[0].offset,
    841		CM_SHAPER_RAMB_EXP_REGION24_NUM_SEGMENTS, curve[0].segments_num,
    842		CM_SHAPER_RAMB_EXP_REGION25_LUT_OFFSET, curve[1].offset,
    843		CM_SHAPER_RAMB_EXP_REGION25_NUM_SEGMENTS, curve[1].segments_num);
    844
    845	curve += 2;
    846	REG_SET_4(CM_SHAPER_RAMB_REGION_26_27, 0,
    847		CM_SHAPER_RAMB_EXP_REGION26_LUT_OFFSET, curve[0].offset,
    848		CM_SHAPER_RAMB_EXP_REGION26_NUM_SEGMENTS, curve[0].segments_num,
    849		CM_SHAPER_RAMB_EXP_REGION27_LUT_OFFSET, curve[1].offset,
    850		CM_SHAPER_RAMB_EXP_REGION27_NUM_SEGMENTS, curve[1].segments_num);
    851
    852	curve += 2;
    853	REG_SET_4(CM_SHAPER_RAMB_REGION_28_29, 0,
    854		CM_SHAPER_RAMB_EXP_REGION28_LUT_OFFSET, curve[0].offset,
    855		CM_SHAPER_RAMB_EXP_REGION28_NUM_SEGMENTS, curve[0].segments_num,
    856		CM_SHAPER_RAMB_EXP_REGION29_LUT_OFFSET, curve[1].offset,
    857		CM_SHAPER_RAMB_EXP_REGION29_NUM_SEGMENTS, curve[1].segments_num);
    858
    859	curve += 2;
    860	REG_SET_4(CM_SHAPER_RAMB_REGION_30_31, 0,
    861		CM_SHAPER_RAMB_EXP_REGION30_LUT_OFFSET, curve[0].offset,
    862		CM_SHAPER_RAMB_EXP_REGION30_NUM_SEGMENTS, curve[0].segments_num,
    863		CM_SHAPER_RAMB_EXP_REGION31_LUT_OFFSET, curve[1].offset,
    864		CM_SHAPER_RAMB_EXP_REGION31_NUM_SEGMENTS, curve[1].segments_num);
    865
    866	curve += 2;
    867	REG_SET_4(CM_SHAPER_RAMB_REGION_32_33, 0,
    868		CM_SHAPER_RAMB_EXP_REGION32_LUT_OFFSET, curve[0].offset,
    869		CM_SHAPER_RAMB_EXP_REGION32_NUM_SEGMENTS, curve[0].segments_num,
    870		CM_SHAPER_RAMB_EXP_REGION33_LUT_OFFSET, curve[1].offset,
    871		CM_SHAPER_RAMB_EXP_REGION33_NUM_SEGMENTS, curve[1].segments_num);
    872
    873}
    874
    875
    876bool dpp20_program_shaper(
    877		struct dpp *dpp_base,
    878		const struct pwl_params *params)
    879{
    880	enum dc_lut_mode current_mode;
    881	enum dc_lut_mode next_mode;
    882
    883	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    884
    885	if (params == NULL) {
    886		REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, 0);
    887		return false;
    888	}
    889	current_mode = dpp20_get_shaper_current(dpp_base);
    890
    891	if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
    892		next_mode = LUT_RAM_B;
    893	else
    894		next_mode = LUT_RAM_A;
    895
    896	dpp20_configure_shaper_lut(dpp_base, next_mode == LUT_RAM_A);
    897
    898	if (next_mode == LUT_RAM_A)
    899		dpp20_program_shaper_luta_settings(dpp_base, params);
    900	else
    901		dpp20_program_shaper_lutb_settings(dpp_base, params);
    902
    903	dpp20_program_shaper_lut(
    904			dpp_base, params->rgb_resulted, params->hw_points_num);
    905
    906	REG_SET(CM_SHAPER_CONTROL, 0, CM_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2);
    907
    908	return true;
    909
    910}
    911
    912static enum dc_lut_mode get3dlut_config(
    913			struct dpp *dpp_base,
    914			bool *is_17x17x17,
    915			bool *is_12bits_color_channel)
    916{
    917	uint32_t i_mode, i_enable_10bits, lut_size;
    918	enum dc_lut_mode mode;
    919	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    920
    921	REG_GET_2(CM_3DLUT_READ_WRITE_CONTROL,
    922			CM_3DLUT_CONFIG_STATUS, &i_mode,
    923			CM_3DLUT_30BIT_EN, &i_enable_10bits);
    924
    925	switch (i_mode) {
    926	case 0:
    927		mode = LUT_BYPASS;
    928		break;
    929	case 1:
    930		mode = LUT_RAM_A;
    931		break;
    932	case 2:
    933		mode = LUT_RAM_B;
    934		break;
    935	default:
    936		mode = LUT_BYPASS;
    937		break;
    938	}
    939	if (i_enable_10bits > 0)
    940		*is_12bits_color_channel = false;
    941	else
    942		*is_12bits_color_channel = true;
    943
    944	REG_GET(CM_3DLUT_MODE, CM_3DLUT_SIZE, &lut_size);
    945
    946	if (lut_size == 0)
    947		*is_17x17x17 = true;
    948	else
    949		*is_17x17x17 = false;
    950
    951	return mode;
    952}
    953/*
    954 * select ramA or ramB, or bypass
    955 * select color channel size 10 or 12 bits
    956 * select 3dlut size 17x17x17 or 9x9x9
    957 */
    958static void dpp20_set_3dlut_mode(
    959		struct dpp *dpp_base,
    960		enum dc_lut_mode mode,
    961		bool is_color_channel_12bits,
    962		bool is_lut_size17x17x17)
    963{
    964	uint32_t lut_mode;
    965	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    966
    967	if (mode == LUT_BYPASS)
    968		lut_mode = 0;
    969	else if (mode == LUT_RAM_A)
    970		lut_mode = 1;
    971	else
    972		lut_mode = 2;
    973
    974	REG_UPDATE_2(CM_3DLUT_MODE,
    975			CM_3DLUT_MODE, lut_mode,
    976			CM_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1);
    977}
    978
    979static void dpp20_select_3dlut_ram(
    980		struct dpp *dpp_base,
    981		enum dc_lut_mode mode,
    982		bool is_color_channel_12bits)
    983{
    984	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
    985
    986	REG_UPDATE_2(CM_3DLUT_READ_WRITE_CONTROL,
    987			CM_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1,
    988			CM_3DLUT_30BIT_EN,
    989			is_color_channel_12bits == true ? 0:1);
    990}
    991
    992
    993
    994static void dpp20_set3dlut_ram12(
    995		struct dpp *dpp_base,
    996		const struct dc_rgb *lut,
    997		uint32_t entries)
    998{
    999	uint32_t i, red, green, blue, red1, green1, blue1;
   1000	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
   1001
   1002	for (i = 0 ; i < entries; i += 2) {
   1003		red   = lut[i].red<<4;
   1004		green = lut[i].green<<4;
   1005		blue  = lut[i].blue<<4;
   1006		red1   = lut[i+1].red<<4;
   1007		green1 = lut[i+1].green<<4;
   1008		blue1  = lut[i+1].blue<<4;
   1009
   1010		REG_SET_2(CM_3DLUT_DATA, 0,
   1011				CM_3DLUT_DATA0, red,
   1012				CM_3DLUT_DATA1, red1);
   1013
   1014		REG_SET_2(CM_3DLUT_DATA, 0,
   1015				CM_3DLUT_DATA0, green,
   1016				CM_3DLUT_DATA1, green1);
   1017
   1018		REG_SET_2(CM_3DLUT_DATA, 0,
   1019				CM_3DLUT_DATA0, blue,
   1020				CM_3DLUT_DATA1, blue1);
   1021
   1022	}
   1023}
   1024
   1025/*
   1026 * load selected lut with 10 bits color channels
   1027 */
   1028static void dpp20_set3dlut_ram10(
   1029		struct dpp *dpp_base,
   1030		const struct dc_rgb *lut,
   1031		uint32_t entries)
   1032{
   1033	uint32_t i, red, green, blue, value;
   1034	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
   1035
   1036	for (i = 0; i < entries; i++) {
   1037		red   = lut[i].red;
   1038		green = lut[i].green;
   1039		blue  = lut[i].blue;
   1040
   1041		value = (red<<20) | (green<<10) | blue;
   1042
   1043		REG_SET(CM_3DLUT_DATA_30BIT, 0, CM_3DLUT_DATA_30BIT, value);
   1044	}
   1045
   1046}
   1047
   1048
   1049static void dpp20_select_3dlut_ram_mask(
   1050		struct dpp *dpp_base,
   1051		uint32_t ram_selection_mask)
   1052{
   1053	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
   1054
   1055	REG_UPDATE(CM_3DLUT_READ_WRITE_CONTROL, CM_3DLUT_WRITE_EN_MASK,
   1056			ram_selection_mask);
   1057	REG_SET(CM_3DLUT_INDEX, 0, CM_3DLUT_INDEX, 0);
   1058}
   1059
   1060bool dpp20_program_3dlut(
   1061		struct dpp *dpp_base,
   1062		struct tetrahedral_params *params)
   1063{
   1064	enum dc_lut_mode mode;
   1065	bool is_17x17x17;
   1066	bool is_12bits_color_channel;
   1067	struct dc_rgb *lut0;
   1068	struct dc_rgb *lut1;
   1069	struct dc_rgb *lut2;
   1070	struct dc_rgb *lut3;
   1071	int lut_size0;
   1072	int lut_size;
   1073
   1074	if (params == NULL) {
   1075		dpp20_set_3dlut_mode(dpp_base, LUT_BYPASS, false, false);
   1076		return false;
   1077	}
   1078	mode = get3dlut_config(dpp_base, &is_17x17x17, &is_12bits_color_channel);
   1079
   1080	if (mode == LUT_BYPASS || mode == LUT_RAM_B)
   1081		mode = LUT_RAM_A;
   1082	else
   1083		mode = LUT_RAM_B;
   1084
   1085	is_17x17x17 = !params->use_tetrahedral_9;
   1086	is_12bits_color_channel = params->use_12bits;
   1087	if (is_17x17x17) {
   1088		lut0 = params->tetrahedral_17.lut0;
   1089		lut1 = params->tetrahedral_17.lut1;
   1090		lut2 = params->tetrahedral_17.lut2;
   1091		lut3 = params->tetrahedral_17.lut3;
   1092		lut_size0 = sizeof(params->tetrahedral_17.lut0)/
   1093					sizeof(params->tetrahedral_17.lut0[0]);
   1094		lut_size  = sizeof(params->tetrahedral_17.lut1)/
   1095					sizeof(params->tetrahedral_17.lut1[0]);
   1096	} else {
   1097		lut0 = params->tetrahedral_9.lut0;
   1098		lut1 = params->tetrahedral_9.lut1;
   1099		lut2 = params->tetrahedral_9.lut2;
   1100		lut3 = params->tetrahedral_9.lut3;
   1101		lut_size0 = sizeof(params->tetrahedral_9.lut0)/
   1102				sizeof(params->tetrahedral_9.lut0[0]);
   1103		lut_size  = sizeof(params->tetrahedral_9.lut1)/
   1104				sizeof(params->tetrahedral_9.lut1[0]);
   1105		}
   1106
   1107	dpp20_select_3dlut_ram(dpp_base, mode,
   1108				is_12bits_color_channel);
   1109	dpp20_select_3dlut_ram_mask(dpp_base, 0x1);
   1110	if (is_12bits_color_channel)
   1111		dpp20_set3dlut_ram12(dpp_base, lut0, lut_size0);
   1112	else
   1113		dpp20_set3dlut_ram10(dpp_base, lut0, lut_size0);
   1114
   1115	dpp20_select_3dlut_ram_mask(dpp_base, 0x2);
   1116	if (is_12bits_color_channel)
   1117		dpp20_set3dlut_ram12(dpp_base, lut1, lut_size);
   1118	else
   1119		dpp20_set3dlut_ram10(dpp_base, lut1, lut_size);
   1120
   1121	dpp20_select_3dlut_ram_mask(dpp_base, 0x4);
   1122	if (is_12bits_color_channel)
   1123		dpp20_set3dlut_ram12(dpp_base, lut2, lut_size);
   1124	else
   1125		dpp20_set3dlut_ram10(dpp_base, lut2, lut_size);
   1126
   1127	dpp20_select_3dlut_ram_mask(dpp_base, 0x8);
   1128	if (is_12bits_color_channel)
   1129		dpp20_set3dlut_ram12(dpp_base, lut3, lut_size);
   1130	else
   1131		dpp20_set3dlut_ram10(dpp_base, lut3, lut_size);
   1132
   1133
   1134	dpp20_set_3dlut_mode(dpp_base, mode, is_12bits_color_channel,
   1135					is_17x17x17);
   1136
   1137	return true;
   1138}
   1139
   1140void dpp2_set_hdr_multiplier(
   1141		struct dpp *dpp_base,
   1142		uint32_t multiplier)
   1143{
   1144	struct dcn20_dpp *dpp = TO_DCN20_DPP(dpp_base);
   1145
   1146	REG_UPDATE(CM_HDR_MULT_COEF, CM_HDR_MULT_COEF, multiplier);
   1147}