Linux Audio

Check our new training course

Linux debugging, profiling, tracing and performance analysis training

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