Commit c2cd9d04 authored by Murton Liu's avatar Murton Liu Committed by Alex Deucher
Browse files

drm/amd/display: Hook up calls to do stereo mux and dig programming to stereo control interface



[Why]
Implementation of stereo mux register is complete, but unused. Need to
call functions to write relevant configs.

[How]
Add function to write stereo config for enable/disable case and call in
stereo control interface.

Signed-off-by: default avatarMurton Liu <murton.liu@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 692626fc
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -1236,6 +1236,53 @@ void dc_release_state(struct dc_state *context)
	kref_put(&context->refcount, dc_state_free);
}

bool dc_set_generic_gpio_for_stereo(bool enable,
		struct gpio_service *gpio_service)
{
	enum gpio_result gpio_result = GPIO_RESULT_NON_SPECIFIC_ERROR;
	struct gpio_pin_info pin_info;
	struct gpio *generic;
	struct gpio_generic_mux_config *config = kzalloc(sizeof(struct gpio_generic_mux_config),
			   GFP_KERNEL);

	pin_info = dal_gpio_get_generic_pin_info(gpio_service, GPIO_ID_GENERIC, 0);

	if (pin_info.mask == 0xFFFFFFFF || pin_info.offset == 0xFFFFFFFF) {
		kfree(config);
		return false;
	} else {
		generic = dal_gpio_service_create_generic_mux(
			gpio_service,
			pin_info.offset,
			pin_info.mask);
	}

	if (!generic) {
		kfree(config);
		return false;
	}

	gpio_result = dal_gpio_open(generic, GPIO_MODE_OUTPUT);

	config->enable_output_from_mux = enable;
	config->mux_select = GPIO_SIGNAL_SOURCE_PASS_THROUGH_STEREO_SYNC;

	if (gpio_result == GPIO_RESULT_OK)
		gpio_result = dal_mux_setup_config(generic, config);

	if (gpio_result == GPIO_RESULT_OK) {
		dal_gpio_close(generic);
		dal_gpio_destroy_generic_mux(&generic);
		kfree(config);
		return true;
	} else {
		dal_gpio_close(generic);
		dal_gpio_destroy_generic_mux(&generic);
		kfree(config);
		return false;
	}
}

static bool is_surface_in_context(
		const struct dc_state *context,
		const struct dc_plane_state *plane_state)
