File Index
Files and directories
Sign in
FILE

dcn30_mpc.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/amd/display/dc/mpc/dcn30/dcn30_mpc.c C
   1/*
   2 * Copyright 2020 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 "reg_helper.h"
  27#include "dcn30_mpc.h"
  28#include "dcn30/dcn30_cm_common.h"
  29#include "basics/conversion.h"
  30#include "dcn10/dcn10_cm_common.h"
  31#include "dc.h"
  32
  33#define REG(reg)\
  34	mpc30->mpc_regs->reg
  35
  36#define CTX \
  37	mpc30->base.ctx
  38
  39#undef FN
  40#define FN(reg_name, field_name) \
  41	mpc30->mpc_shift->field_name, mpc30->mpc_mask->field_name
  42
  43
  44#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
  45
  46
  47void mpc3_mpc_init(struct mpc *mpc)
  48{
  49	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
  50	int opp_id;
  51
  52	mpc1_mpc_init(mpc);
  53
  54	for (opp_id = 0; opp_id < MAX_OPP; opp_id++) {
  55		if (REG(MUX[opp_id]))
  56			/* disable mpc out rate and flow control */
  57			REG_UPDATE_2(MUX[opp_id], MPC_OUT_RATE_CONTROL_DISABLE,
  58					1, MPC_OUT_FLOW_CONTROL_COUNT, 0);
  59	}
  60}
  61
  62void mpc3_mpc_init_single_inst(struct mpc *mpc, unsigned int mpcc_id)
  63{
  64	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
  65
  66	mpc1_mpc_init_single_inst(mpc, mpcc_id);
  67
  68	/* assuming mpc out mux is connected to opp with the same index at this
  69	 * point in time (e.g. transitioning from vbios to driver)
  70	 */
  71	if (mpcc_id < MAX_OPP && REG(MUX[mpcc_id]))
  72		/* disable mpc out rate and flow control */
  73		REG_UPDATE_2(MUX[mpcc_id], MPC_OUT_RATE_CONTROL_DISABLE,
  74				1, MPC_OUT_FLOW_CONTROL_COUNT, 0);
  75}
  76
  77bool mpc3_is_dwb_idle(
  78	struct mpc *mpc,
  79	int dwb_id)
  80{
  81	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
  82	unsigned int status;
  83
  84	REG_GET(DWB_MUX[dwb_id], MPC_DWB0_MUX_STATUS, &status);
  85
  86	if (status == 0xf)
  87		return true;
  88	else
  89		return false;
  90}
  91
  92void mpc3_set_dwb_mux(
  93	struct mpc *mpc,
  94	int dwb_id,
  95	int mpcc_id)
  96{
  97	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
  98
  99	REG_SET(DWB_MUX[dwb_id], 0,
 100		MPC_DWB0_MUX, mpcc_id);
 101}
 102
 103void mpc3_disable_dwb_mux(
 104	struct mpc *mpc,
 105	int dwb_id)
 106{
 107	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 108
 109	REG_SET(DWB_MUX[dwb_id], 0,
 110		MPC_DWB0_MUX, 0xf);
 111}
 112
 113void mpc3_set_out_rate_control(
 114	struct mpc *mpc,
 115	int opp_id,
 116	bool enable,
 117	bool rate_2x_mode,
 118	struct mpc_dwb_flow_control *flow_control)
 119{
 120	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 121
 122	/* Always disable mpc out rate and flow control.
 123	 * MPC flow rate control is not needed for DCN30 and above.
 124	 */
 125	REG_UPDATE_2(MUX[opp_id],
 126			MPC_OUT_RATE_CONTROL_DISABLE, 1,
 127			MPC_OUT_RATE_CONTROL, 0);
 128}
 129
 130enum dc_lut_mode mpc3_get_ogam_current(struct mpc *mpc, int mpcc_id)
 131{
 132	/*Contrary to DCN2 and DCN1 wherein a single status register field holds this info;
 133	 *in DCN3/3AG, we need to read two separate fields to retrieve the same info
 134	 */
 135	enum dc_lut_mode mode;
 136	uint32_t state_mode;
 137	uint32_t state_ram_lut_in_use;
 138	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 139
 140	REG_GET_2(MPCC_OGAM_CONTROL[mpcc_id], MPCC_OGAM_MODE_CURRENT, &state_mode,
 141		  MPCC_OGAM_SELECT_CURRENT, &state_ram_lut_in_use);
 142
 143	switch (state_mode) {
 144	case 0:
 145		mode = LUT_BYPASS;
 146		break;
 147	case 2:
 148		switch (state_ram_lut_in_use) {
 149		case 0:
 150			mode = LUT_RAM_A;
 151			break;
 152		case 1:
 153			mode = LUT_RAM_B;
 154			break;
 155		default:
 156			mode = LUT_BYPASS;
 157			break;
 158		}
 159		break;
 160	default:
 161		mode = LUT_BYPASS;
 162		break;
 163	}
 164
 165	return mode;
 166}
 167
 168void mpc3_power_on_ogam_lut(
 169		struct mpc *mpc, int mpcc_id,
 170		bool power_on)
 171{
 172	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 173
 174	/*
 175	 * Powering on: force memory active so the LUT can be updated.
 176	 * Powering off: allow entering memory low power mode
 177	 *
 178	 * Memory low power mode is controlled during MPC OGAM LUT init.
 179	 */
 180	REG_UPDATE(MPCC_MEM_PWR_CTRL[mpcc_id],
 181		   MPCC_OGAM_MEM_PWR_DIS, power_on != 0);
 182
 183	/* Wait for memory to be powered on - we won't be able to write to it otherwise. */
 184	if (power_on)
 185		REG_WAIT(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_PWR_STATE, 0, 10, 10);
 186}
 187
 188static void mpc3_configure_ogam_lut(
 189		struct mpc *mpc, int mpcc_id,
 190		bool is_ram_a)
 191{
 192	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 193
 194	REG_UPDATE_2(MPCC_OGAM_LUT_CONTROL[mpcc_id],
 195			MPCC_OGAM_LUT_WRITE_COLOR_MASK, 7,
 196			MPCC_OGAM_LUT_HOST_SEL, is_ram_a == true ? 0:1);
 197
 198	REG_SET(MPCC_OGAM_LUT_INDEX[mpcc_id], 0, MPCC_OGAM_LUT_INDEX, 0);
 199}
 200
 201static void mpc3_ogam_get_reg_field(
 202		struct mpc *mpc,
 203		struct dcn3_xfer_func_reg *reg)
 204{
 205	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 206
 207	reg->shifts.field_region_start_base = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_START_BASE_B;
 208	reg->masks.field_region_start_base = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_START_BASE_B;
 209	reg->shifts.field_offset = mpc30->mpc_shift->MPCC_OGAM_RAMA_OFFSET_B;
 210	reg->masks.field_offset = mpc30->mpc_mask->MPCC_OGAM_RAMA_OFFSET_B;
 211
 212	reg->shifts.exp_region0_lut_offset = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION0_LUT_OFFSET;
 213	reg->masks.exp_region0_lut_offset = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION0_LUT_OFFSET;
 214	reg->shifts.exp_region0_num_segments = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
 215	reg->masks.exp_region0_num_segments = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION0_NUM_SEGMENTS;
 216	reg->shifts.exp_region1_lut_offset = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION1_LUT_OFFSET;
 217	reg->masks.exp_region1_lut_offset = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION1_LUT_OFFSET;
 218	reg->shifts.exp_region1_num_segments = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
 219	reg->masks.exp_region1_num_segments = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION1_NUM_SEGMENTS;
 220
 221	reg->shifts.field_region_end = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_END_B;
 222	reg->masks.field_region_end = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_END_B;
 223	reg->shifts.field_region_end_slope = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_END_SLOPE_B;
 224	reg->masks.field_region_end_slope = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_END_SLOPE_B;
 225	reg->shifts.field_region_end_base = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_END_BASE_B;
 226	reg->masks.field_region_end_base = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_END_BASE_B;
 227	reg->shifts.field_region_linear_slope = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_START_SLOPE_B;
 228	reg->masks.field_region_linear_slope = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_START_SLOPE_B;
 229	reg->shifts.exp_region_start = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_START_B;
 230	reg->masks.exp_region_start = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_START_B;
 231	reg->shifts.exp_resion_start_segment = mpc30->mpc_shift->MPCC_OGAM_RAMA_EXP_REGION_START_SEGMENT_B;
 232	reg->masks.exp_resion_start_segment = mpc30->mpc_mask->MPCC_OGAM_RAMA_EXP_REGION_START_SEGMENT_B;
 233}
 234
 235static void mpc3_program_luta(struct mpc *mpc, int mpcc_id,
 236		const struct pwl_params *params)
 237{
 238	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 239	struct dcn3_xfer_func_reg gam_regs;
 240
 241	mpc3_ogam_get_reg_field(mpc, &gam_regs);
 242
 243	gam_regs.start_cntl_b = REG(MPCC_OGAM_RAMA_START_CNTL_B[mpcc_id]);
 244	gam_regs.start_cntl_g = REG(MPCC_OGAM_RAMA_START_CNTL_G[mpcc_id]);
 245	gam_regs.start_cntl_r = REG(MPCC_OGAM_RAMA_START_CNTL_R[mpcc_id]);
 246	gam_regs.start_slope_cntl_b = REG(MPCC_OGAM_RAMA_START_SLOPE_CNTL_B[mpcc_id]);
 247	gam_regs.start_slope_cntl_g = REG(MPCC_OGAM_RAMA_START_SLOPE_CNTL_G[mpcc_id]);
 248	gam_regs.start_slope_cntl_r = REG(MPCC_OGAM_RAMA_START_SLOPE_CNTL_R[mpcc_id]);
 249	gam_regs.start_end_cntl1_b = REG(MPCC_OGAM_RAMA_END_CNTL1_B[mpcc_id]);
 250	gam_regs.start_end_cntl2_b = REG(MPCC_OGAM_RAMA_END_CNTL2_B[mpcc_id]);
 251	gam_regs.start_end_cntl1_g = REG(MPCC_OGAM_RAMA_END_CNTL1_G[mpcc_id]);
 252	gam_regs.start_end_cntl2_g = REG(MPCC_OGAM_RAMA_END_CNTL2_G[mpcc_id]);
 253	gam_regs.start_end_cntl1_r = REG(MPCC_OGAM_RAMA_END_CNTL1_R[mpcc_id]);
 254	gam_regs.start_end_cntl2_r = REG(MPCC_OGAM_RAMA_END_CNTL2_R[mpcc_id]);
 255	gam_regs.region_start = REG(MPCC_OGAM_RAMA_REGION_0_1[mpcc_id]);
 256	gam_regs.region_end = REG(MPCC_OGAM_RAMA_REGION_32_33[mpcc_id]);
 257	//New registers in DCN3AG/DCN OGAM block
 258	gam_regs.offset_b =  REG(MPCC_OGAM_RAMA_OFFSET_B[mpcc_id]);
 259	gam_regs.offset_g =  REG(MPCC_OGAM_RAMA_OFFSET_G[mpcc_id]);
 260	gam_regs.offset_r =  REG(MPCC_OGAM_RAMA_OFFSET_R[mpcc_id]);
 261	gam_regs.start_base_cntl_b = REG(MPCC_OGAM_RAMA_START_BASE_CNTL_B[mpcc_id]);
 262	gam_regs.start_base_cntl_g = REG(MPCC_OGAM_RAMA_START_BASE_CNTL_G[mpcc_id]);
 263	gam_regs.start_base_cntl_r = REG(MPCC_OGAM_RAMA_START_BASE_CNTL_R[mpcc_id]);
 264
 265	cm_helper_program_gamcor_xfer_func(mpc30->base.ctx, params, &gam_regs);
 266}
 267
 268static void mpc3_program_lutb(struct mpc *mpc, int mpcc_id,
 269		const struct pwl_params *params)
 270{
 271	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 272	struct dcn3_xfer_func_reg gam_regs;
 273
 274	mpc3_ogam_get_reg_field(mpc, &gam_regs);
 275
 276	gam_regs.start_cntl_b = REG(MPCC_OGAM_RAMB_START_CNTL_B[mpcc_id]);
 277	gam_regs.start_cntl_g = REG(MPCC_OGAM_RAMB_START_CNTL_G[mpcc_id]);
 278	gam_regs.start_cntl_r = REG(MPCC_OGAM_RAMB_START_CNTL_R[mpcc_id]);
 279	gam_regs.start_slope_cntl_b = REG(MPCC_OGAM_RAMB_START_SLOPE_CNTL_B[mpcc_id]);
 280	gam_regs.start_slope_cntl_g = REG(MPCC_OGAM_RAMB_START_SLOPE_CNTL_G[mpcc_id]);
 281	gam_regs.start_slope_cntl_r = REG(MPCC_OGAM_RAMB_START_SLOPE_CNTL_R[mpcc_id]);
 282	gam_regs.start_end_cntl1_b = REG(MPCC_OGAM_RAMB_END_CNTL1_B[mpcc_id]);
 283	gam_regs.start_end_cntl2_b = REG(MPCC_OGAM_RAMB_END_CNTL2_B[mpcc_id]);
 284	gam_regs.start_end_cntl1_g = REG(MPCC_OGAM_RAMB_END_CNTL1_G[mpcc_id]);
 285	gam_regs.start_end_cntl2_g = REG(MPCC_OGAM_RAMB_END_CNTL2_G[mpcc_id]);
 286	gam_regs.start_end_cntl1_r = REG(MPCC_OGAM_RAMB_END_CNTL1_R[mpcc_id]);
 287	gam_regs.start_end_cntl2_r = REG(MPCC_OGAM_RAMB_END_CNTL2_R[mpcc_id]);
 288	gam_regs.region_start = REG(MPCC_OGAM_RAMB_REGION_0_1[mpcc_id]);
 289	gam_regs.region_end = REG(MPCC_OGAM_RAMB_REGION_32_33[mpcc_id]);
 290	//New registers in DCN3AG/DCN OGAM block
 291	gam_regs.offset_b =  REG(MPCC_OGAM_RAMB_OFFSET_B[mpcc_id]);
 292	gam_regs.offset_g =  REG(MPCC_OGAM_RAMB_OFFSET_G[mpcc_id]);
 293	gam_regs.offset_r =  REG(MPCC_OGAM_RAMB_OFFSET_R[mpcc_id]);
 294	gam_regs.start_base_cntl_b = REG(MPCC_OGAM_RAMB_START_BASE_CNTL_B[mpcc_id]);
 295	gam_regs.start_base_cntl_g = REG(MPCC_OGAM_RAMB_START_BASE_CNTL_G[mpcc_id]);
 296	gam_regs.start_base_cntl_r = REG(MPCC_OGAM_RAMB_START_BASE_CNTL_R[mpcc_id]);
 297
 298	cm_helper_program_gamcor_xfer_func(mpc30->base.ctx, params, &gam_regs);
 299}
 300
 301
 302static void mpc3_program_ogam_pwl(
 303		struct mpc *mpc, int mpcc_id,
 304		const struct pwl_result_data *rgb,
 305		uint32_t num)
 306{
 307	uint32_t i;
 308	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 309
 310	if (is_rgb_equal(rgb,  num)) {
 311		for (i = 0 ; i < num; i++)
 312			REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].red_reg);
 313	} else {
 314
 315		REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id],
 316				MPCC_OGAM_LUT_WRITE_COLOR_MASK, 4);
 317
 318		for (i = 0 ; i < num; i++)
 319			REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].red_reg);
 320
 321		REG_SET(MPCC_OGAM_LUT_INDEX[mpcc_id], 0, MPCC_OGAM_LUT_INDEX, 0);
 322
 323		REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id],
 324				MPCC_OGAM_LUT_WRITE_COLOR_MASK, 2);
 325
 326		for (i = 0 ; i < num; i++)
 327			REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].green_reg);
 328
 329		REG_SET(MPCC_OGAM_LUT_INDEX[mpcc_id], 0, MPCC_OGAM_LUT_INDEX, 0);
 330
 331		REG_UPDATE(MPCC_OGAM_LUT_CONTROL[mpcc_id],
 332				MPCC_OGAM_LUT_WRITE_COLOR_MASK, 1);
 333
 334		for (i = 0 ; i < num; i++)
 335			REG_SET(MPCC_OGAM_LUT_DATA[mpcc_id], 0, MPCC_OGAM_LUT_DATA, rgb[i].blue_reg);
 336
 337	}
 338
 339}
 340
 341void mpc3_set_output_gamma(
 342		struct mpc *mpc,
 343		int mpcc_id,
 344		const struct pwl_params *params)
 345{
 346	enum dc_lut_mode current_mode;
 347	enum dc_lut_mode next_mode;
 348	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 349
 350	if (mpc->ctx->dc->debug.cm_in_bypass) {
 351		REG_SET(MPCC_OGAM_MODE[mpcc_id], 0, MPCC_OGAM_MODE, 0);
 352		return;
 353	}
 354
 355	if (params == NULL) { //disable OGAM
 356		REG_SET(MPCC_OGAM_CONTROL[mpcc_id], 0, MPCC_OGAM_MODE, 0);
 357		return;
 358	}
 359	//enable OGAM
 360	REG_SET(MPCC_OGAM_CONTROL[mpcc_id], 0, MPCC_OGAM_MODE, 2);
 361
 362	current_mode = mpc3_get_ogam_current(mpc, mpcc_id);
 363	if (current_mode == LUT_BYPASS)
 364		next_mode = LUT_RAM_A;
 365	else if (current_mode == LUT_RAM_A)
 366		next_mode = LUT_RAM_B;
 367	else
 368		next_mode = LUT_RAM_A;
 369
 370	mpc3_power_on_ogam_lut(mpc, mpcc_id, true);
 371	mpc3_configure_ogam_lut(mpc, mpcc_id, next_mode == LUT_RAM_A);
 372
 373	if (next_mode == LUT_RAM_A)
 374		mpc3_program_luta(mpc, mpcc_id, params);
 375	else
 376		mpc3_program_lutb(mpc, mpcc_id, params);
 377
 378	mpc3_program_ogam_pwl(
 379			mpc, mpcc_id, params->rgb_resulted, params->hw_points_num);
 380
 381	/*we need to program 2 fields here as apposed to 1*/
 382	REG_UPDATE(MPCC_OGAM_CONTROL[mpcc_id],
 383			MPCC_OGAM_SELECT, next_mode == LUT_RAM_A ? 0:1);
 384
 385	if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
 386		mpc3_power_on_ogam_lut(mpc, mpcc_id, false);
 387}
 388
 389void mpc3_set_denorm(
 390		struct mpc *mpc,
 391		int opp_id,
 392		enum dc_color_depth output_depth)
 393{
 394	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 395	/* De-normalize Fixed U1.13 color data to different target bit depths. 0 is bypass*/
 396	int denorm_mode = 0;
 397
 398	switch (output_depth) {
 399	case COLOR_DEPTH_666:
 400		denorm_mode = 1;
 401		break;
 402	case COLOR_DEPTH_888:
 403		denorm_mode = 2;
 404		break;
 405	case COLOR_DEPTH_999:
 406		denorm_mode = 3;
 407		break;
 408	case COLOR_DEPTH_101010:
 409		denorm_mode = 4;
 410		break;
 411	case COLOR_DEPTH_111111:
 412		denorm_mode = 5;
 413		break;
 414	case COLOR_DEPTH_121212:
 415		denorm_mode = 6;
 416		break;
 417	case COLOR_DEPTH_141414:
 418	case COLOR_DEPTH_161616:
 419	default:
 420		/* not valid used case! */
 421		break;
 422	}
 423
 424	REG_UPDATE(DENORM_CONTROL[opp_id],
 425			MPC_OUT_DENORM_MODE, denorm_mode);
 426}
 427
 428void mpc3_set_denorm_clamp(
 429		struct mpc *mpc,
 430		int opp_id,
 431		struct mpc_denorm_clamp denorm_clamp)
 432{
 433	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 434
 435	/*program min and max clamp values for the pixel components*/
 436	REG_UPDATE_2(DENORM_CONTROL[opp_id],
 437			MPC_OUT_DENORM_CLAMP_MAX_R_CR, denorm_clamp.clamp_max_r_cr,
 438			MPC_OUT_DENORM_CLAMP_MIN_R_CR, denorm_clamp.clamp_min_r_cr);
 439	REG_UPDATE_2(DENORM_CLAMP_G_Y[opp_id],
 440			MPC_OUT_DENORM_CLAMP_MAX_G_Y, denorm_clamp.clamp_max_g_y,
 441			MPC_OUT_DENORM_CLAMP_MIN_G_Y, denorm_clamp.clamp_min_g_y);
 442	REG_UPDATE_2(DENORM_CLAMP_B_CB[opp_id],
 443			MPC_OUT_DENORM_CLAMP_MAX_B_CB, denorm_clamp.clamp_max_b_cb,
 444			MPC_OUT_DENORM_CLAMP_MIN_B_CB, denorm_clamp.clamp_min_b_cb);
 445}
 446
 447static enum dc_lut_mode mpc3_get_shaper_current(struct mpc *mpc, uint32_t rmu_idx)
 448{
 449	enum dc_lut_mode mode;
 450	uint32_t state_mode;
 451	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 452
 453	REG_GET(SHAPER_CONTROL[rmu_idx], MPC_RMU_SHAPER_LUT_MODE_CURRENT, &state_mode);
 454
 455	switch (state_mode) {
 456	case 0:
 457		mode = LUT_BYPASS;
 458		break;
 459	case 1:
 460		mode = LUT_RAM_A;
 461		break;
 462	case 2:
 463		mode = LUT_RAM_B;
 464		break;
 465	default:
 466		mode = LUT_BYPASS;
 467		break;
 468	}
 469
 470	return mode;
 471}
 472
 473static void mpc3_configure_shaper_lut(
 474		struct mpc *mpc,
 475		bool is_ram_a,
 476		uint32_t rmu_idx)
 477{
 478	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 479
 480	REG_UPDATE(SHAPER_LUT_WRITE_EN_MASK[rmu_idx],
 481			MPC_RMU_SHAPER_LUT_WRITE_EN_MASK, 7);
 482	REG_UPDATE(SHAPER_LUT_WRITE_EN_MASK[rmu_idx],
 483			MPC_RMU_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
 484	REG_SET(SHAPER_LUT_INDEX[rmu_idx], 0, MPC_RMU_SHAPER_LUT_INDEX, 0);
 485}
 486
 487static void mpc3_program_shaper_luta_settings(
 488		struct mpc *mpc,
 489		const struct pwl_params *params,
 490		uint32_t rmu_idx)
 491{
 492	const struct gamma_curve *curve;
 493	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 494
 495	REG_SET_2(SHAPER_RAMA_START_CNTL_B[rmu_idx], 0,
 496		MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
 497		MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 498	REG_SET_2(SHAPER_RAMA_START_CNTL_G[rmu_idx], 0,
 499			MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].green.custom_float_x,
 500			MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 501	REG_SET_2(SHAPER_RAMA_START_CNTL_R[rmu_idx], 0,
 502			MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].red.custom_float_x,
 503			MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 504
 505	REG_SET_2(SHAPER_RAMA_END_CNTL_B[rmu_idx], 0,
 506			MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
 507			MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
 508	REG_SET_2(SHAPER_RAMA_END_CNTL_G[rmu_idx], 0,
 509			MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].green.custom_float_x,
 510			MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].green.custom_float_y);
 511	REG_SET_2(SHAPER_RAMA_END_CNTL_R[rmu_idx], 0,
 512			MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].red.custom_float_x,
 513			MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].red.custom_float_y);
 514
 515	curve = params->arr_curve_points;
 516	REG_SET_4(SHAPER_RAMA_REGION_0_1[rmu_idx], 0,
 517		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 518		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 519		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 520		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 521
 522	curve += 2;
 523	REG_SET_4(SHAPER_RAMA_REGION_2_3[rmu_idx], 0,
 524		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 525		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 526		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 527		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 528
 529	curve += 2;
 530	REG_SET_4(SHAPER_RAMA_REGION_4_5[rmu_idx], 0,
 531		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 532		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 533		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 534		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 535
 536	curve += 2;
 537	REG_SET_4(SHAPER_RAMA_REGION_6_7[rmu_idx], 0,
 538		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 539		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 540		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 541		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 542
 543	curve += 2;
 544	REG_SET_4(SHAPER_RAMA_REGION_8_9[rmu_idx], 0,
 545		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 546		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 547		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 548		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 549
 550	curve += 2;
 551	REG_SET_4(SHAPER_RAMA_REGION_10_11[rmu_idx], 0,
 552		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 553		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 554		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 555		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 556
 557	curve += 2;
 558	REG_SET_4(SHAPER_RAMA_REGION_12_13[rmu_idx], 0,
 559		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 560		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 561		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 562		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 563
 564	curve += 2;
 565	REG_SET_4(SHAPER_RAMA_REGION_14_15[rmu_idx], 0,
 566		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 567		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 568		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 569		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 570
 571
 572	curve += 2;
 573	REG_SET_4(SHAPER_RAMA_REGION_16_17[rmu_idx], 0,
 574		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 575		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 576		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 577		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 578
 579	curve += 2;
 580	REG_SET_4(SHAPER_RAMA_REGION_18_19[rmu_idx], 0,
 581		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 582		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 583		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 584		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 585
 586	curve += 2;
 587	REG_SET_4(SHAPER_RAMA_REGION_20_21[rmu_idx], 0,
 588		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 589		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 590		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 591		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 592
 593	curve += 2;
 594	REG_SET_4(SHAPER_RAMA_REGION_22_23[rmu_idx], 0,
 595		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 596		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 597		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 598		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 599
 600	curve += 2;
 601	REG_SET_4(SHAPER_RAMA_REGION_24_25[rmu_idx], 0,
 602		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 603		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 604		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 605		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 606
 607	curve += 2;
 608	REG_SET_4(SHAPER_RAMA_REGION_26_27[rmu_idx], 0,
 609			MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 610			MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 611			MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 612			MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 613
 614	curve += 2;
 615	REG_SET_4(SHAPER_RAMA_REGION_28_29[rmu_idx], 0,
 616		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 617		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 618		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 619		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 620
 621	curve += 2;
 622	REG_SET_4(SHAPER_RAMA_REGION_30_31[rmu_idx], 0,
 623		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 624		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 625		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 626		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 627
 628	curve += 2;
 629	REG_SET_4(SHAPER_RAMA_REGION_32_33[rmu_idx], 0,
 630		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 631		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 632		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 633		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 634}
 635
 636static void mpc3_program_shaper_lutb_settings(
 637		struct mpc *mpc,
 638		const struct pwl_params *params,
 639		uint32_t rmu_idx)
 640{
 641	const struct gamma_curve *curve;
 642	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 643
 644	REG_SET_2(SHAPER_RAMB_START_CNTL_B[rmu_idx], 0,
 645		MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
 646		MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 647	REG_SET_2(SHAPER_RAMB_START_CNTL_G[rmu_idx], 0,
 648			MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].green.custom_float_x,
 649			MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 650	REG_SET_2(SHAPER_RAMB_START_CNTL_R[rmu_idx], 0,
 651			MPC_RMU_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].red.custom_float_x,
 652			MPC_RMU_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 653
 654	REG_SET_2(SHAPER_RAMB_END_CNTL_B[rmu_idx], 0,
 655			MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
 656			MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
 657	REG_SET_2(SHAPER_RAMB_END_CNTL_G[rmu_idx], 0,
 658			MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].green.custom_float_x,
 659			MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].green.custom_float_y);
 660	REG_SET_2(SHAPER_RAMB_END_CNTL_R[rmu_idx], 0,
 661			MPC_RMU_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].red.custom_float_x,
 662			MPC_RMU_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].red.custom_float_y);
 663
 664	curve = params->arr_curve_points;
 665	REG_SET_4(SHAPER_RAMB_REGION_0_1[rmu_idx], 0,
 666		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 667		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 668		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 669		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 670
 671	curve += 2;
 672	REG_SET_4(SHAPER_RAMB_REGION_2_3[rmu_idx], 0,
 673			MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 674			MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 675			MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 676			MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 677
 678
 679	curve += 2;
 680	REG_SET_4(SHAPER_RAMB_REGION_4_5[rmu_idx], 0,
 681			MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 682			MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 683			MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 684			MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 685
 686	curve += 2;
 687	REG_SET_4(SHAPER_RAMB_REGION_6_7[rmu_idx], 0,
 688			MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 689			MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 690			MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 691			MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 692
 693	curve += 2;
 694	REG_SET_4(SHAPER_RAMB_REGION_8_9[rmu_idx], 0,
 695		MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 696		MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 697		MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 698		MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 699
 700	curve += 2;
 701	REG_SET_4(SHAPER_RAMB_REGION_10_11[rmu_idx], 0,
 702			MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 703			MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 704			MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 705			MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 706
 707	curve += 2;
 708	REG_SET_4(SHAPER_RAMB_REGION_12_13[rmu_idx], 0,
 709			MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 710			MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 711			MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 712			MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 713
 714	curve += 2;
 715	REG_SET_4(SHAPER_RAMB_REGION_14_15[rmu_idx], 0,
 716			MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 717			MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 718			MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 719			MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 720
 721
 722	curve += 2;
 723	REG_SET_4(SHAPER_RAMB_REGION_16_17[rmu_idx], 0,
 724			MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 725			MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 726			MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 727			MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 728
 729	curve += 2;
 730	REG_SET_4(SHAPER_RAMB_REGION_18_19[rmu_idx], 0,
 731			MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 732			MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 733			MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 734			MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 735
 736	curve += 2;
 737	REG_SET_4(SHAPER_RAMB_REGION_20_21[rmu_idx], 0,
 738			MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 739			MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 740			MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 741			MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 742
 743	curve += 2;
 744	REG_SET_4(SHAPER_RAMB_REGION_22_23[rmu_idx], 0,
 745			MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 746			MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 747			MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 748			MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 749
 750	curve += 2;
 751	REG_SET_4(SHAPER_RAMB_REGION_24_25[rmu_idx], 0,
 752			MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 753			MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 754			MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 755			MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 756
 757	curve += 2;
 758	REG_SET_4(SHAPER_RAMB_REGION_26_27[rmu_idx], 0,
 759			MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 760			MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 761			MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 762			MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 763
 764	curve += 2;
 765	REG_SET_4(SHAPER_RAMB_REGION_28_29[rmu_idx], 0,
 766			MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 767			MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 768			MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 769			MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 770
 771	curve += 2;
 772	REG_SET_4(SHAPER_RAMB_REGION_30_31[rmu_idx], 0,
 773			MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 774			MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 775			MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 776			MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 777
 778	curve += 2;
 779	REG_SET_4(SHAPER_RAMB_REGION_32_33[rmu_idx], 0,
 780			MPC_RMU_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 781			MPC_RMU_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 782			MPC_RMU_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 783			MPC_RMU_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 784}
 785
 786
 787static void mpc3_program_shaper_lut(
 788		struct mpc *mpc,
 789		const struct pwl_result_data *rgb,
 790		uint32_t num,
 791		uint32_t rmu_idx)
 792{
 793	uint32_t i, red, green, blue;
 794	uint32_t  red_delta, green_delta, blue_delta;
 795	uint32_t  red_value, green_value, blue_value;
 796
 797	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 798
 799	for (i = 0 ; i < num; i++) {
 800
 801		red   = rgb[i].red_reg;
 802		green = rgb[i].green_reg;
 803		blue  = rgb[i].blue_reg;
 804
 805		red_delta   = rgb[i].delta_red_reg;
 806		green_delta = rgb[i].delta_green_reg;
 807		blue_delta  = rgb[i].delta_blue_reg;
 808
 809		red_value   = ((red_delta   & 0x3ff) << 14) | (red   & 0x3fff);
 810		green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff);
 811		blue_value  = ((blue_delta  & 0x3ff) << 14) | (blue  & 0x3fff);
 812
 813		REG_SET(SHAPER_LUT_DATA[rmu_idx], 0, MPC_RMU_SHAPER_LUT_DATA, red_value);
 814		REG_SET(SHAPER_LUT_DATA[rmu_idx], 0, MPC_RMU_SHAPER_LUT_DATA, green_value);
 815		REG_SET(SHAPER_LUT_DATA[rmu_idx], 0, MPC_RMU_SHAPER_LUT_DATA, blue_value);
 816	}
 817
 818}
 819
 820static void mpc3_power_on_shaper_3dlut(
 821		struct mpc *mpc,
 822		uint32_t rmu_idx,
 823	bool power_on)
 824{
 825	uint32_t power_status_shaper = 2;
 826	uint32_t power_status_3dlut  = 2;
 827	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 828	int max_retries = 10;
 829
 830	if (rmu_idx == 0) {
 831		REG_SET(MPC_RMU_MEM_PWR_CTRL, 0,
 832			MPC_RMU0_MEM_PWR_DIS, power_on == true ? 1:0);
 833		/* wait for memory to fully power up */
 834		if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
 835			REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_SHAPER_MEM_PWR_STATE, 0, 1, max_retries);
 836			REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_3DLUT_MEM_PWR_STATE, 0, 1, max_retries);
 837		}
 838
 839		/*read status is not mandatory, it is just for debugging*/
 840		REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_SHAPER_MEM_PWR_STATE, &power_status_shaper);
 841		REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_3DLUT_MEM_PWR_STATE, &power_status_3dlut);
 842	} else if (rmu_idx == 1) {
 843		REG_SET(MPC_RMU_MEM_PWR_CTRL, 0,
 844			MPC_RMU1_MEM_PWR_DIS, power_on == true ? 1:0);
 845		if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
 846			REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_SHAPER_MEM_PWR_STATE, 0, 1, max_retries);
 847			REG_WAIT(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_3DLUT_MEM_PWR_STATE, 0, 1, max_retries);
 848		}
 849
 850		REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_SHAPER_MEM_PWR_STATE, &power_status_shaper);
 851		REG_GET(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_3DLUT_MEM_PWR_STATE, &power_status_3dlut);
 852	}
 853	/*TODO Add rmu_idx == 2 for SIENNA_CICHLID */
 854	if (power_status_shaper != 0 && power_on == true)
 855		BREAK_TO_DEBUGGER();
 856
 857	if (power_status_3dlut != 0 && power_on == true)
 858		BREAK_TO_DEBUGGER();
 859}
 860
 861
 862
 863bool mpc3_program_shaper(
 864		struct mpc *mpc,
 865		const struct pwl_params *params,
 866		uint32_t rmu_idx)
 867{
 868	enum dc_lut_mode current_mode;
 869	enum dc_lut_mode next_mode;
 870
 871	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 872
 873	if (params == NULL) {
 874		REG_SET(SHAPER_CONTROL[rmu_idx], 0, MPC_RMU_SHAPER_LUT_MODE, 0);
 875		return false;
 876	}
 877
 878	if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
 879		mpc3_power_on_shaper_3dlut(mpc, rmu_idx, true);
 880
 881	current_mode = mpc3_get_shaper_current(mpc, rmu_idx);
 882
 883	if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
 884		next_mode = LUT_RAM_B;
 885	else
 886		next_mode = LUT_RAM_A;
 887
 888	mpc3_configure_shaper_lut(mpc, next_mode == LUT_RAM_A, rmu_idx);
 889
 890	if (next_mode == LUT_RAM_A)
 891		mpc3_program_shaper_luta_settings(mpc, params, rmu_idx);
 892	else
 893		mpc3_program_shaper_lutb_settings(mpc, params, rmu_idx);
 894
 895	mpc3_program_shaper_lut(
 896			mpc, params->rgb_resulted, params->hw_points_num, rmu_idx);
 897
 898	REG_SET(SHAPER_CONTROL[rmu_idx], 0, MPC_RMU_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2);
 899	mpc3_power_on_shaper_3dlut(mpc, rmu_idx, false);
 900
 901	return true;
 902}
 903
 904static void mpc3_set_3dlut_mode(
 905		struct mpc *mpc,
 906		enum dc_lut_mode mode,
 907		bool is_color_channel_12bits,
 908		bool is_lut_size17x17x17,
 909		uint32_t rmu_idx)
 910{
 911	uint32_t lut_mode;
 912	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 913
 914	if (mode == LUT_BYPASS)
 915		lut_mode = 0;
 916	else if (mode == LUT_RAM_A)
 917		lut_mode = 1;
 918	else
 919		lut_mode = 2;
 920
 921	REG_UPDATE_2(RMU_3DLUT_MODE[rmu_idx],
 922			MPC_RMU_3DLUT_MODE, lut_mode,
 923			MPC_RMU_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1);
 924}
 925
 926static enum dc_lut_mode get3dlut_config(
 927			struct mpc *mpc,
 928			bool *is_17x17x17,
 929			bool *is_12bits_color_channel,
 930			int rmu_idx)
 931{
 932	uint32_t i_mode, i_enable_10bits, lut_size;
 933	enum dc_lut_mode mode;
 934	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 935
 936	REG_GET(RMU_3DLUT_MODE[rmu_idx],
 937			MPC_RMU_3DLUT_MODE_CURRENT,  &i_mode);
 938
 939	REG_GET(RMU_3DLUT_READ_WRITE_CONTROL[rmu_idx],
 940			MPC_RMU_3DLUT_30BIT_EN, &i_enable_10bits);
 941
 942	switch (i_mode) {
 943	case 0:
 944		mode = LUT_BYPASS;
 945		break;
 946	case 1:
 947		mode = LUT_RAM_A;
 948		break;
 949	case 2:
 950		mode = LUT_RAM_B;
 951		break;
 952	default:
 953		mode = LUT_BYPASS;
 954		break;
 955	}
 956	if (i_enable_10bits > 0)
 957		*is_12bits_color_channel = false;
 958	else
 959		*is_12bits_color_channel = true;
 960
 961	REG_GET(RMU_3DLUT_MODE[rmu_idx], MPC_RMU_3DLUT_SIZE, &lut_size);
 962
 963	if (lut_size == 0)
 964		*is_17x17x17 = true;
 965	else
 966		*is_17x17x17 = false;
 967
 968	return mode;
 969}
 970
 971static void mpc3_select_3dlut_ram(
 972		struct mpc *mpc,
 973		enum dc_lut_mode mode,
 974		bool is_color_channel_12bits,
 975		uint32_t rmu_idx)
 976{
 977	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 978
 979	REG_UPDATE_2(RMU_3DLUT_READ_WRITE_CONTROL[rmu_idx],
 980		MPC_RMU_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1,
 981		MPC_RMU_3DLUT_30BIT_EN, is_color_channel_12bits == true ? 0:1);
 982}
 983
 984static void mpc3_select_3dlut_ram_mask(
 985		struct mpc *mpc,
 986		uint32_t ram_selection_mask,
 987		uint32_t rmu_idx)
 988{
 989	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 990
 991	REG_UPDATE(RMU_3DLUT_READ_WRITE_CONTROL[rmu_idx], MPC_RMU_3DLUT_WRITE_EN_MASK,
 992			ram_selection_mask);
 993	REG_SET(RMU_3DLUT_INDEX[rmu_idx], 0, MPC_RMU_3DLUT_INDEX, 0);
 994}
 995
 996static void mpc3_set3dlut_ram12(
 997		struct mpc *mpc,
 998		const struct dc_rgb *lut,
 999		uint32_t entries,
1000		uint32_t rmu_idx)
1001{
1002	uint32_t i, red, green, blue, red1, green1, blue1;
1003	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1004
1005	for (i = 0 ; i < entries; i += 2) {
1006		red   = lut[i].red<<4;
1007		green = lut[i].green<<4;
1008		blue  = lut[i].blue<<4;
1009		red1   = lut[i+1].red<<4;
1010		green1 = lut[i+1].green<<4;
1011		blue1  = lut[i+1].blue<<4;
1012
1013		REG_SET_2(RMU_3DLUT_DATA[rmu_idx], 0,
1014				MPC_RMU_3DLUT_DATA0, red,
1015				MPC_RMU_3DLUT_DATA1, red1);
1016
1017		REG_SET_2(RMU_3DLUT_DATA[rmu_idx], 0,
1018				MPC_RMU_3DLUT_DATA0, green,
1019				MPC_RMU_3DLUT_DATA1, green1);
1020
1021		REG_SET_2(RMU_3DLUT_DATA[rmu_idx], 0,
1022				MPC_RMU_3DLUT_DATA0, blue,
1023				MPC_RMU_3DLUT_DATA1, blue1);
1024	}
1025}
1026
1027static void mpc3_set3dlut_ram10(
1028		struct mpc *mpc,
1029		const struct dc_rgb *lut,
1030		uint32_t entries,
1031		uint32_t rmu_idx)
1032{
1033	uint32_t i, red, green, blue, value;
1034	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1035
1036	for (i = 0; i < entries; i++) {
1037		red   = lut[i].red;
1038		green = lut[i].green;
1039		blue  = lut[i].blue;
1040		//should we shift red 22bit and green 12? ask Nvenko
1041		value = (red<<20) | (green<<10) | blue;
1042
1043		REG_SET(RMU_3DLUT_DATA_30BIT[rmu_idx], 0, MPC_RMU_3DLUT_DATA_30BIT, value);
1044	}
1045
1046}
1047
1048
1049void mpc3_init_mpcc(struct mpcc *mpcc, int mpcc_inst)
1050{
1051	mpcc->mpcc_id = mpcc_inst;
1052	mpcc->dpp_id = 0xf;
1053	mpcc->mpcc_bot = NULL;
1054	mpcc->blnd_cfg.overlap_only = false;
1055	mpcc->blnd_cfg.global_alpha = 0xff;
1056	mpcc->blnd_cfg.global_gain = 0xff;
1057	mpcc->blnd_cfg.background_color_bpc = 4;
1058	mpcc->blnd_cfg.bottom_gain_mode = 0;
1059	mpcc->blnd_cfg.top_gain = 0x1f000;
1060	mpcc->blnd_cfg.bottom_inside_gain = 0x1f000;
1061	mpcc->blnd_cfg.bottom_outside_gain = 0x1f000;
1062	mpcc->sm_cfg.enable = false;
1063	mpcc->shared_bottom = false;
1064}
1065
1066static void program_gamut_remap(
1067		struct dcn30_mpc *mpc30,
1068		int mpcc_id,
1069		const uint16_t *regval,
1070		int select)
1071{
1072	uint16_t selection = 0;
1073	struct color_matrices_reg gam_regs;
1074
1075	if (regval == NULL || select == GAMUT_REMAP_BYPASS) {
1076		REG_SET(MPCC_GAMUT_REMAP_MODE[mpcc_id], 0,
1077				MPCC_GAMUT_REMAP_MODE, GAMUT_REMAP_BYPASS);
1078		return;
1079	}
1080	switch (select) {
1081	case GAMUT_REMAP_COEFF:
1082		selection = 1;
1083		break;
1084		/*this corresponds to GAMUT_REMAP coefficients set B
1085		 * we don't have common coefficient sets in dcn3ag/dcn3
1086		 */
1087	case GAMUT_REMAP_COMA_COEFF:
1088		selection = 2;
1089		break;
1090	default:
1091		break;
1092	}
1093
1094	gam_regs.shifts.csc_c11 = mpc30->mpc_shift->MPCC_GAMUT_REMAP_C11_A;
1095	gam_regs.masks.csc_c11  = mpc30->mpc_mask->MPCC_GAMUT_REMAP_C11_A;
1096	gam_regs.shifts.csc_c12 = mpc30->mpc_shift->MPCC_GAMUT_REMAP_C12_A;
1097	gam_regs.masks.csc_c12 = mpc30->mpc_mask->MPCC_GAMUT_REMAP_C12_A;
1098
1099
1100	if (select == GAMUT_REMAP_COEFF) {
1101		gam_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_A[mpcc_id]);
1102		gam_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_A[mpcc_id]);
1103
1104		cm_helper_program_color_matrices(
1105				mpc30->base.ctx,
1106				regval,
1107				&gam_regs);
1108
1109	} else  if (select == GAMUT_REMAP_COMA_COEFF) {
1110
1111		gam_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_B[mpcc_id]);
1112		gam_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_B[mpcc_id]);
1113
1114		cm_helper_program_color_matrices(
1115				mpc30->base.ctx,
1116				regval,
1117				&gam_regs);
1118
1119	}
1120	//select coefficient set to use
1121	REG_SET(MPCC_GAMUT_REMAP_MODE[mpcc_id], 0,
1122					MPCC_GAMUT_REMAP_MODE, selection);
1123}
1124
1125void mpc3_set_gamut_remap(
1126		struct mpc *mpc,
1127		int mpcc_id,
1128		const struct mpc_grph_gamut_adjustment *adjust)
1129{
1130	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1131	int i = 0;
1132	int gamut_mode;
1133
1134	if (adjust->gamut_adjust_type != GRAPHICS_GAMUT_ADJUST_TYPE_SW)
1135		program_gamut_remap(mpc30, mpcc_id, NULL, GAMUT_REMAP_BYPASS);
1136	else {
1137		struct fixed31_32 arr_matrix[12];
1138		uint16_t arr_reg_val[12];
1139
1140		for (i = 0; i < 12; i++)
1141			arr_matrix[i] = adjust->temperature_matrix[i];
1142
1143		convert_float_matrix(
1144			arr_reg_val, arr_matrix, 12);
1145
1146		//current coefficient set in use
1147		REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_id], MPCC_GAMUT_REMAP_MODE_CURRENT, &gamut_mode);
1148
1149		if (gamut_mode == 0)
1150			gamut_mode = 1; //use coefficient set A
1151		else if (gamut_mode == 1)
1152			gamut_mode = 2;
1153		else
1154			gamut_mode = 1;
1155
1156		program_gamut_remap(mpc30, mpcc_id, arr_reg_val, gamut_mode);
1157	}
1158}
1159
1160static void read_gamut_remap(struct dcn30_mpc *mpc30,
1161			     int mpcc_id,
1162			     uint16_t *regval,
1163			     uint32_t *select)
1164{
1165	struct color_matrices_reg gam_regs;
1166
1167	//current coefficient set in use
1168	REG_GET(MPCC_GAMUT_REMAP_MODE[mpcc_id], MPCC_GAMUT_REMAP_MODE_CURRENT, select);
1169
1170	gam_regs.shifts.csc_c11 = mpc30->mpc_shift->MPCC_GAMUT_REMAP_C11_A;
1171	gam_regs.masks.csc_c11  = mpc30->mpc_mask->MPCC_GAMUT_REMAP_C11_A;
1172	gam_regs.shifts.csc_c12 = mpc30->mpc_shift->MPCC_GAMUT_REMAP_C12_A;
1173	gam_regs.masks.csc_c12 = mpc30->mpc_mask->MPCC_GAMUT_REMAP_C12_A;
1174
1175	if (*select == GAMUT_REMAP_COEFF) {
1176		gam_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_A[mpcc_id]);
1177		gam_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_A[mpcc_id]);
1178
1179		cm_helper_read_color_matrices(
1180				mpc30->base.ctx,
1181				regval,
1182				&gam_regs);
1183
1184	} else  if (*select == GAMUT_REMAP_COMA_COEFF) {
1185
1186		gam_regs.csc_c11_c12 = REG(MPC_GAMUT_REMAP_C11_C12_B[mpcc_id]);
1187		gam_regs.csc_c33_c34 = REG(MPC_GAMUT_REMAP_C33_C34_B[mpcc_id]);
1188
1189		cm_helper_read_color_matrices(
1190				mpc30->base.ctx,
1191				regval,
1192				&gam_regs);
1193
1194	}
1195
1196}
1197
1198void mpc3_get_gamut_remap(struct mpc *mpc,
1199			  int mpcc_id,
1200			  struct mpc_grph_gamut_adjustment *adjust)
1201{
1202	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1203	uint16_t arr_reg_val[12] = {0};
1204	int select;
1205
1206	read_gamut_remap(mpc30, mpcc_id, arr_reg_val, &select);
1207
1208	if (select == GAMUT_REMAP_BYPASS) {
1209		adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_BYPASS;
1210		return;
1211	}
1212
1213	adjust->gamut_adjust_type = GRAPHICS_GAMUT_ADJUST_TYPE_SW;
1214	convert_hw_matrix(adjust->temperature_matrix,
1215			  arr_reg_val, ARRAY_SIZE(arr_reg_val));
1216}
1217
1218bool mpc3_program_3dlut(
1219		struct mpc *mpc,
1220		const struct tetrahedral_params *params,
1221		int rmu_idx)
1222{
1223	enum dc_lut_mode mode;
1224	bool is_17x17x17;
1225	bool is_12bits_color_channel;
1226	const struct dc_rgb *lut0;
1227	const struct dc_rgb *lut1;
1228	const struct dc_rgb *lut2;
1229	const struct dc_rgb *lut3;
1230	int lut_size0;
1231	int lut_size;
1232
1233	if (params == NULL) {
1234		mpc3_set_3dlut_mode(mpc, LUT_BYPASS, false, false, rmu_idx);
1235		return false;
1236	}
1237	mpc3_power_on_shaper_3dlut(mpc, rmu_idx, true);
1238
1239	mode = get3dlut_config(mpc, &is_17x17x17, &is_12bits_color_channel, rmu_idx);
1240
1241	if (mode == LUT_BYPASS || mode == LUT_RAM_B)
1242		mode = LUT_RAM_A;
1243	else
1244		mode = LUT_RAM_B;
1245
1246	is_17x17x17 = !params->use_tetrahedral_9;
1247	is_12bits_color_channel = params->use_12bits;
1248	if (is_17x17x17) {
1249		lut0 = params->tetrahedral_17.lut0;
1250		lut1 = params->tetrahedral_17.lut1;
1251		lut2 = params->tetrahedral_17.lut2;
1252		lut3 = params->tetrahedral_17.lut3;
1253		lut_size0 = sizeof(params->tetrahedral_17.lut0)/
1254					sizeof(params->tetrahedral_17.lut0[0]);
1255		lut_size  = sizeof(params->tetrahedral_17.lut1)/
1256					sizeof(params->tetrahedral_17.lut1[0]);
1257	} else {
1258		lut0 = params->tetrahedral_9.lut0;
1259		lut1 = params->tetrahedral_9.lut1;
1260		lut2 = params->tetrahedral_9.lut2;
1261		lut3 = params->tetrahedral_9.lut3;
1262		lut_size0 = sizeof(params->tetrahedral_9.lut0)/
1263				sizeof(params->tetrahedral_9.lut0[0]);
1264		lut_size  = sizeof(params->tetrahedral_9.lut1)/
1265				sizeof(params->tetrahedral_9.lut1[0]);
1266		}
1267
1268	mpc3_select_3dlut_ram(mpc, mode,
1269				is_12bits_color_channel, rmu_idx);
1270	mpc3_select_3dlut_ram_mask(mpc, 0x1, rmu_idx);
1271	if (is_12bits_color_channel)
1272		mpc3_set3dlut_ram12(mpc, lut0, lut_size0, rmu_idx);
1273	else
1274		mpc3_set3dlut_ram10(mpc, lut0, lut_size0, rmu_idx);
1275
1276	mpc3_select_3dlut_ram_mask(mpc, 0x2, rmu_idx);
1277	if (is_12bits_color_channel)
1278		mpc3_set3dlut_ram12(mpc, lut1, lut_size, rmu_idx);
1279	else
1280		mpc3_set3dlut_ram10(mpc, lut1, lut_size, rmu_idx);
1281
1282	mpc3_select_3dlut_ram_mask(mpc, 0x4, rmu_idx);
1283	if (is_12bits_color_channel)
1284		mpc3_set3dlut_ram12(mpc, lut2, lut_size, rmu_idx);
1285	else
1286		mpc3_set3dlut_ram10(mpc, lut2, lut_size, rmu_idx);
1287
1288	mpc3_select_3dlut_ram_mask(mpc, 0x8, rmu_idx);
1289	if (is_12bits_color_channel)
1290		mpc3_set3dlut_ram12(mpc, lut3, lut_size, rmu_idx);
1291	else
1292		mpc3_set3dlut_ram10(mpc, lut3, lut_size, rmu_idx);
1293
1294	mpc3_set_3dlut_mode(mpc, mode, is_12bits_color_channel,
1295					is_17x17x17, rmu_idx);
1296
1297	if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
1298		mpc3_power_on_shaper_3dlut(mpc, rmu_idx, false);
1299
1300	return true;
1301}
1302
1303void mpc3_set_output_csc(
1304		struct mpc *mpc,
1305		int opp_id,
1306		const uint16_t *regval,
1307		enum mpc_output_csc_mode ocsc_mode)
1308{
1309	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1310	struct color_matrices_reg ocsc_regs;
1311
1312	REG_WRITE(MPC_OUT_CSC_COEF_FORMAT, 0);
1313
1314	REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode);
1315
1316	if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE)
1317		return;
1318
1319	if (regval == NULL) {
1320		BREAK_TO_DEBUGGER();
1321		return;
1322	}
1323
1324	ocsc_regs.shifts.csc_c11 = mpc30->mpc_shift->MPC_OCSC_C11_A;
1325	ocsc_regs.masks.csc_c11  = mpc30->mpc_mask->MPC_OCSC_C11_A;
1326	ocsc_regs.shifts.csc_c12 = mpc30->mpc_shift->MPC_OCSC_C12_A;
1327	ocsc_regs.masks.csc_c12 = mpc30->mpc_mask->MPC_OCSC_C12_A;
1328
1329	if (ocsc_mode == MPC_OUTPUT_CSC_COEF_A) {
1330		ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_A[opp_id]);
1331		ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_A[opp_id]);
1332	} else {
1333		ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_B[opp_id]);
1334		ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_B[opp_id]);
1335	}
1336	cm_helper_program_color_matrices(
1337			mpc30->base.ctx,
1338			regval,
1339			&ocsc_regs);
1340}
1341
1342void mpc3_set_ocsc_default(
1343		struct mpc *mpc,
1344		int opp_id,
1345		enum dc_color_space color_space,
1346		enum mpc_output_csc_mode ocsc_mode)
1347{
1348	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1349	uint32_t arr_size;
1350	struct color_matrices_reg ocsc_regs;
1351	const uint16_t *regval = NULL;
1352
1353	REG_WRITE(MPC_OUT_CSC_COEF_FORMAT, 0);
1354
1355	REG_SET(CSC_MODE[opp_id], 0, MPC_OCSC_MODE, ocsc_mode);
1356	if (ocsc_mode == MPC_OUTPUT_CSC_DISABLE)
1357		return;
1358
1359	regval = find_color_matrix(color_space, &arr_size);
1360
1361	if (regval == NULL) {
1362		BREAK_TO_DEBUGGER();
1363		return;
1364	}
1365
1366	ocsc_regs.shifts.csc_c11 = mpc30->mpc_shift->MPC_OCSC_C11_A;
1367	ocsc_regs.masks.csc_c11  = mpc30->mpc_mask->MPC_OCSC_C11_A;
1368	ocsc_regs.shifts.csc_c12 = mpc30->mpc_shift->MPC_OCSC_C12_A;
1369	ocsc_regs.masks.csc_c12 = mpc30->mpc_mask->MPC_OCSC_C12_A;
1370
1371
1372	if (ocsc_mode == MPC_OUTPUT_CSC_COEF_A) {
1373		ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_A[opp_id]);
1374		ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_A[opp_id]);
1375	} else {
1376		ocsc_regs.csc_c11_c12 = REG(CSC_C11_C12_B[opp_id]);
1377		ocsc_regs.csc_c33_c34 = REG(CSC_C33_C34_B[opp_id]);
1378	}
1379
1380	cm_helper_program_color_matrices(
1381			mpc30->base.ctx,
1382			regval,
1383			&ocsc_regs);
1384}
1385
1386void mpc3_set_rmu_mux(
1387	struct mpc *mpc,
1388	int rmu_idx,
1389	int value)
1390{
1391	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1392
1393	if (rmu_idx == 0)
1394		REG_UPDATE(MPC_RMU_CONTROL, MPC_RMU0_MUX, value);
1395	else if (rmu_idx == 1)
1396		REG_UPDATE(MPC_RMU_CONTROL, MPC_RMU1_MUX, value);
1397
1398}
1399
1400uint32_t mpc3_get_rmu_mux_status(
1401	struct mpc *mpc,
1402	int rmu_idx)
1403{
1404	uint32_t status = 0xf;
1405	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1406
1407	if (rmu_idx == 0)
1408		REG_GET(MPC_RMU_CONTROL, MPC_RMU0_MUX_STATUS, &status);
1409	else if (rmu_idx == 1)
1410		REG_GET(MPC_RMU_CONTROL, MPC_RMU1_MUX_STATUS, &status);
1411
1412	return status;
1413}
1414
1415uint32_t mpcc3_acquire_rmu(struct mpc *mpc, int mpcc_id, int rmu_idx)
1416{
1417	uint32_t rmu_status;
1418
1419	//determine if this mpcc is already multiplexed to an RMU unit
1420	rmu_status = mpc3_get_rmu_mux_status(mpc, rmu_idx);
1421	if (rmu_status == mpcc_id)
1422		//return rmu_idx of pre_acquired rmu unit
1423		return rmu_idx;
1424
1425	if (rmu_status == 0xf) {//rmu unit is disabled
1426		mpc3_set_rmu_mux(mpc, rmu_idx, mpcc_id);
1427		return rmu_idx;
1428	}
1429
1430	//no vacant RMU units or invalid parameters acquire_post_bldn_3dlut
1431	return -1;
1432}
1433
1434static int mpcc3_release_rmu(struct mpc *mpc, int mpcc_id)
1435{
1436	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1437	int rmu_idx;
1438	uint32_t rmu_status;
1439	int released_rmu = -1;
1440
1441	for (rmu_idx = 0; rmu_idx < mpc30->num_rmu; rmu_idx++) {
1442		rmu_status = mpc3_get_rmu_mux_status(mpc, rmu_idx);
1443		if (rmu_status == mpcc_id) {
1444			mpc3_set_rmu_mux(mpc, rmu_idx, 0xf);
1445			released_rmu = rmu_idx;
1446			break;
1447		}
1448	}
1449	return released_rmu;
1450
1451}
1452
1453static void mpc3_set_mpc_mem_lp_mode(struct mpc *mpc)
1454{
1455	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1456	int mpcc_id;
1457
1458	if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
1459		if (mpc30->mpc_mask->MPC_RMU0_MEM_LOW_PWR_MODE && mpc30->mpc_mask->MPC_RMU1_MEM_LOW_PWR_MODE) {
1460			REG_UPDATE(MPC_RMU_MEM_PWR_CTRL, MPC_RMU0_MEM_LOW_PWR_MODE, 3);
1461			REG_UPDATE(MPC_RMU_MEM_PWR_CTRL, MPC_RMU1_MEM_LOW_PWR_MODE, 3);
1462		}
1463
1464		if (mpc30->mpc_mask->MPCC_OGAM_MEM_LOW_PWR_MODE) {
1465			for (mpcc_id = 0; mpcc_id < mpc30->num_mpcc; mpcc_id++)
1466				REG_UPDATE(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_LOW_PWR_MODE, 3);
1467		}
1468	}
1469}
1470
1471static void mpc3_read_mpcc_state(
1472		struct mpc *mpc,
1473		int mpcc_inst,
1474		struct mpcc_state *s)
1475{
1476	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1477	uint32_t rmu_status = 0xf;
1478
1479	REG_GET(MPCC_OPP_ID[mpcc_inst], MPCC_OPP_ID, &s->opp_id);
1480	REG_GET(MPCC_TOP_SEL[mpcc_inst], MPCC_TOP_SEL, &s->dpp_id);
1481	REG_GET(MPCC_BOT_SEL[mpcc_inst], MPCC_BOT_SEL, &s->bot_mpcc_id);
1482	REG_GET_4(MPCC_CONTROL[mpcc_inst], MPCC_MODE, &s->mode,
1483			MPCC_ALPHA_BLND_MODE, &s->alpha_mode,
1484			MPCC_ALPHA_MULTIPLIED_MODE, &s->pre_multiplied_alpha,
1485			MPCC_BLND_ACTIVE_OVERLAP_ONLY, &s->overlap_only);
1486	REG_GET_2(MPCC_STATUS[mpcc_inst], MPCC_IDLE, &s->idle,
1487			MPCC_BUSY, &s->busy);
1488
1489	/* Color blocks state */
1490	REG_GET(MPC_RMU_CONTROL, MPC_RMU0_MUX_STATUS, &rmu_status);
1491
1492	if (rmu_status == mpcc_inst) {
1493		REG_GET(SHAPER_CONTROL[0],
1494			MPC_RMU_SHAPER_LUT_MODE_CURRENT, &s->shaper_lut_mode);
1495		REG_GET(RMU_3DLUT_MODE[0],
1496			MPC_RMU_3DLUT_MODE_CURRENT,  &s->lut3d_mode);
1497		REG_GET(RMU_3DLUT_READ_WRITE_CONTROL[0],
1498			MPC_RMU_3DLUT_30BIT_EN, &s->lut3d_bit_depth);
1499		REG_GET(RMU_3DLUT_MODE[0],
1500			MPC_RMU_3DLUT_SIZE, &s->lut3d_size);
1501	} else {
1502		REG_GET(SHAPER_CONTROL[1],
1503			MPC_RMU_SHAPER_LUT_MODE_CURRENT, &s->shaper_lut_mode);
1504		REG_GET(RMU_3DLUT_MODE[1],
1505			MPC_RMU_3DLUT_MODE_CURRENT,  &s->lut3d_mode);
1506		REG_GET(RMU_3DLUT_READ_WRITE_CONTROL[1],
1507			MPC_RMU_3DLUT_30BIT_EN, &s->lut3d_bit_depth);
1508		REG_GET(RMU_3DLUT_MODE[1],
1509			MPC_RMU_3DLUT_SIZE, &s->lut3d_size);
1510	}
1511
1512	REG_GET_2(MPCC_OGAM_CONTROL[mpcc_inst],
1513		  MPCC_OGAM_MODE_CURRENT, &s->rgam_mode,
1514		  MPCC_OGAM_SELECT_CURRENT, &s->rgam_lut);
1515}
1516
1517void mpc3_read_reg_state(
1518		struct mpc *mpc,
1519		int mpcc_inst, struct dcn_mpc_reg_state *mpc_reg_state)
1520{
1521	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
1522
1523	mpc_reg_state->mpcc_bot_sel = REG_READ(MPCC_BOT_SEL[mpcc_inst]);
1524	mpc_reg_state->mpcc_control = REG_READ(MPCC_CONTROL[mpcc_inst]);
1525	mpc_reg_state->mpcc_ogam_control = REG_READ(MPCC_OGAM_CONTROL[mpcc_inst]);
1526	mpc_reg_state->mpcc_opp_id = REG_READ(MPCC_OPP_ID[mpcc_inst]);
1527	mpc_reg_state->mpcc_status = REG_READ(MPCC_STATUS[mpcc_inst]);
1528	mpc_reg_state->mpcc_top_sel = REG_READ(MPCC_TOP_SEL[mpcc_inst]);
1529
1530}
1531
1532static const struct mpc_funcs dcn30_mpc_funcs = {
1533	.read_mpcc_state = mpc3_read_mpcc_state,
1534	.insert_plane = mpc1_insert_plane,
1535	.remove_mpcc = mpc1_remove_mpcc,
1536	.mpc_init = mpc3_mpc_init,
1537	.mpc_init_single_inst = mpc3_mpc_init_single_inst,
1538	.update_blending = mpc2_update_blending,
1539	.cursor_lock = mpc1_cursor_lock,
1540	.get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp,
1541	.wait_for_idle = mpc2_assert_idle_mpcc,
1542	.assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect,
1543	.init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw,
1544	.set_denorm =  mpc3_set_denorm,
1545	.set_denorm_clamp = mpc3_set_denorm_clamp,
1546	.set_output_csc = mpc3_set_output_csc,
1547	.set_ocsc_default = mpc3_set_ocsc_default,
1548	.set_output_gamma = mpc3_set_output_gamma,
1549	.insert_plane_to_secondary = NULL,
1550	.remove_mpcc_from_secondary =  NULL,
1551	.set_dwb_mux = mpc3_set_dwb_mux,
1552	.disable_dwb_mux = mpc3_disable_dwb_mux,
1553	.is_dwb_idle = mpc3_is_dwb_idle,
1554	.set_out_rate_control = mpc3_set_out_rate_control,
1555	.set_gamut_remap = mpc3_set_gamut_remap,
1556	.program_shaper = mpc3_program_shaper,
1557	.acquire_rmu = mpcc3_acquire_rmu,
1558	.program_3dlut = mpc3_program_3dlut,
1559	.release_rmu = mpcc3_release_rmu,
1560	.power_on_mpc_mem_pwr = mpc3_power_on_ogam_lut,
1561	.get_mpc_out_mux = mpc1_get_mpc_out_mux,
1562	.mpc_read_reg_state = mpc3_read_reg_state,
1563	.set_bg_color = mpc1_set_bg_color,
1564	.set_mpc_mem_lp_mode = mpc3_set_mpc_mem_lp_mode,
1565};
1566
1567void dcn30_mpc_construct(struct dcn30_mpc *mpc30,
1568	struct dc_context *ctx,
1569	const struct dcn30_mpc_registers *mpc_regs,
1570	const struct dcn30_mpc_shift *mpc_shift,
1571	const struct dcn30_mpc_mask *mpc_mask,
1572	int num_mpcc,
1573	int num_rmu)
1574{
1575	int i;
1576
1577	mpc30->base.ctx = ctx;
1578
1579	mpc30->base.funcs = &dcn30_mpc_funcs;
1580
1581	mpc30->mpc_regs = mpc_regs;
1582	mpc30->mpc_shift = mpc_shift;
1583	mpc30->mpc_mask = mpc_mask;
1584
1585	mpc30->mpcc_in_use_mask = 0;
1586	mpc30->num_mpcc = num_mpcc;
1587	mpc30->num_rmu = num_rmu;
1588
1589	for (i = 0; i < MAX_MPCC; i++)
1590		mpc3_init_mpcc(&mpc30->base.mpcc_array[i], i);
1591}
1592
~/ Read-only file preview.