Commit b8fdfcc6 authored by Harry Wentland's avatar Harry Wentland Committed by Alex Deucher
Browse files

drm/amd/display: Add DCE12 core support

parent 9a48d684
Loading
Loading
Loading
Loading
+197 −0
Original line number Diff line number Diff line
/*
 * Copyright 2015 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: AMD
 *
 */

#include "dm_services.h"
#include "dc.h"
#include "core_dc.h"
#include "core_types.h"
#include "dce120_hw_sequencer.h"

#include "dce110/dce110_hw_sequencer.h"

/* include DCE12.0 register header files */
#include "vega10/DC/dce_12_0_offset.h"
#include "vega10/DC/dce_12_0_sh_mask.h"
#include "vega10/soc15ip.h"
#include "reg_helper.h"

struct dce120_hw_seq_reg_offsets {
	uint32_t crtc;
};

static const struct dce120_hw_seq_reg_offsets reg_offsets[] = {
{
	.crtc = (mmCRTC0_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
},
{
	.crtc = (mmCRTC1_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
},
{
	.crtc = (mmCRTC2_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
},
{
	.crtc = (mmCRTC3_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
},
{
	.crtc = (mmCRTC4_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
},
{
	.crtc = (mmCRTC5_CRTC_GSL_CONTROL - mmCRTC0_CRTC_GSL_CONTROL),
}
};

#define HW_REG_CRTC(reg, id)\
	(reg + reg_offsets[id].crtc)

#define CNTL_ID(controller_id)\
	controller_id
/*******************************************************************************
 * Private definitions
 ******************************************************************************/
#if 0
static void dce120_init_pte(struct dc_context *ctx, uint8_t controller_id)
{
	uint32_t addr;
	uint32_t value = 0;
	uint32_t chunk_int = 0;
	uint32_t chunk_mul = 0;
/*
	addr = mmDCP0_DVMM_PTE_CONTROL + controller_id *
			(mmDCP1_DVMM_PTE_CONTROL- mmDCP0_DVMM_PTE_CONTROL);

	value = dm_read_reg(ctx, addr);

	set_reg_field_value(
			value, 0, DCP, controller_id,
			DVMM_PTE_CONTROL,
			DVMM_USE_SINGLE_PTE);

	set_reg_field_value_soc15(
			value, 1, DCP, controller_id,
			DVMM_PTE_CONTROL,
			DVMM_PTE_BUFFER_MODE0);

	set_reg_field_value_soc15(
			value, 1, DCP, controller_id,
			DVMM_PTE_CONTROL,
			DVMM_PTE_BUFFER_MODE1);

	dm_write_reg(ctx, addr, value);*/

	addr = mmDVMM_PTE_REQ;
	value = dm_read_reg(ctx, addr);

	chunk_int = get_reg_field_value(
		value,
		DVMM_PTE_REQ,
		HFLIP_PTEREQ_PER_CHUNK_INT);

	chunk_mul = get_reg_field_value(
		value,
		DVMM_PTE_REQ,
		HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);

	if (chunk_int != 0x4 || chunk_mul != 0x4) {

		set_reg_field_value(
			value,
			255,
			DVMM_PTE_REQ,
			MAX_PTEREQ_TO_ISSUE);

		set_reg_field_value(
			value,
			4,
			DVMM_PTE_REQ,
			HFLIP_PTEREQ_PER_CHUNK_INT);

		set_reg_field_value(
			value,
			4,
			DVMM_PTE_REQ,
			HFLIP_PTEREQ_PER_CHUNK_MULTIPLIER);

		dm_write_reg(ctx, addr, value);
	}
}
#endif

static bool dce120_enable_display_power_gating(
	struct core_dc *dc,
	uint8_t controller_id,
	struct dc_bios *dcb,
	enum pipe_gating_control power_gating)
{
	/* disable for bringup */
#if 0
	enum bp_result bp_result = BP_RESULT_OK;
	enum bp_pipe_control_action cntl;
	struct dc_context *ctx = dc->ctx;

	if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
		return true;

	if (power_gating == PIPE_GATING_CONTROL_INIT)
		cntl = ASIC_PIPE_INIT;
	else if (power_gating == PIPE_GATING_CONTROL_ENABLE)
		cntl = ASIC_PIPE_ENABLE;
	else
		cntl = ASIC_PIPE_DISABLE;

	if (power_gating != PIPE_GATING_CONTROL_INIT || controller_id == 0) {

		bp_result = dcb->funcs->enable_disp_power_gating(
						dcb, controller_id + 1, cntl);

		/* Revert MASTER_UPDATE_MODE to 0 because bios sets it 2
		 * by default when command table is called
		 */
		dm_write_reg(ctx,
			HW_REG_CRTC(mmCRTC0_CRTC_MASTER_UPDATE_MODE, controller_id),
			0);
	}

	if (power_gating != PIPE_GATING_CONTROL_ENABLE)
		dce120_init_pte(ctx, controller_id);

	if (bp_result == BP_RESULT_OK)
		return true;
	else
		return false;
#endif
	return false;
}

bool dce120_hw_sequencer_construct(struct core_dc *dc)
{
	/* All registers used by dce11.2 match those in dce11 in offset and
	 * structure
	 */
	dce110_hw_sequencer_construct(dc);
	dc->hwss.enable_display_power_gating = dce120_enable_display_power_gating;

	return true;
}
+36 −0
Original line number Diff line number Diff line
/*
* Copyright 2012-15 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: AMD
 *
 */

#ifndef __DC_HWSS_DCE120_H__
#define __DC_HWSS_DCE120_H__

#include "core_types.h"

struct core_dc;

bool dce120_hw_sequencer_construct(struct core_dc *dc);

#endif /* __DC_HWSS_DCE112_H__ */
+58 −0
Original line number Diff line number Diff line
/*
 * Copyright 2012-15 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: AMD
 *
 */

#include "dm_services.h"
#include "include/logger_interface.h"

#include "vega10/DC/dce_12_0_offset.h"
#include "vega10/DC/dce_12_0_sh_mask.h"
#include "vega10/soc15ip.h"

#include "dce120_ipp.h"

static const struct ipp_funcs funcs = {
		.ipp_cursor_set_attributes = dce120_ipp_cursor_set_attributes,
		.ipp_cursor_set_position = dce120_ipp_cursor_set_position,
		.ipp_program_prescale = dce120_ipp_program_prescale,
		.ipp_program_input_lut = dce120_ipp_program_input_lut,
		.ipp_set_degamma = dce120_ipp_set_degamma,
};

bool dce120_ipp_construct(
	struct dce110_ipp *ipp,
	struct dc_context *ctx,
	uint32_t inst,
	const struct dce110_ipp_reg_offsets *offset)
{
	if (!dce110_ipp_construct(ipp, ctx, inst, offset)) {
		ASSERT_CRITICAL(false);
		return false;
	}

	ipp->base.funcs = &funcs;

	return true;
}
+62 −0
Original line number Diff line number Diff line
/*
 * Copyright 2012-15 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: AMD
 *
 */

#ifndef __DC_IPP_DCE120_H__
#define __DC_IPP_DCE120_H__

#include "ipp.h"
#include "../dce110/dce110_ipp.h"


bool dce120_ipp_construct(
	struct dce110_ipp *ipp,
	struct dc_context *ctx,
	enum controller_id id,
	const struct dce110_ipp_reg_offsets *offset);

/* CURSOR RELATED */
void dce120_ipp_cursor_set_position(
	struct input_pixel_processor *ipp,
	const struct dc_cursor_position *position,
	const struct dc_cursor_mi_param *param);

bool dce120_ipp_cursor_set_attributes(
	struct input_pixel_processor *ipp,
	const struct dc_cursor_attributes *attributes);

/* DEGAMMA RELATED */
bool dce120_ipp_set_degamma(
	struct input_pixel_processor *ipp,
	enum ipp_degamma_mode mode);

void dce120_ipp_program_prescale(
	struct input_pixel_processor *ipp,
	struct ipp_prescale_params *params);

void dce120_ipp_program_input_lut(
	struct input_pixel_processor *ipp,
	const struct dc_gamma *gamma);

#endif /*__DC_IPP_DCE120_H__*/
+202 −0
Original line number Diff line number Diff line
/*
 * Copyright 2012-15 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: AMD
 *
 */

#include "dm_services.h"
#include "include/logger_interface.h"

#include "vega10/DC/dce_12_0_offset.h"
#include "vega10/DC/dce_12_0_sh_mask.h"
#include "vega10/soc15ip.h"

#include "../dce110/dce110_ipp.h"


#define DCP_REG_UPDATE_N(reg_name, n, ...)	\
		generic_reg_update_soc15(ipp110->base.ctx, ipp110->offsets.dcp_offset, reg_name, n, __VA_ARGS__)

#define DCP_REG_SET_N(reg_name, n, ...)	\
		generic_reg_set_soc15(ipp110->base.ctx, ipp110->offsets.dcp_offset, reg_name, n, __VA_ARGS__)

#define DCP_REG_UPDATE(reg, field, val)	\
		DCP_REG_UPDATE_N(reg, 1, FD(reg##__##field), val)

#define DCP_REG_UPDATE_2(reg, field1, val1, field2, val2)	\
		DCP_REG_UPDATE_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)

#define DCP_REG_UPDATE_3(reg, field1, val1, field2, val2, field3, val3)	\
		DCP_REG_UPDATE_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)

#define DCP_REG_SET(reg, field, val)	\
		DCP_REG_SET_N(reg, 1, FD(reg##__##field), val)

#define DCP_REG_SET_2(reg, field1, val1, field2, val2)	\
		DCP_REG_SET_N(reg, 2, FD(reg##__##field1), val1, FD(reg##__##field2), val2)

#define DCP_REG_SET_3(reg, field1, val1, field2, val2, field3, val3)	\
		DCP_REG_SET_N(reg, 3, FD(reg##__##field1), val1, FD(reg##__##field2), val2, FD(reg##__##field3), val3)

/* TODO: DAL3 does not implement cursor memory control
 * MCIF_MEM_CONTROL, DMIF_CURSOR_MEM_CONTROL
 */
static void lock(
	struct dce110_ipp *ipp110, bool lock)
{
	DCP_REG_UPDATE(DCP0_CUR_UPDATE, CURSOR_UPDATE_LOCK, lock);
}

static bool program_control(
	struct dce110_ipp *ipp110,
	enum dc_cursor_color_format color_format,
	bool enable_magnification,
	bool inverse_transparent_clamping)
{
	uint32_t mode = 0;

	switch (color_format) {
	case CURSOR_MODE_MONO:
		mode = 0;
		break;
	case CURSOR_MODE_COLOR_1BIT_AND:
		mode = 1;
		break;
	case CURSOR_MODE_COLOR_PRE_MULTIPLIED_ALPHA:
		mode = 2;
		break;
	case CURSOR_MODE_COLOR_UN_PRE_MULTIPLIED_ALPHA:
		mode = 3;
		break;
	default:
		return false;
	}

	DCP_REG_UPDATE_3(
		DCP0_CUR_CONTROL,
		CURSOR_MODE, mode,
		CURSOR_2X_MAGNIFY, enable_magnification,
		CUR_INV_TRANS_CLAMP, inverse_transparent_clamping);

	if (color_format == CURSOR_MODE_MONO) {
		DCP_REG_SET_3(
			DCP0_CUR_COLOR1,
			CUR_COLOR1_BLUE, 0,
			CUR_COLOR1_GREEN, 0,
			CUR_COLOR1_RED, 0);

		DCP_REG_SET_3(
			DCP0_CUR_COLOR2,
			CUR_COLOR2_BLUE, 0xff,
			CUR_COLOR2_GREEN, 0xff,
			CUR_COLOR2_RED, 0xff);
	}
	return true;
}

static void program_address(
	struct dce110_ipp *ipp110,
	PHYSICAL_ADDRESS_LOC address)
{
	/* SURFACE_ADDRESS_HIGH: Higher order bits (39:32) of hardware cursor
	 * surface base address in byte. It is 4K byte aligned.
	 * The correct way to program cursor surface address is to first write
	 * to CUR_SURFACE_ADDRESS_HIGH, and then write to CUR_SURFACE_ADDRESS
	 */

	DCP_REG_SET(
		DCP0_CUR_SURFACE_ADDRESS_HIGH,
		CURSOR_SURFACE_ADDRESS_HIGH, address.high_part);

	DCP_REG_SET(
		DCP0_CUR_SURFACE_ADDRESS,
		CURSOR_SURFACE_ADDRESS, address.low_part);
}

void dce120_ipp_cursor_set_position(
	struct input_pixel_processor *ipp,
	const struct dc_cursor_position *position,
	const struct dc_cursor_mi_param *param)
{
	struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);

	/* lock cursor registers */
	lock(ipp110, true);

	/* Flag passed in structure differentiates cursor enable/disable. */
	/* Update if it differs from cached state. */
	DCP_REG_UPDATE(DCP0_CUR_CONTROL, CURSOR_EN, position->enable);

	DCP_REG_SET_2(
		DCP0_CUR_POSITION,
		CURSOR_X_POSITION, position->x,
		CURSOR_Y_POSITION, position->y);

	if (position->hot_spot_enable)
		DCP_REG_SET_2(
			DCP0_CUR_HOT_SPOT,
			CURSOR_HOT_SPOT_X, position->x_hotspot,
			CURSOR_HOT_SPOT_Y, position->y_hotspot);

	/* unlock cursor registers */
	lock(ipp110, false);
}

bool dce120_ipp_cursor_set_attributes(
	struct input_pixel_processor *ipp,
	const struct dc_cursor_attributes *attributes)
{
	struct dce110_ipp *ipp110 = TO_DCE110_IPP(ipp);
	/* Lock cursor registers */
	lock(ipp110, true);

	/* Program cursor control */
	program_control(
		ipp110,
		attributes->color_format,
		attributes->attribute_flags.bits.ENABLE_MAGNIFICATION,
		attributes->attribute_flags.bits.INVERSE_TRANSPARENT_CLAMPING);

	/* Program hot spot coordinates */
	DCP_REG_SET_2(
		DCP0_CUR_HOT_SPOT,
		CURSOR_HOT_SPOT_X, attributes->x_hot,
		CURSOR_HOT_SPOT_Y, attributes->y_hot);

	/*
	 * Program cursor size -- NOTE: HW spec specifies that HW register
	 * stores size as (height - 1, width - 1)
	 */
	DCP_REG_SET_2(
		DCP0_CUR_SIZE,
		CURSOR_WIDTH, attributes->width-1,
		CURSOR_HEIGHT, attributes->height-1);

	/* Program cursor surface address */
	program_address(ipp110, attributes->address);

	/* Unlock Cursor registers. */
	lock(ipp110, false);

	return true;
}
Loading