+3 −0
Original line number Diff line number Diff line
@@ -852,6 +852,9 @@ enum dc_status dc_validate_plane(struct dc *dc, const struct dc_plane_state *pla

void get_clock_requirements_for_state(struct dc_state *state, struct AsicStateEx *info);

bool dc_set_generic_gpio_for_stereo(bool enable,
		struct gpio_service *gpio_service);

/*
 * fast_validate: we return after determining if we can support the new state,
 * but before we populate the programming info
+7 −0
Original line number Diff line number Diff line
@@ -2692,6 +2692,13 @@ static void dcn10_setup_stereo(struct pipe_ctx *pipe_ctx, struct dc *dc)

	dcn10_config_stereo_parameters(stream, &flags);

	if (stream->timing.timing_3d_format == TIMING_3D_FORMAT_SIDEBAND_FA) {
		if (!dc_set_generic_gpio_for_stereo(true, dc->ctx->gpio_service))
			dc_set_generic_gpio_for_stereo(false, dc->ctx->gpio_service);
	} else {
		dc_set_generic_gpio_for_stereo(false, dc->ctx->gpio_service);
	}

	pipe_ctx->stream_res.opp->funcs->opp_program_stereo(
		pipe_ctx->stream_res.opp,
		flags.PROGRAM_STEREO == 1 ? true:false,
+40 −2
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include "../hw_gpio.h"
#include "../hw_ddc.h"
#include "../hw_hpd.h"
#include "../hw_generic.h"

#include "hw_factory_dcn10.h"

@@ -121,6 +122,42 @@ static const struct ddc_sh_mask ddc_mask = {
		DDC_MASK_SH_LIST(_MASK)
};

#include "../generic_regs.h"

/* set field name */
#define SF_GENERIC(reg_name, field_name, post_fix)\
	.field_name = reg_name ## __ ## field_name ## post_fix

#define generic_regs(id) \
{\
	GENERIC_REG_LIST(id)\
}

static const struct generic_registers generic_regs[] = {
	generic_regs(A),
	generic_regs(B),
};

static const struct generic_sh_mask generic_shift[] = {
	GENERIC_MASK_SH_LIST(__SHIFT, A),
	GENERIC_MASK_SH_LIST(__SHIFT, B),
};

static const struct generic_sh_mask generic_mask[] = {
	GENERIC_MASK_SH_LIST(_MASK, A),
	GENERIC_MASK_SH_LIST(_MASK, B),
};

static void define_generic_registers(struct hw_gpio_pin *pin, uint32_t en)
{
	struct hw_generic *generic = HW_GENERIC_FROM_BASE(pin);

	generic->regs = &generic_regs[en];
	generic->shifts = &generic_shift[en];
	generic->masks = &generic_mask[en];
	generic->base.regs = &generic_regs[en].gpio;
}

static void define_ddc_registers(
		struct hw_gpio_pin *pin,
		uint32_t en)
@@ -161,12 +198,13 @@ static void define_hpd_registers(struct hw_gpio_pin *pin, uint32_t en)
static const struct hw_factory_funcs funcs = {
	.create_ddc_data = dal_hw_ddc_create,
	.create_ddc_clock = dal_hw_ddc_create,
	.create_generic = NULL,
	.create_generic = dal_hw_generic_create,
	.create_hpd = dal_hw_hpd_create,
	.create_sync = NULL,
	.create_gsl = NULL,
	.define_hpd_registers = define_hpd_registers,
	.define_ddc_registers = define_ddc_registers
	.define_ddc_registers = define_ddc_registers,
	.define_generic_registers = define_generic_registers
};
/*
 * dal_hw_factory_dcn10_init
+72 −0
Original line number Diff line number Diff line
@@ -141,6 +141,62 @@ struct gpio *dal_gpio_service_create_irq(
	return dal_gpio_create_irq(service, id, en);
}

struct gpio *dal_gpio_service_create_generic_mux(
	struct gpio_service *service,
	uint32_t offset,
	uint32_t mask)
{
	enum gpio_id id;
	uint32_t en;
	struct gpio *generic;

	if (mask == 1)
		en = GPIO_GENERIC_A;
	else if (mask == 0x00000100L)
		en = GPIO_GENERIC_B;
	else
		return NULL;

	id = GPIO_ID_GENERIC;

	generic = dal_gpio_create(
		service, id, en, GPIO_PIN_OUTPUT_STATE_DEFAULT);

	return generic;
}

void dal_gpio_destroy_generic_mux(
	struct gpio **mux)
{
	if (!mux || !*mux) {
		ASSERT_CRITICAL(false);
		return;
	}

	dal_gpio_close(*mux);
	dal_gpio_destroy(mux);
	kfree(*mux);

	*mux = NULL;
}

struct gpio_pin_info dal_gpio_get_generic_pin_info(
	struct gpio_service *service,
	enum gpio_id id,
	uint32_t en)
{
	struct gpio_pin_info pin;

	if (service->translate.funcs->id_to_offset) {
		service->translate.funcs->id_to_offset(id, en, &pin);
	} else {
		pin.mask = 0xFFFFFFFF;
		pin.offset = 0xFFFFFFFF;
	}

	return pin;
}

void dal_gpio_service_destroy(
	struct gpio_service **ptr)
{
@@ -165,6 +221,21 @@ void dal_gpio_service_destroy(
	*ptr = NULL;
}

enum gpio_result dal_mux_setup_config(
	struct gpio *mux,
	struct gpio_generic_mux_config *config)
{
	struct gpio_config_data config_data;

	if (!config)
		return GPIO_RESULT_INVALID_DATA;

	config_data.config.generic_mux = *config;
	config_data.type = GPIO_CONFIG_TYPE_GENERIC_MUX;

	return dal_gpio_set_config(mux, &config_data);
}

/*
 * @brief
 * Private API.
@@ -255,6 +326,7 @@ enum gpio_result dal_gpio_service_open(
	case GPIO_ID_GENERIC:
		pin = service->factory.funcs->create_generic(
			service->ctx, id, en);
		service->factory.funcs->define_generic_registers(pin, en);
	break;
	case GPIO_ID_HPD:
		pin = service->factory.funcs->create_hpd(
Loading