Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
   1/*
   2 * Copyright 2021 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/dcn30_mpc.h"
  28#include "dcn30/dcn30_cm_common.h"
  29#include "dcn32_mpc.h"
  30#include "basics/conversion.h"
  31#include "dcn10/dcn10_cm_common.h"
  32#include "dc.h"
  33
  34#define REG(reg)\
  35	mpc30->mpc_regs->reg
  36
  37#define CTX \
  38	mpc30->base.ctx
  39
  40#undef FN
  41#define FN(reg_name, field_name) \
  42	mpc30->mpc_shift->field_name, mpc30->mpc_mask->field_name
  43
  44
  45void mpc32_mpc_init(struct mpc *mpc)
  46{
  47	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
  48	int mpcc_id;
  49
  50	mpc3_mpc_init(mpc);
  51
  52	if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
  53		if (mpc30->mpc_mask->MPCC_MCM_SHAPER_MEM_LOW_PWR_MODE && mpc30->mpc_mask->MPCC_MCM_3DLUT_MEM_LOW_PWR_MODE) {
  54			for (mpcc_id = 0; mpcc_id < mpc30->num_mpcc; mpcc_id++) {
  55				REG_UPDATE(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_SHAPER_MEM_LOW_PWR_MODE, 3);
  56				REG_UPDATE(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_3DLUT_MEM_LOW_PWR_MODE, 3);
  57				REG_UPDATE(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_1DLUT_MEM_LOW_PWR_MODE, 3);
  58			}
  59		}
  60		if (mpc30->mpc_mask->MPCC_OGAM_MEM_LOW_PWR_MODE) {
  61			for (mpcc_id = 0; mpcc_id < mpc30->num_mpcc; mpcc_id++)
  62				REG_UPDATE(MPCC_MEM_PWR_CTRL[mpcc_id], MPCC_OGAM_MEM_LOW_PWR_MODE, 3);
  63		}
  64	}
  65}
  66
  67void mpc32_power_on_blnd_lut(
  68	struct mpc *mpc,
  69	uint32_t mpcc_id,
  70	bool power_on)
  71{
  72	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
  73
  74	REG_SET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 0, MPCC_MCM_1DLUT_MEM_PWR_DIS, power_on);
  75
  76	if (mpc->ctx->dc->debug.enable_mem_low_power.bits.cm) {
  77		if (power_on) {
  78			REG_UPDATE(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_1DLUT_MEM_PWR_FORCE, 0);
  79			REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_1DLUT_MEM_PWR_STATE, 0, 1, 5);
  80		} else if (!mpc->ctx->dc->debug.disable_mem_low_power) {
  81			/* TODO: change to mpc
  82			 *  dpp_base->ctx->dc->optimized_required = true;
  83			 *  dpp_base->deferred_reg_writes.bits.disable_blnd_lut = true;
  84			 */
  85		}
  86	} else {
  87		REG_SET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 0,
  88				MPCC_MCM_1DLUT_MEM_PWR_FORCE, power_on == true ? 0 : 1);
  89	}
  90}
  91
  92static enum dc_lut_mode mpc32_get_post1dlut_current(struct mpc *mpc, uint32_t mpcc_id)
  93{
  94	enum dc_lut_mode mode;
  95	uint32_t mode_current = 0;
  96	uint32_t in_use = 0;
  97
  98	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
  99
 100	REG_GET(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
 101			MPCC_MCM_1DLUT_MODE_CURRENT, &mode_current);
 102	REG_GET(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
 103			MPCC_MCM_1DLUT_SELECT_CURRENT, &in_use);
 104
 105	switch (mode_current) {
 106	case 0:
 107	case 1:
 108		mode = LUT_BYPASS;
 109		break;
 110
 111	case 2:
 112		if (in_use == 0)
 113			mode = LUT_RAM_A;
 114		else
 115			mode = LUT_RAM_B;
 116		break;
 117	default:
 118		mode = LUT_BYPASS;
 119		break;
 120	}
 121	return mode;
 122}
 123
 124void mpc32_configure_post1dlut(
 125		struct mpc *mpc,
 126		uint32_t mpcc_id,
 127		bool is_ram_a)
 128{
 129	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 130
 131	//TODO: this
 132	REG_UPDATE_2(MPCC_MCM_1DLUT_LUT_CONTROL[mpcc_id],
 133			MPCC_MCM_1DLUT_LUT_WRITE_COLOR_MASK, 7,
 134			MPCC_MCM_1DLUT_LUT_HOST_SEL, is_ram_a == true ? 0 : 1);
 135
 136	REG_SET(MPCC_MCM_1DLUT_LUT_INDEX[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_INDEX, 0);
 137}
 138
 139static void mpc32_post1dlut_get_reg_field(
 140		struct dcn30_mpc *mpc,
 141		struct dcn3_xfer_func_reg *reg)
 142{
 143	reg->shifts.exp_region0_lut_offset = mpc->mpc_shift->MPCC_MCM_1DLUT_RAMA_EXP_REGION0_LUT_OFFSET;
 144	reg->masks.exp_region0_lut_offset = mpc->mpc_mask->MPCC_MCM_1DLUT_RAMA_EXP_REGION0_LUT_OFFSET;
 145	reg->shifts.exp_region0_num_segments = mpc->mpc_shift->MPCC_MCM_1DLUT_RAMA_EXP_REGION0_NUM_SEGMENTS;
 146	reg->masks.exp_region0_num_segments = mpc->mpc_mask->MPCC_MCM_1DLUT_RAMA_EXP_REGION0_NUM_SEGMENTS;
 147	reg->shifts.exp_region1_lut_offset = mpc->mpc_shift->MPCC_MCM_1DLUT_RAMA_EXP_REGION1_LUT_OFFSET;
 148	reg->masks.exp_region1_lut_offset = mpc->mpc_mask->MPCC_MCM_1DLUT_RAMA_EXP_REGION1_LUT_OFFSET;
 149	reg->shifts.exp_region1_num_segments = mpc->mpc_shift->MPCC_MCM_1DLUT_RAMA_EXP_REGION1_NUM_SEGMENTS;
 150	reg->masks.exp_region1_num_segments = mpc->mpc_mask->MPCC_MCM_1DLUT_RAMA_EXP_REGION1_NUM_SEGMENTS;
 151
 152	reg->shifts.field_region_end = mpc->mpc_shift->MPCC_MCM_1DLUT_RAMA_EXP_REGION_END_B;
 153	reg->masks.field_region_end = mpc->mpc_mask->MPCC_MCM_1DLUT_RAMA_EXP_REGION_END_B;
 154	reg->shifts.field_region_end_slope = mpc->mpc_shift->MPCC_MCM_1DLUT_RAMA_EXP_REGION_END_SLOPE_B;
 155	reg->masks.field_region_end_slope = mpc->mpc_mask->MPCC_MCM_1DLUT_RAMA_EXP_REGION_END_SLOPE_B;
 156	reg->shifts.field_region_end_base = mpc->mpc_shift->MPCC_MCM_1DLUT_RAMA_EXP_REGION_END_BASE_B;
 157	reg->masks.field_region_end_base = mpc->mpc_mask->MPCC_MCM_1DLUT_RAMA_EXP_REGION_END_BASE_B;
 158	reg->shifts.field_region_linear_slope = mpc->mpc_shift->MPCC_MCM_1DLUT_RAMA_EXP_REGION_START_SLOPE_B;
 159	reg->masks.field_region_linear_slope = mpc->mpc_mask->MPCC_MCM_1DLUT_RAMA_EXP_REGION_START_SLOPE_B;
 160	reg->shifts.exp_region_start = mpc->mpc_shift->MPCC_MCM_1DLUT_RAMA_EXP_REGION_START_B;
 161	reg->masks.exp_region_start = mpc->mpc_mask->MPCC_MCM_1DLUT_RAMA_EXP_REGION_START_B;
 162	reg->shifts.exp_resion_start_segment = mpc->mpc_shift->MPCC_MCM_1DLUT_RAMA_EXP_REGION_START_SEGMENT_B;
 163	reg->masks.exp_resion_start_segment = mpc->mpc_mask->MPCC_MCM_1DLUT_RAMA_EXP_REGION_START_SEGMENT_B;
 164}
 165
 166/*program blnd lut RAM A*/
 167void mpc32_program_post1dluta_settings(
 168		struct mpc *mpc,
 169		uint32_t mpcc_id,
 170		const struct pwl_params *params)
 171{
 172	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 173	struct dcn3_xfer_func_reg gam_regs;
 174
 175	mpc32_post1dlut_get_reg_field(mpc30, &gam_regs);
 176
 177	gam_regs.start_cntl_b = REG(MPCC_MCM_1DLUT_RAMA_START_CNTL_B[mpcc_id]);
 178	gam_regs.start_cntl_g = REG(MPCC_MCM_1DLUT_RAMA_START_CNTL_G[mpcc_id]);
 179	gam_regs.start_cntl_r = REG(MPCC_MCM_1DLUT_RAMA_START_CNTL_R[mpcc_id]);
 180	gam_regs.start_slope_cntl_b = REG(MPCC_MCM_1DLUT_RAMA_START_SLOPE_CNTL_B[mpcc_id]);
 181	gam_regs.start_slope_cntl_g = REG(MPCC_MCM_1DLUT_RAMA_START_SLOPE_CNTL_G[mpcc_id]);
 182	gam_regs.start_slope_cntl_r = REG(MPCC_MCM_1DLUT_RAMA_START_SLOPE_CNTL_R[mpcc_id]);
 183	gam_regs.start_end_cntl1_b = REG(MPCC_MCM_1DLUT_RAMA_END_CNTL1_B[mpcc_id]);
 184	gam_regs.start_end_cntl2_b = REG(MPCC_MCM_1DLUT_RAMA_END_CNTL2_B[mpcc_id]);
 185	gam_regs.start_end_cntl1_g = REG(MPCC_MCM_1DLUT_RAMA_END_CNTL1_G[mpcc_id]);
 186	gam_regs.start_end_cntl2_g = REG(MPCC_MCM_1DLUT_RAMA_END_CNTL2_G[mpcc_id]);
 187	gam_regs.start_end_cntl1_r = REG(MPCC_MCM_1DLUT_RAMA_END_CNTL1_R[mpcc_id]);
 188	gam_regs.start_end_cntl2_r = REG(MPCC_MCM_1DLUT_RAMA_END_CNTL2_R[mpcc_id]);
 189	gam_regs.region_start = REG(MPCC_MCM_1DLUT_RAMA_REGION_0_1[mpcc_id]);
 190	gam_regs.region_end = REG(MPCC_MCM_1DLUT_RAMA_REGION_32_33[mpcc_id]);
 191
 192	cm_helper_program_gamcor_xfer_func(mpc->ctx, params, &gam_regs);
 193}
 194
 195/*program blnd lut RAM B*/
 196void mpc32_program_post1dlutb_settings(
 197		struct mpc *mpc,
 198		uint32_t mpcc_id,
 199		const struct pwl_params *params)
 200{
 201	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 202	struct dcn3_xfer_func_reg gam_regs;
 203
 204	mpc32_post1dlut_get_reg_field(mpc30, &gam_regs);
 205
 206	gam_regs.start_cntl_b = REG(MPCC_MCM_1DLUT_RAMB_START_CNTL_B[mpcc_id]);
 207	gam_regs.start_cntl_g = REG(MPCC_MCM_1DLUT_RAMB_START_CNTL_G[mpcc_id]);
 208	gam_regs.start_cntl_r = REG(MPCC_MCM_1DLUT_RAMB_START_CNTL_R[mpcc_id]);
 209	gam_regs.start_slope_cntl_b = REG(MPCC_MCM_1DLUT_RAMB_START_SLOPE_CNTL_B[mpcc_id]);
 210	gam_regs.start_slope_cntl_g = REG(MPCC_MCM_1DLUT_RAMB_START_SLOPE_CNTL_G[mpcc_id]);
 211	gam_regs.start_slope_cntl_r = REG(MPCC_MCM_1DLUT_RAMB_START_SLOPE_CNTL_R[mpcc_id]);
 212	gam_regs.start_end_cntl1_b = REG(MPCC_MCM_1DLUT_RAMB_END_CNTL1_B[mpcc_id]);
 213	gam_regs.start_end_cntl2_b = REG(MPCC_MCM_1DLUT_RAMB_END_CNTL2_B[mpcc_id]);
 214	gam_regs.start_end_cntl1_g = REG(MPCC_MCM_1DLUT_RAMB_END_CNTL1_G[mpcc_id]);
 215	gam_regs.start_end_cntl2_g = REG(MPCC_MCM_1DLUT_RAMB_END_CNTL2_G[mpcc_id]);
 216	gam_regs.start_end_cntl1_r = REG(MPCC_MCM_1DLUT_RAMB_END_CNTL1_R[mpcc_id]);
 217	gam_regs.start_end_cntl2_r = REG(MPCC_MCM_1DLUT_RAMB_END_CNTL2_R[mpcc_id]);
 218	gam_regs.region_start = REG(MPCC_MCM_1DLUT_RAMB_REGION_0_1[mpcc_id]);
 219	gam_regs.region_end = REG(MPCC_MCM_1DLUT_RAMB_REGION_32_33[mpcc_id]);
 220
 221	cm_helper_program_gamcor_xfer_func(mpc->ctx, params, &gam_regs);
 222}
 223
 224void mpc32_program_post1dlut_pwl(
 225		struct mpc *mpc,
 226		uint32_t mpcc_id,
 227		const struct pwl_result_data *rgb,
 228		uint32_t num)
 229{
 230	uint32_t i;
 231	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 232	uint32_t last_base_value_red = rgb[num-1].red_reg + rgb[num-1].delta_red_reg;
 233	uint32_t last_base_value_green = rgb[num-1].green_reg + rgb[num-1].delta_green_reg;
 234	uint32_t last_base_value_blue = rgb[num-1].blue_reg + rgb[num-1].delta_blue_reg;
 235
 236	if (is_rgb_equal(rgb, num)) {
 237		for (i = 0 ; i < num; i++)
 238			REG_SET(MPCC_MCM_1DLUT_LUT_DATA[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_DATA, rgb[i].red_reg);
 239		REG_SET(MPCC_MCM_1DLUT_LUT_DATA[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_DATA, last_base_value_red);
 240	} else {
 241		REG_SET(MPCC_MCM_1DLUT_LUT_INDEX[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_INDEX, 0);
 242		REG_UPDATE(MPCC_MCM_1DLUT_LUT_CONTROL[mpcc_id], MPCC_MCM_1DLUT_LUT_WRITE_COLOR_MASK, 4);
 243		for (i = 0 ; i < num; i++)
 244			REG_SET(MPCC_MCM_1DLUT_LUT_DATA[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_DATA, rgb[i].red_reg);
 245		REG_SET(MPCC_MCM_1DLUT_LUT_DATA[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_DATA, last_base_value_red);
 246
 247		REG_SET(MPCC_MCM_1DLUT_LUT_INDEX[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_INDEX, 0);
 248		REG_UPDATE(MPCC_MCM_1DLUT_LUT_CONTROL[mpcc_id], MPCC_MCM_1DLUT_LUT_WRITE_COLOR_MASK, 2);
 249		for (i = 0 ; i < num; i++)
 250			REG_SET(MPCC_MCM_1DLUT_LUT_DATA[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_DATA, rgb[i].green_reg);
 251		REG_SET(MPCC_MCM_1DLUT_LUT_DATA[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_DATA, last_base_value_green);
 252
 253		REG_SET(MPCC_MCM_1DLUT_LUT_INDEX[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_INDEX, 0);
 254		REG_UPDATE(MPCC_MCM_1DLUT_LUT_CONTROL[mpcc_id], MPCC_MCM_1DLUT_LUT_WRITE_COLOR_MASK, 1);
 255		for (i = 0 ; i < num; i++)
 256			REG_SET(MPCC_MCM_1DLUT_LUT_DATA[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_DATA, rgb[i].blue_reg);
 257		REG_SET(MPCC_MCM_1DLUT_LUT_DATA[mpcc_id], 0, MPCC_MCM_1DLUT_LUT_DATA, last_base_value_blue);
 258	}
 259}
 260
 261bool mpc32_program_post1dlut(
 262		struct mpc *mpc,
 263		const struct pwl_params *params,
 264		uint32_t mpcc_id)
 265{
 266	enum dc_lut_mode current_mode;
 267	enum dc_lut_mode next_mode;
 268	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 269
 270	if (params == NULL) {
 271		REG_SET(MPCC_MCM_1DLUT_CONTROL[mpcc_id], 0, MPCC_MCM_1DLUT_MODE, 0);
 272		if (mpc->ctx->dc->debug.enable_mem_low_power.bits.cm)
 273			mpc32_power_on_blnd_lut(mpc, mpcc_id, false);
 274		return false;
 275	}
 276
 277	current_mode = mpc32_get_post1dlut_current(mpc, mpcc_id);
 278	if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_B)
 279		next_mode = LUT_RAM_A;
 280	else
 281		next_mode = LUT_RAM_B;
 282
 283	mpc32_power_on_blnd_lut(mpc, mpcc_id, true);
 284	mpc32_configure_post1dlut(mpc, mpcc_id, next_mode == LUT_RAM_A);
 285
 286	if (next_mode == LUT_RAM_A)
 287		mpc32_program_post1dluta_settings(mpc, mpcc_id, params);
 288	else
 289		mpc32_program_post1dlutb_settings(mpc, mpcc_id, params);
 290
 291	mpc32_program_post1dlut_pwl(
 292			mpc, mpcc_id, params->rgb_resulted, params->hw_points_num);
 293
 294	REG_UPDATE_2(MPCC_MCM_1DLUT_CONTROL[mpcc_id],
 295			MPCC_MCM_1DLUT_MODE, 2,
 296			MPCC_MCM_1DLUT_SELECT, next_mode == LUT_RAM_A ? 0 : 1);
 297
 298	return true;
 299}
 300
 301static enum dc_lut_mode mpc32_get_shaper_current(struct mpc *mpc, uint32_t mpcc_id)
 302{
 303	enum dc_lut_mode mode;
 304	uint32_t state_mode;
 305	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 306
 307	REG_GET(MPCC_MCM_SHAPER_CONTROL[mpcc_id], MPCC_MCM_SHAPER_MODE_CURRENT, &state_mode);
 308
 309	switch (state_mode) {
 310	case 0:
 311		mode = LUT_BYPASS;
 312		break;
 313	case 1:
 314		mode = LUT_RAM_A;
 315		break;
 316	case 2:
 317		mode = LUT_RAM_B;
 318		break;
 319	default:
 320		mode = LUT_BYPASS;
 321		break;
 322	}
 323
 324	return mode;
 325}
 326
 327
 328void mpc32_configure_shaper_lut(
 329		struct mpc *mpc,
 330		bool is_ram_a,
 331		uint32_t mpcc_id)
 332{
 333	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 334
 335	REG_UPDATE(MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK[mpcc_id],
 336			MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK, 7);
 337	REG_UPDATE(MPCC_MCM_SHAPER_LUT_WRITE_EN_MASK[mpcc_id],
 338			MPCC_MCM_SHAPER_LUT_WRITE_SEL, is_ram_a == true ? 0:1);
 339	REG_SET(MPCC_MCM_SHAPER_LUT_INDEX[mpcc_id], 0, MPCC_MCM_SHAPER_LUT_INDEX, 0);
 340}
 341
 342
 343void mpc32_program_shaper_luta_settings(
 344		struct mpc *mpc,
 345		const struct pwl_params *params,
 346		uint32_t mpcc_id)
 347{
 348	const struct gamma_curve *curve;
 349	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 350
 351	REG_SET_2(MPCC_MCM_SHAPER_RAMA_START_CNTL_B[mpcc_id], 0,
 352		MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
 353		MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 354	REG_SET_2(MPCC_MCM_SHAPER_RAMA_START_CNTL_G[mpcc_id], 0,
 355			MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].green.custom_float_x,
 356			MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 357	REG_SET_2(MPCC_MCM_SHAPER_RAMA_START_CNTL_R[mpcc_id], 0,
 358			MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].red.custom_float_x,
 359			MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 360
 361	REG_SET_2(MPCC_MCM_SHAPER_RAMA_END_CNTL_B[mpcc_id], 0,
 362			MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
 363			MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
 364	REG_SET_2(MPCC_MCM_SHAPER_RAMA_END_CNTL_G[mpcc_id], 0,
 365			MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].green.custom_float_x,
 366			MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].green.custom_float_y);
 367	REG_SET_2(MPCC_MCM_SHAPER_RAMA_END_CNTL_R[mpcc_id], 0,
 368			MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].red.custom_float_x,
 369			MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].red.custom_float_y);
 370
 371	curve = params->arr_curve_points;
 372	REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_0_1[mpcc_id], 0,
 373		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 374		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 375		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 376		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 377
 378	curve += 2;
 379	REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_2_3[mpcc_id], 0,
 380		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 381		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 382		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 383		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 384
 385	curve += 2;
 386	REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_4_5[mpcc_id], 0,
 387		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 388		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 389		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 390		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 391
 392	curve += 2;
 393	REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_6_7[mpcc_id], 0,
 394		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 395		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 396		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 397		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 398
 399	curve += 2;
 400	REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_8_9[mpcc_id], 0,
 401		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 402		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 403		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 404		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 405
 406	curve += 2;
 407	REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_10_11[mpcc_id], 0,
 408		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 409		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 410		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 411		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 412
 413	curve += 2;
 414	REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_12_13[mpcc_id], 0,
 415		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 416		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 417		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 418		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 419
 420	curve += 2;
 421	REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_14_15[mpcc_id], 0,
 422		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 423		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 424		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 425		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 426
 427
 428	curve += 2;
 429	REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_16_17[mpcc_id], 0,
 430		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 431		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 432		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 433		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 434
 435	curve += 2;
 436	REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_18_19[mpcc_id], 0,
 437		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 438		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 439		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 440		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 441
 442	curve += 2;
 443	REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_20_21[mpcc_id], 0,
 444		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 445		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 446		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 447		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 448
 449	curve += 2;
 450	REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_22_23[mpcc_id], 0,
 451		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 452		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 453		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 454		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 455
 456	curve += 2;
 457	REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_24_25[mpcc_id], 0,
 458		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 459		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 460		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 461		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 462
 463	curve += 2;
 464	REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_26_27[mpcc_id], 0,
 465			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 466			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 467			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 468			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 469
 470	curve += 2;
 471	REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_28_29[mpcc_id], 0,
 472		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 473		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 474		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 475		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 476
 477	curve += 2;
 478	REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_30_31[mpcc_id], 0,
 479		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 480		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 481		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 482		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 483
 484	curve += 2;
 485	REG_SET_4(MPCC_MCM_SHAPER_RAMA_REGION_32_33[mpcc_id], 0,
 486		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 487		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 488		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 489		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 490}
 491
 492
 493void mpc32_program_shaper_lutb_settings(
 494		struct mpc *mpc,
 495		const struct pwl_params *params,
 496		uint32_t mpcc_id)
 497{
 498	const struct gamma_curve *curve;
 499	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 500
 501	REG_SET_2(MPCC_MCM_SHAPER_RAMB_START_CNTL_B[mpcc_id], 0,
 502		MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].blue.custom_float_x,
 503		MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 504	REG_SET_2(MPCC_MCM_SHAPER_RAMB_START_CNTL_G[mpcc_id], 0,
 505			MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].green.custom_float_x,
 506			MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 507	REG_SET_2(MPCC_MCM_SHAPER_RAMB_START_CNTL_R[mpcc_id], 0,
 508			MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_B, params->corner_points[0].red.custom_float_x,
 509			MPCC_MCM_SHAPER_RAMA_EXP_REGION_START_SEGMENT_B, 0);
 510
 511	REG_SET_2(MPCC_MCM_SHAPER_RAMB_END_CNTL_B[mpcc_id], 0,
 512			MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].blue.custom_float_x,
 513			MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].blue.custom_float_y);
 514	REG_SET_2(MPCC_MCM_SHAPER_RAMB_END_CNTL_G[mpcc_id], 0,
 515			MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].green.custom_float_x,
 516			MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].green.custom_float_y);
 517	REG_SET_2(MPCC_MCM_SHAPER_RAMB_END_CNTL_R[mpcc_id], 0,
 518			MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_B, params->corner_points[1].red.custom_float_x,
 519			MPCC_MCM_SHAPER_RAMA_EXP_REGION_END_BASE_B, params->corner_points[1].red.custom_float_y);
 520
 521	curve = params->arr_curve_points;
 522	REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_0_1[mpcc_id], 0,
 523		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 524		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 525		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 526		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 527
 528	curve += 2;
 529	REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_2_3[mpcc_id], 0,
 530			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 531			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 532			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 533			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 534
 535
 536	curve += 2;
 537	REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_4_5[mpcc_id], 0,
 538			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 539			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 540			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 541			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 542
 543	curve += 2;
 544	REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_6_7[mpcc_id], 0,
 545			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 546			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 547			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 548			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 549
 550	curve += 2;
 551	REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_8_9[mpcc_id], 0,
 552		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 553		MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 554		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 555		MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 556
 557	curve += 2;
 558	REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_10_11[mpcc_id], 0,
 559			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 560			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 561			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 562			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 563
 564	curve += 2;
 565	REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_12_13[mpcc_id], 0,
 566			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 567			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 568			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 569			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 570
 571	curve += 2;
 572	REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_14_15[mpcc_id], 0,
 573			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 574			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 575			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 576			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 577
 578
 579	curve += 2;
 580	REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_16_17[mpcc_id], 0,
 581			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 582			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 583			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 584			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 585
 586	curve += 2;
 587	REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_18_19[mpcc_id], 0,
 588			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 589			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 590			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 591			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 592
 593	curve += 2;
 594	REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_20_21[mpcc_id], 0,
 595			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 596			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 597			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 598			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 599
 600	curve += 2;
 601	REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_22_23[mpcc_id], 0,
 602			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 603			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 604			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 605			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 606
 607	curve += 2;
 608	REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_24_25[mpcc_id], 0,
 609			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 610			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 611			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 612			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 613
 614	curve += 2;
 615	REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_26_27[mpcc_id], 0,
 616			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 617			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 618			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 619			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 620
 621	curve += 2;
 622	REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_28_29[mpcc_id], 0,
 623			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 624			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 625			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 626			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 627
 628	curve += 2;
 629	REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_30_31[mpcc_id], 0,
 630			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 631			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 632			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 633			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 634
 635	curve += 2;
 636	REG_SET_4(MPCC_MCM_SHAPER_RAMB_REGION_32_33[mpcc_id], 0,
 637			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_LUT_OFFSET, curve[0].offset,
 638			MPCC_MCM_SHAPER_RAMA_EXP_REGION0_NUM_SEGMENTS, curve[0].segments_num,
 639			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_LUT_OFFSET, curve[1].offset,
 640			MPCC_MCM_SHAPER_RAMA_EXP_REGION1_NUM_SEGMENTS, curve[1].segments_num);
 641}
 642
 643
 644void mpc32_program_shaper_lut(
 645		struct mpc *mpc,
 646		const struct pwl_result_data *rgb,
 647		uint32_t num,
 648		uint32_t mpcc_id)
 649{
 650	uint32_t i, red, green, blue;
 651	uint32_t  red_delta, green_delta, blue_delta;
 652	uint32_t  red_value, green_value, blue_value;
 653
 654	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 655
 656	for (i = 0 ; i < num; i++) {
 657
 658		red   = rgb[i].red_reg;
 659		green = rgb[i].green_reg;
 660		blue  = rgb[i].blue_reg;
 661
 662		red_delta   = rgb[i].delta_red_reg;
 663		green_delta = rgb[i].delta_green_reg;
 664		blue_delta  = rgb[i].delta_blue_reg;
 665
 666		red_value   = ((red_delta   & 0x3ff) << 14) | (red   & 0x3fff);
 667		green_value = ((green_delta & 0x3ff) << 14) | (green & 0x3fff);
 668		blue_value  = ((blue_delta  & 0x3ff) << 14) | (blue  & 0x3fff);
 669
 670		REG_SET(MPCC_MCM_SHAPER_LUT_DATA[mpcc_id], 0, MPCC_MCM_SHAPER_LUT_DATA, red_value);
 671		REG_SET(MPCC_MCM_SHAPER_LUT_DATA[mpcc_id], 0, MPCC_MCM_SHAPER_LUT_DATA, green_value);
 672		REG_SET(MPCC_MCM_SHAPER_LUT_DATA[mpcc_id], 0, MPCC_MCM_SHAPER_LUT_DATA, blue_value);
 673	}
 674
 675}
 676
 677
 678void mpc32_power_on_shaper_3dlut(
 679		struct mpc *mpc,
 680		uint32_t mpcc_id,
 681		bool power_on)
 682{
 683	uint32_t power_status_shaper = 2;
 684	uint32_t power_status_3dlut  = 2;
 685	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 686	int max_retries = 10;
 687
 688	REG_SET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], 0,
 689	MPCC_MCM_3DLUT_MEM_PWR_DIS, power_on == true ? 1:0);
 690	/* wait for memory to fully power up */
 691	if (power_on && mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) {
 692		REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_SHAPER_MEM_PWR_STATE, 0, 1, max_retries);
 693		REG_WAIT(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_3DLUT_MEM_PWR_STATE, 0, 1, max_retries);
 694	}
 695
 696	/*read status is not mandatory, it is just for debugging*/
 697	REG_GET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_SHAPER_MEM_PWR_STATE, &power_status_shaper);
 698	REG_GET(MPCC_MCM_MEM_PWR_CTRL[mpcc_id], MPCC_MCM_3DLUT_MEM_PWR_STATE, &power_status_3dlut);
 699
 700	if (power_status_shaper != 0 && power_on == true)
 701		BREAK_TO_DEBUGGER();
 702
 703	if (power_status_3dlut != 0 && power_on == true)
 704		BREAK_TO_DEBUGGER();
 705}
 706
 707
 708bool mpc32_program_shaper(
 709		struct mpc *mpc,
 710		const struct pwl_params *params,
 711		uint32_t mpcc_id)
 712{
 713	enum dc_lut_mode current_mode;
 714	enum dc_lut_mode next_mode;
 715
 716	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 717
 718	if (params == NULL) {
 719		REG_SET(MPCC_MCM_SHAPER_CONTROL[mpcc_id], 0, MPCC_MCM_SHAPER_LUT_MODE, 0);
 720		return false;
 721	}
 722
 723	if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
 724		mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true);
 725
 726	current_mode = mpc32_get_shaper_current(mpc, mpcc_id);
 727
 728	if (current_mode == LUT_BYPASS || current_mode == LUT_RAM_A)
 729		next_mode = LUT_RAM_B;
 730	else
 731		next_mode = LUT_RAM_A;
 732
 733	mpc32_configure_shaper_lut(mpc, next_mode == LUT_RAM_A, mpcc_id);
 734
 735	if (next_mode == LUT_RAM_A)
 736		mpc32_program_shaper_luta_settings(mpc, params, mpcc_id);
 737	else
 738		mpc32_program_shaper_lutb_settings(mpc, params, mpcc_id);
 739
 740	mpc32_program_shaper_lut(
 741			mpc, params->rgb_resulted, params->hw_points_num, mpcc_id);
 742
 743	REG_SET(MPCC_MCM_SHAPER_CONTROL[mpcc_id], 0, MPCC_MCM_SHAPER_LUT_MODE, next_mode == LUT_RAM_A ? 1:2);
 744	mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false);
 745
 746	return true;
 747}
 748
 749
 750static enum dc_lut_mode get3dlut_config(
 751			struct mpc *mpc,
 752			bool *is_17x17x17,
 753			bool *is_12bits_color_channel,
 754			int mpcc_id)
 755{
 756	uint32_t i_mode, i_enable_10bits, lut_size;
 757	enum dc_lut_mode mode;
 758	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 759
 760	REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id],
 761			MPCC_MCM_3DLUT_MODE_CURRENT,  &i_mode);
 762
 763	REG_GET(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
 764			MPCC_MCM_3DLUT_30BIT_EN, &i_enable_10bits);
 765
 766	switch (i_mode) {
 767	case 0:
 768		mode = LUT_BYPASS;
 769		break;
 770	case 1:
 771		mode = LUT_RAM_A;
 772		break;
 773	case 2:
 774		mode = LUT_RAM_B;
 775		break;
 776	default:
 777		mode = LUT_BYPASS;
 778		break;
 779	}
 780	if (i_enable_10bits > 0)
 781		*is_12bits_color_channel = false;
 782	else
 783		*is_12bits_color_channel = true;
 784
 785	REG_GET(MPCC_MCM_3DLUT_MODE[mpcc_id], MPCC_MCM_3DLUT_SIZE, &lut_size);
 786
 787	if (lut_size == 0)
 788		*is_17x17x17 = true;
 789	else
 790		*is_17x17x17 = false;
 791
 792	return mode;
 793}
 794
 795
 796void mpc32_select_3dlut_ram(
 797		struct mpc *mpc,
 798		enum dc_lut_mode mode,
 799		bool is_color_channel_12bits,
 800		uint32_t mpcc_id)
 801{
 802	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 803
 804	REG_UPDATE_2(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id],
 805		MPCC_MCM_3DLUT_RAM_SEL, mode == LUT_RAM_A ? 0 : 1,
 806		MPCC_MCM_3DLUT_30BIT_EN, is_color_channel_12bits == true ? 0:1);
 807}
 808
 809
 810void mpc32_select_3dlut_ram_mask(
 811		struct mpc *mpc,
 812		uint32_t ram_selection_mask,
 813		uint32_t mpcc_id)
 814{
 815	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 816
 817	REG_UPDATE(MPCC_MCM_3DLUT_READ_WRITE_CONTROL[mpcc_id], MPCC_MCM_3DLUT_WRITE_EN_MASK,
 818			ram_selection_mask);
 819	REG_SET(MPCC_MCM_3DLUT_INDEX[mpcc_id], 0, MPCC_MCM_3DLUT_INDEX, 0);
 820}
 821
 822
 823void mpc32_set3dlut_ram12(
 824		struct mpc *mpc,
 825		const struct dc_rgb *lut,
 826		uint32_t entries,
 827		uint32_t mpcc_id)
 828{
 829	uint32_t i, red, green, blue, red1, green1, blue1;
 830	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 831
 832	for (i = 0 ; i < entries; i += 2) {
 833		red   = lut[i].red<<4;
 834		green = lut[i].green<<4;
 835		blue  = lut[i].blue<<4;
 836		red1   = lut[i+1].red<<4;
 837		green1 = lut[i+1].green<<4;
 838		blue1  = lut[i+1].blue<<4;
 839
 840		REG_SET_2(MPCC_MCM_3DLUT_DATA[mpcc_id], 0,
 841				MPCC_MCM_3DLUT_DATA0, red,
 842				MPCC_MCM_3DLUT_DATA1, red1);
 843
 844		REG_SET_2(MPCC_MCM_3DLUT_DATA[mpcc_id], 0,
 845				MPCC_MCM_3DLUT_DATA0, green,
 846				MPCC_MCM_3DLUT_DATA1, green1);
 847
 848		REG_SET_2(MPCC_MCM_3DLUT_DATA[mpcc_id], 0,
 849				MPCC_MCM_3DLUT_DATA0, blue,
 850				MPCC_MCM_3DLUT_DATA1, blue1);
 851	}
 852}
 853
 854
 855void mpc32_set3dlut_ram10(
 856		struct mpc *mpc,
 857		const struct dc_rgb *lut,
 858		uint32_t entries,
 859		uint32_t mpcc_id)
 860{
 861	uint32_t i, red, green, blue, value;
 862	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 863
 864	for (i = 0; i < entries; i++) {
 865		red   = lut[i].red;
 866		green = lut[i].green;
 867		blue  = lut[i].blue;
 868		//should we shift red 22bit and green 12?
 869		value = (red<<20) | (green<<10) | blue;
 870
 871		REG_SET(MPCC_MCM_3DLUT_DATA_30BIT[mpcc_id], 0, MPCC_MCM_3DLUT_DATA_30BIT, value);
 872	}
 873
 874}
 875
 876
 877static void mpc32_set_3dlut_mode(
 878		struct mpc *mpc,
 879		enum dc_lut_mode mode,
 880		bool is_color_channel_12bits,
 881		bool is_lut_size17x17x17,
 882		uint32_t mpcc_id)
 883{
 884	uint32_t lut_mode;
 885	struct dcn30_mpc *mpc30 = TO_DCN30_MPC(mpc);
 886
 887	// set default 3DLUT to pre-blend
 888	// TODO: implement movable CM location
 889	REG_UPDATE(MPCC_MOVABLE_CM_LOCATION_CONTROL[mpcc_id], MPCC_MOVABLE_CM_LOCATION_CNTL, 0);
 890
 891	if (mode == LUT_BYPASS)
 892		lut_mode = 0;
 893	else if (mode == LUT_RAM_A)
 894		lut_mode = 1;
 895	else
 896		lut_mode = 2;
 897
 898	REG_UPDATE_2(MPCC_MCM_3DLUT_MODE[mpcc_id],
 899			MPCC_MCM_3DLUT_MODE, lut_mode,
 900			MPCC_MCM_3DLUT_SIZE, is_lut_size17x17x17 == true ? 0 : 1);
 901}
 902
 903
 904bool mpc32_program_3dlut(
 905		struct mpc *mpc,
 906		const struct tetrahedral_params *params,
 907		int mpcc_id)
 908{
 909	enum dc_lut_mode mode;
 910	bool is_17x17x17;
 911	bool is_12bits_color_channel;
 912	const struct dc_rgb *lut0;
 913	const struct dc_rgb *lut1;
 914	const struct dc_rgb *lut2;
 915	const struct dc_rgb *lut3;
 916	int lut_size0;
 917	int lut_size;
 918
 919	if (params == NULL) {
 920		mpc32_set_3dlut_mode(mpc, LUT_BYPASS, false, false, mpcc_id);
 921		return false;
 922	}
 923	mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true);
 924
 925	mode = get3dlut_config(mpc, &is_17x17x17, &is_12bits_color_channel, mpcc_id);
 926
 927	if (mode == LUT_BYPASS || mode == LUT_RAM_B)
 928		mode = LUT_RAM_A;
 929	else
 930		mode = LUT_RAM_B;
 931
 932	is_17x17x17 = !params->use_tetrahedral_9;
 933	is_12bits_color_channel = params->use_12bits;
 934	if (is_17x17x17) {
 935		lut0 = params->tetrahedral_17.lut0;
 936		lut1 = params->tetrahedral_17.lut1;
 937		lut2 = params->tetrahedral_17.lut2;
 938		lut3 = params->tetrahedral_17.lut3;
 939		lut_size0 = sizeof(params->tetrahedral_17.lut0)/
 940					sizeof(params->tetrahedral_17.lut0[0]);
 941		lut_size  = sizeof(params->tetrahedral_17.lut1)/
 942					sizeof(params->tetrahedral_17.lut1[0]);
 943	} else {
 944		lut0 = params->tetrahedral_9.lut0;
 945		lut1 = params->tetrahedral_9.lut1;
 946		lut2 = params->tetrahedral_9.lut2;
 947		lut3 = params->tetrahedral_9.lut3;
 948		lut_size0 = sizeof(params->tetrahedral_9.lut0)/
 949				sizeof(params->tetrahedral_9.lut0[0]);
 950		lut_size  = sizeof(params->tetrahedral_9.lut1)/
 951				sizeof(params->tetrahedral_9.lut1[0]);
 952		}
 953
 954	mpc32_select_3dlut_ram(mpc, mode,
 955				is_12bits_color_channel, mpcc_id);
 956	mpc32_select_3dlut_ram_mask(mpc, 0x1, mpcc_id);
 957	if (is_12bits_color_channel)
 958		mpc32_set3dlut_ram12(mpc, lut0, lut_size0, mpcc_id);
 959	else
 960		mpc32_set3dlut_ram10(mpc, lut0, lut_size0, mpcc_id);
 961
 962	mpc32_select_3dlut_ram_mask(mpc, 0x2, mpcc_id);
 963	if (is_12bits_color_channel)
 964		mpc32_set3dlut_ram12(mpc, lut1, lut_size, mpcc_id);
 965	else
 966		mpc32_set3dlut_ram10(mpc, lut1, lut_size, mpcc_id);
 967
 968	mpc32_select_3dlut_ram_mask(mpc, 0x4, mpcc_id);
 969	if (is_12bits_color_channel)
 970		mpc32_set3dlut_ram12(mpc, lut2, lut_size, mpcc_id);
 971	else
 972		mpc32_set3dlut_ram10(mpc, lut2, lut_size, mpcc_id);
 973
 974	mpc32_select_3dlut_ram_mask(mpc, 0x8, mpcc_id);
 975	if (is_12bits_color_channel)
 976		mpc32_set3dlut_ram12(mpc, lut3, lut_size, mpcc_id);
 977	else
 978		mpc32_set3dlut_ram10(mpc, lut3, lut_size, mpcc_id);
 979
 980	mpc32_set_3dlut_mode(mpc, mode, is_12bits_color_channel,
 981					is_17x17x17, mpcc_id);
 982
 983	if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc)
 984		mpc32_power_on_shaper_3dlut(mpc, mpcc_id, false);
 985
 986	return true;
 987}
 988
 989static const struct mpc_funcs dcn32_mpc_funcs = {
 990	.read_mpcc_state = mpc1_read_mpcc_state,
 991	.insert_plane = mpc1_insert_plane,
 992	.remove_mpcc = mpc1_remove_mpcc,
 993	.mpc_init = mpc32_mpc_init,
 994	.mpc_init_single_inst = mpc3_mpc_init_single_inst,
 995	.update_blending = mpc2_update_blending,
 996	.cursor_lock = mpc1_cursor_lock,
 997	.get_mpcc_for_dpp = mpc1_get_mpcc_for_dpp,
 998	.wait_for_idle = mpc2_assert_idle_mpcc,
 999	.assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect,
1000	.init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw,
1001	.set_denorm =  mpc3_set_denorm,
1002	.set_denorm_clamp = mpc3_set_denorm_clamp,
1003	.set_output_csc = mpc3_set_output_csc,
1004	.set_ocsc_default = mpc3_set_ocsc_default,
1005	.set_output_gamma = mpc3_set_output_gamma,
1006	.insert_plane_to_secondary = NULL,
1007	.remove_mpcc_from_secondary =  NULL,
1008	.set_dwb_mux = mpc3_set_dwb_mux,
1009	.disable_dwb_mux = mpc3_disable_dwb_mux,
1010	.is_dwb_idle = mpc3_is_dwb_idle,
1011	.set_gamut_remap = mpc3_set_gamut_remap,
1012	.program_shaper = mpc32_program_shaper,
1013	.program_3dlut = mpc32_program_3dlut,
1014	.program_1dlut = mpc32_program_post1dlut,
1015	.acquire_rmu = NULL,
1016	.release_rmu = NULL,
1017	.power_on_mpc_mem_pwr = mpc3_power_on_ogam_lut,
1018	.get_mpc_out_mux = mpc1_get_mpc_out_mux,
1019	.set_bg_color = mpc1_set_bg_color,
1020};
1021
1022
1023void dcn32_mpc_construct(struct dcn30_mpc *mpc30,
1024	struct dc_context *ctx,
1025	const struct dcn30_mpc_registers *mpc_regs,
1026	const struct dcn30_mpc_shift *mpc_shift,
1027	const struct dcn30_mpc_mask *mpc_mask,
1028	int num_mpcc,
1029	int num_rmu)
1030{
1031	int i;
1032
1033	mpc30->base.ctx = ctx;
1034
1035	mpc30->base.funcs = &dcn32_mpc_funcs;
1036
1037	mpc30->mpc_regs = mpc_regs;
1038	mpc30->mpc_shift = mpc_shift;
1039	mpc30->mpc_mask = mpc_mask;
1040
1041	mpc30->mpcc_in_use_mask = 0;
1042	mpc30->num_mpcc = num_mpcc;
1043	mpc30->num_rmu = num_rmu;
1044
1045	for (i = 0; i < MAX_MPCC; i++)
1046		mpc3_init_mpcc(&mpc30->base.mpcc_array[i], i);
1047}