for (i = 0; i < connectors_num; i++) {
struct link_init_data link_init_params = {0};
- struct core_link *link;
+ struct dc_link *link;
link_init_params.ctx = dc->ctx;
/* next BIOS object table connector */
}
for (i = 0; i < num_virtual_links; i++) {
- struct core_link *link = dm_alloc(sizeof(*link));
+ struct dc_link *link = dm_alloc(sizeof(*link));
struct encoder_init_data enc_init = {0};
if (link == NULL) {
link->ctx = dc->ctx;
link->dc = dc;
- link->public.connector_signal = SIGNAL_TYPE_VIRTUAL;
+ link->connector_signal = SIGNAL_TYPE_VIRTUAL;
link->link_id.type = OBJECT_TYPE_CONNECTOR;
link->link_id.id = CONNECTOR_ID_VIRTUAL;
link->link_id.enum_id = ENUM_ID_1;
enc_init.encoder.enum_id = ENUM_ID_1;
virtual_link_encoder_construct(link->link_enc, &enc_init);
- link->public.link_index = dc->link_count;
+ link->link_index = dc->link_count;
dc->links[dc->link_count] = link;
dc->link_count++;
}
int i;
for (i = 0; i < core_dc->link_count; i++) {
- if (&core_dc->links[i]->public == link)
+ if (core_dc->links[i] == link)
break;
}
if (i >= core_dc->link_count)
ASSERT_CRITICAL(false);
- dc_link_dp_set_drive_settings(&core_dc->links[i]->public, lt_settings);
+ dc_link_dp_set_drive_settings(core_dc->links[i], lt_settings);
}
static void perform_link_training(struct dc *dc,
for (i = 0; i < core_dc->link_count; i++)
dc_link_dp_perform_link_training(
- &core_dc->links[i]->public,
+ core_dc->links[i],
link_setting,
skip_video_pattern);
}
static void set_preferred_link_settings(struct dc *dc,
struct dc_link_settings *link_setting,
- const struct dc_link *link)
+ struct dc_link *link)
{
- struct core_link *core_link = DC_LINK_TO_CORE(link);
-
- core_link->public.verified_link_cap.lane_count =
- link_setting->lane_count;
- core_link->public.verified_link_cap.link_rate =
- link_setting->link_rate;
- dp_retrain_link_dp_test(core_link, link_setting, false);
+ link->preferred_link_setting = *link_setting;
+ dp_retrain_link_dp_test(link, link_setting, false);
}
static void enable_hpd(const struct dc_link *link)
static void set_test_pattern(
- const struct dc_link *link,
+ struct dc_link *link,
enum dp_test_pattern test_pattern,
const struct link_training_settings *p_link_settings,
const unsigned char *p_custom_pattern,
{
struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream);
struct bit_depth_reduction_params params;
- struct core_link *core_link = DC_LINK_TO_CORE(stream->status.link);
- struct pipe_ctx *pipes =
- core_link->dc->current_context->res_ctx.pipe_ctx;
+ struct dc_link *link = stream->status.link;
+ struct pipe_ctx *pipes = link->dc->current_context->res_ctx.pipe_ctx;
memset(¶ms, 0, sizeof(params));
if (!stream)
static void destruct(struct core_dc *dc)
{
- dc_resource_validate_ctx_destruct(dc->current_context);
+ dc_release_validate_context(dc->current_context);
+ dc->current_context = NULL;
destroy_links(dc);
if (dc->ctx->logger)
dal_logger_destroy(&dc->ctx->logger);
- dm_free(dc->current_context);
- dc->current_context = NULL;
-
dm_free(dc->ctx);
dc->ctx = NULL;
}
goto val_ctx_fail;
}
+ dc->current_context->ref_count++;
+
dc_ctx->cgs_device = init_params->cgs_device;
dc_ctx->driver_context = init_params->driver;
dc_ctx->dc = &dc->public;
if (context == NULL)
goto context_alloc_fail;
+ ++context->ref_count;
+
if (!is_validation_required(core_dc, set, set_count)) {
dc_resource_validate_ctx_copy_construct(core_dc->current_context, context);
return context;
__func__,
result);
- dc_resource_validate_ctx_destruct(context);
- dm_free(context);
+ dc_release_validate_context(context);
context = NULL;
}
if (context == NULL)
goto context_alloc_fail;
+ ++context->ref_count;
+
result = core_dc->res_pool->funcs->validate_with_context(
core_dc, set, set_count, context, NULL);
result);
}
- dc_resource_validate_ctx_destruct(context);
- dm_free(context);
+ dc_release_validate_context(context);
context = NULL;
return result == DC_OK;
if (context == NULL)
goto context_alloc_fail;
+ ++context->ref_count;
+
result = core_dc->res_pool->funcs->validate_guaranteed(
core_dc, stream, context);
- dc_resource_validate_ctx_destruct(context);
- dm_free(context);
+ dc_release_validate_context(context);
context_alloc_fail:
if (result != DC_OK) {
return ret;
}
-/* TODO operate on validation set (or something like it) */
-bool dc_commit_context(struct dc *dc, struct validate_context *context)
+
+/*
+ * Applies given context to HW and copy it into current context.
+ * It's up to the user to release the src context afterwards.
+ */
+static bool dc_commit_context_no_check(struct dc *dc, struct validate_context *context)
{
struct core_dc *core_dc = DC_TO_CORE(dc);
struct dc_bios *dcb = core_dc->ctx->dc_bios;
enum dc_status result = DC_ERROR_UNEXPECTED;
struct pipe_ctx *pipe;
int i, j, k, l;
+ const struct dc_stream *dc_streams[MAX_STREAMS] = {0};
- if (!context)
- dm_logger_write(core_dc->ctx->logger, LOG_ERROR,
- "%s: dc_commit_context with no context!\n",
- __func__);
-
- if (false == context_changed(core_dc, context))
- return DC_OK;
-
- dm_logger_write(core_dc->ctx->logger, LOG_DC, "%s: %d streams\n",
- __func__, context->stream_count);
-
- for (i = 0; i < context->stream_count; i++) {
- const struct dc_stream *stream = &context->streams[i]->public;
-
- dc_stream_log(stream,
- core_dc->ctx->logger,
- LOG_DC);
- }
+ for (i = 0; i < context->stream_count; i++)
+ dc_streams[i] = &context->streams[i]->public;
if (!dcb->funcs->is_accelerated_mode(dcb))
core_dc->hwss.enable_accelerated_mode(core_dc);
+ for (i = 0; i < core_dc->res_pool->pipe_count; i++) {
+ pipe = &context->res_ctx.pipe_ctx[i];
+ core_dc->hwss.wait_for_mpcc_disconnect(core_dc, core_dc->res_pool, pipe);
+ }
result = core_dc->hwss.apply_ctx_to_hw(core_dc, context);
program_timing_sync(core_dc, context);
for (i = 0; i < context->stream_count; i++) {
- const struct core_sink *sink = context->streams[i]->sink;
+ const struct dc_sink *sink = context->streams[i]->sink;
for (j = 0; j < context->stream_status[i].surface_count; j++) {
- struct core_surface *surface =
- DC_SURFACE_TO_CORE(context->stream_status[i].surfaces[j]);
+ const struct dc_surface *surface =
+ context->stream_status[i].surfaces[j];
core_dc->hwss.apply_ctx_for_surface(core_dc, surface, context);
context->streams[i]->public.timing.pix_clk_khz);
}
- dc_resource_validate_ctx_copy_construct(context, core_dc->current_context);
+ dc_enable_stereo(dc, context, dc_streams, context->stream_count);
+
+ dc_release_validate_context(core_dc->current_context);
+
+ core_dc->current_context = context;
+
+ dc_retain_validate_context(core_dc->current_context);
return (result == DC_OK);
}
+bool dc_commit_context(struct dc *dc, struct validate_context *context)
+{
+ enum dc_status result = DC_ERROR_UNEXPECTED;
+ struct core_dc *core_dc = DC_TO_CORE(dc);
+ int i;
+
+ if (false == context_changed(core_dc, context))
+ return DC_OK;
+
+ dm_logger_write(core_dc->ctx->logger, LOG_DC, "%s: %d streams\n",
+ __func__, context->stream_count);
+
+ for (i = 0; i < context->stream_count; i++) {
+ const struct dc_stream *stream = &context->streams[i]->public;
+
+ dc_stream_log(stream,
+ core_dc->ctx->logger,
+ LOG_DC);
+ }
+
+ result = dc_commit_context_no_check(dc, context);
+
+ return (result == DC_OK);
+}
+
+
bool dc_commit_streams(
struct dc *dc,
const struct dc_stream *streams[],
uint8_t stream_count)
{
struct core_dc *core_dc = DC_TO_CORE(dc);
- struct dc_bios *dcb = core_dc->ctx->dc_bios;
enum dc_status result = DC_ERROR_UNEXPECTED;
struct validate_context *context;
struct dc_validation_set set[MAX_STREAMS] = { {0, {0} } };
- int i, j;
+ int i;
if (false == streams_changed(core_dc, streams, stream_count))
return DC_OK;
if (context == NULL)
goto context_alloc_fail;
+ ++context->ref_count;
+
result = core_dc->res_pool->funcs->validate_with_context(
core_dc, set, stream_count, context, core_dc->current_context);
if (result != DC_OK){
__func__,
result);
BREAK_TO_DEBUGGER();
- dc_resource_validate_ctx_destruct(context);
goto fail;
}
- if (!dcb->funcs->is_accelerated_mode(dcb)) {
- core_dc->hwss.enable_accelerated_mode(core_dc);
- }
-
- if (result == DC_OK) {
- result = core_dc->hwss.apply_ctx_to_hw(core_dc, context);
- }
-
- program_timing_sync(core_dc, context);
-
- for (i = 0; i < context->stream_count; i++) {
- const struct core_sink *sink = context->streams[i]->sink;
-
- for (j = 0; j < context->stream_status[i].surface_count; j++) {
- struct core_surface *surface =
- DC_SURFACE_TO_CORE(context->stream_status[i].surfaces[j]);
-
- core_dc->hwss.apply_ctx_for_surface(core_dc, surface, context);
- }
-
- CONN_MSG_MODE(sink->link, "{%ux%u, %ux%u@%u, %ux%u@%uKhz}",
- context->streams[i]->public.src.width,
- context->streams[i]->public.src.height,
- context->streams[i]->public.timing.h_addressable,
- context->streams[i]->public.timing.v_addressable,
- context->streams[i]->public.timing.pix_clk_khz * 1000 /
- context->streams[i]->public.timing.h_total /
- context->streams[i]->public.timing.v_total, // Refresh rate
- context->streams[i]->public.timing.h_total,
- context->streams[i]->public.timing.v_total,
- context->streams[i]->public.timing.pix_clk_khz);
- }
- dc_enable_stereo(dc, context, streams, stream_count);
- dc_resource_validate_ctx_destruct(core_dc->current_context);
- dm_free(core_dc->current_context);
-
- core_dc->current_context = context;
-
- return (result == DC_OK);
+ result = dc_commit_context_no_check(dc, context);
fail:
- dm_free(context);
+ dc_release_validate_context(context);
context_alloc_fail:
return (result == DC_OK);
bool dc_commit_surfaces_to_stream(
struct dc *dc,
- const struct dc_surface **new_surfaces,
+ struct dc_surface **new_surfaces,
uint8_t new_surface_count,
const struct dc_stream *dc_stream)
{
stream_update->src = dc_stream->src;
stream_update->dst = dc_stream->dst;
+ stream_update->out_transfer_func = dc_stream->out_transfer_func;
for (i = 0; i < new_surface_count; i++) {
updates[i].surface = new_surfaces[i];
updates[i].gamma =
(struct dc_gamma *)new_surfaces[i]->gamma_correction;
+ updates[i].in_transfer_func = new_surfaces[i]->in_transfer_func;
flip_addr[i].address = new_surfaces[i]->address;
flip_addr[i].flip_immediate = new_surfaces[i]->flip_immediate;
plane_info[i].color_space = new_surfaces[i]->color_space;
return true;
}
+void dc_retain_validate_context(struct validate_context *context)
+{
+ ASSERT(context->ref_count > 0);
+ ++context->ref_count;
+}
+
+void dc_release_validate_context(struct validate_context *context)
+{
+ ASSERT(context->ref_count > 0);
+ --context->ref_count;
+
+ if (context->ref_count == 0) {
+ dc_resource_validate_ctx_destruct(context);
+ dm_free(context);
+ }
+}
+
static bool is_surface_in_context(
const struct validate_context *context,
const struct dc_surface *surface)
for (j = 0; j < MAX_PIPES; j++) {
const struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
- if (surface == &pipe_ctx->surface->public) {
+ if (surface == pipe_ctx->surface) {
return true;
}
}
enum surface_update_type update_type;
const struct dc_stream_status *stream_status;
struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream);
+ struct dc_context *dc_ctx = core_dc->ctx;
+
+ /* Currently this function do not result in any HW programming
+ * when called with 0 surface. But proceeding will cause
+ * SW state to be updated in validate_context. So we might as
+ * well make it not do anything at all until the hw programming
+ * is implemented properly to handle 0 surface case.
+ * TODO: fix hw programming then remove this early return
+ */
+ if (surface_count == 0)
+ return;
stream_status = dc_stream_get_status(dc_stream);
ASSERT(stream_status);
update_surface_trace(dc, srf_updates, surface_count);
if (update_type >= UPDATE_TYPE_FULL) {
- const struct dc_surface *new_surfaces[MAX_SURFACES] = {0};
+ struct dc_surface *new_surfaces[MAX_SURFACES] = {0};
for (i = 0; i < surface_count; i++)
new_surfaces[i] = srf_updates[i].surface;
/* initialize scratch memory for building context */
context = dm_alloc(sizeof(*context));
+ if (context == NULL)
+ goto context_alloc_fail;
+
+ ++context->ref_count;
+
dc_resource_validate_ctx_copy_construct(
core_dc->current_context, context);
/* save update parameters into surface */
for (i = 0; i < surface_count; i++) {
- struct core_surface *surface =
- DC_SURFACE_TO_CORE(srf_updates[i].surface);
+ struct dc_surface *surface = srf_updates[i].surface;
if (srf_updates[i].flip_addr) {
- surface->public.address = srf_updates[i].flip_addr->address;
- surface->public.flip_immediate =
+ surface->address = srf_updates[i].flip_addr->address;
+ surface->flip_immediate =
srf_updates[i].flip_addr->flip_immediate;
}
if (srf_updates[i].scaling_info) {
- surface->public.scaling_quality =
+ surface->scaling_quality =
srf_updates[i].scaling_info->scaling_quality;
- surface->public.dst_rect =
+ surface->dst_rect =
srf_updates[i].scaling_info->dst_rect;
- surface->public.src_rect =
+ surface->src_rect =
srf_updates[i].scaling_info->src_rect;
- surface->public.clip_rect =
+ surface->clip_rect =
srf_updates[i].scaling_info->clip_rect;
}
if (srf_updates[i].plane_info) {
- surface->public.color_space =
+ surface->color_space =
srf_updates[i].plane_info->color_space;
- surface->public.format =
+ surface->format =
srf_updates[i].plane_info->format;
- surface->public.plane_size =
+ surface->plane_size =
srf_updates[i].plane_info->plane_size;
- surface->public.rotation =
+ surface->rotation =
srf_updates[i].plane_info->rotation;
- surface->public.horizontal_mirror =
+ surface->horizontal_mirror =
srf_updates[i].plane_info->horizontal_mirror;
- surface->public.stereo_format =
+ surface->stereo_format =
srf_updates[i].plane_info->stereo_format;
- surface->public.tiling_info =
+ surface->tiling_info =
srf_updates[i].plane_info->tiling_info;
- surface->public.visible =
+ surface->visible =
srf_updates[i].plane_info->visible;
- surface->public.per_pixel_alpha =
+ surface->per_pixel_alpha =
srf_updates[i].plane_info->per_pixel_alpha;
- surface->public.dcc =
+ surface->dcc =
srf_updates[i].plane_info->dcc;
}
}
if (srf_updates[i].gamma &&
- srf_updates[i].gamma != surface->public.gamma_correction) {
- if (surface->public.gamma_correction != NULL)
- dc_gamma_release(&surface->public.
- gamma_correction);
+ srf_updates[i].gamma != surface->gamma_correction) {
+ if (surface->gamma_correction != NULL)
+ dc_gamma_release(&surface->gamma_correction);
dc_gamma_retain(srf_updates[i].gamma);
- surface->public.gamma_correction =
- srf_updates[i].gamma;
+ surface->gamma_correction = srf_updates[i].gamma;
}
if (srf_updates[i].in_transfer_func &&
- srf_updates[i].in_transfer_func != surface->public.in_transfer_func) {
- if (surface->public.in_transfer_func != NULL)
+ srf_updates[i].in_transfer_func != surface->in_transfer_func) {
+ if (surface->in_transfer_func != NULL)
dc_transfer_func_release(
- surface->public.
+ surface->
in_transfer_func);
dc_transfer_func_retain(
srf_updates[i].in_transfer_func);
- surface->public.in_transfer_func =
+ surface->in_transfer_func =
srf_updates[i].in_transfer_func;
}
if (srf_updates[i].hdr_static_metadata)
- surface->public.hdr_static_ctx =
+ surface->hdr_static_ctx =
*(srf_updates[i].hdr_static_metadata);
}
}
}
+ if (update_type > UPDATE_TYPE_FAST) {
+ for (j = 0; j < core_dc->res_pool->pipe_count; j++) {
+ struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
+
+ core_dc->hwss.wait_for_mpcc_disconnect(core_dc, core_dc->res_pool, pipe_ctx);
+ }
+ }
+
if (surface_count == 0)
core_dc->hwss.apply_ctx_for_surface(core_dc, NULL, context);
/* Lock pipes for provided surfaces, or all active if full update*/
for (i = 0; i < surface_count; i++) {
- struct core_surface *surface = DC_SURFACE_TO_CORE(srf_updates[i].surface);
+ struct dc_surface *surface = srf_updates[i].surface;
for (j = 0; j < core_dc->res_pool->pipe_count; j++) {
struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j];
/* Perform requested Updates */
for (i = 0; i < surface_count; i++) {
- struct core_surface *surface = DC_SURFACE_TO_CORE(srf_updates[i].surface);
+ struct dc_surface *surface = srf_updates[i].surface;
if (update_type == UPDATE_TYPE_MED)
core_dc->hwss.apply_ctx_for_surface(
for (j = 0; j < surface_count; j++) {
if (update_type != UPDATE_TYPE_FULL &&
- srf_updates[j].surface != &pipe_ctx->surface->public)
+ srf_updates[j].surface != pipe_ctx->surface)
continue;
if (!pipe_ctx->surface || pipe_ctx->top_pipe)
continue;
}
if (core_dc->current_context != context) {
- dc_resource_validate_ctx_destruct(core_dc->current_context);
- dm_free(core_dc->current_context);
-
+ dc_release_validate_context(core_dc->current_context);
core_dc->current_context = context;
}
return;
fail:
- dc_resource_validate_ctx_destruct(context);
- dm_free(context);
+ dc_release_validate_context(context);
+
+context_alloc_fail:
+ DC_ERROR("Failed to allocate new validate context!\n");
}
uint8_t dc_get_current_stream_count(const struct dc *dc)
return NULL;
}
-const struct dc_link *dc_get_link_at_index(const struct dc *dc, uint32_t link_index)
+struct dc_link *dc_get_link_at_index(const struct dc *dc, uint32_t link_index)
{
struct core_dc *core_dc = DC_TO_CORE(dc);
- return &core_dc->links[link_index]->public;
+ return core_dc->links[link_index];
}
const struct graphics_object_id dc_get_link_id_at_index(
struct dc *dc, uint32_t link_index)
{
struct core_dc *core_dc = DC_TO_CORE(dc);
- return core_dc->links[link_index]->public.irq_source_hpd;
+ return core_dc->links[link_index]->irq_source_hpd;
}
const struct audio **dc_get_audios(struct dc *dc)
enum dc_acpi_cm_power_state power_state)
{
struct core_dc *core_dc = DC_TO_CORE(dc);
+ int ref_count;
switch (power_state) {
case DC_ACPI_CM_POWER_STATE_D0:
* clean state, and dc hw programming optimizations will not
* cause any trouble.
*/
+
+ /* Preserve refcount */
+ ref_count = core_dc->current_context->ref_count;
+ dc_resource_validate_ctx_destruct(core_dc->current_context);
memset(core_dc->current_context, 0,
sizeof(*core_dc->current_context));
+ core_dc->current_context->ref_count = ref_count;
break;
}
{
struct core_dc *core_dc = DC_TO_CORE(dc);
- struct core_link *link = core_dc->links[link_index];
+ struct dc_link *link = core_dc->links[link_index];
enum ddc_result r = dal_ddc_service_read_dpcd_data(
- link->public.ddc,
+ link->ddc,
false,
I2C_MOT_UNDEF,
address,
uint32_t size)
{
struct core_dc *core_dc = DC_TO_CORE(dc);
- struct core_link *link = core_dc->links[link_index];
+ struct dc_link *link = core_dc->links[link_index];
enum ddc_result r = dal_ddc_service_write_dpcd_data(
- link->public.ddc,
+ link->ddc,
false,
I2C_MOT_UNDEF,
address,
{
struct core_dc *core_dc = DC_TO_CORE(dc);
- struct core_link *link = core_dc->links[link_index];
+ struct dc_link *link = core_dc->links[link_index];
enum ddc_result r = dal_ddc_service_read_dpcd_data(
- link->public.ddc,
+ link->ddc,
true,
mot,
address,
uint32_t size)
{
struct core_dc *core_dc = DC_TO_CORE(dc);
- struct core_link *link = core_dc->links[link_index];
+ struct dc_link *link = core_dc->links[link_index];
enum ddc_result r = dal_ddc_service_write_dpcd_data(
- link->public.ddc,
+ link->ddc,
true,
mot,
address,
struct core_dc *core_dc = DC_TO_CORE(dc);
- struct core_link *link = core_dc->links[link_index];
+ struct dc_link *link = core_dc->links[link_index];
bool result = dal_ddc_service_query_ddc_data(
- link->public.ddc,
+ link->ddc,
address,
write_buf,
write_size,
{
struct core_dc *core_dc = DC_TO_CORE(dc);
- struct core_link *link = core_dc->links[link_index];
- struct ddc_service *ddc = link->public.ddc;
+ struct dc_link *link = core_dc->links[link_index];
+ struct ddc_service *ddc = link->ddc;
return dal_i2caux_submit_i2c_command(
ddc->ctx->i2caux,
cmd);
}
-static bool link_add_remote_sink_helper(struct core_link *core_link, struct dc_sink *sink)
+static bool link_add_remote_sink_helper(struct dc_link *dc_link, struct dc_sink *sink)
{
- struct dc_link *dc_link = &core_link->public;
-
if (dc_link->sink_count >= MAX_SINKS_PER_LINK) {
BREAK_TO_DEBUGGER();
return false;
}
struct dc_sink *dc_link_add_remote_sink(
- const struct dc_link *link,
+ struct dc_link *link,
const uint8_t *edid,
int len,
struct dc_sink_init_data *init_data)
{
struct dc_sink *dc_sink;
enum dc_edid_status edid_status;
- struct core_link *core_link = DC_LINK_TO_LINK(link);
if (len > MAX_EDID_BUFFER_SIZE) {
dm_error("Max EDID buffer size breached!\n");
dc_sink->dc_edid.length = len;
if (!link_add_remote_sink_helper(
- core_link,
+ link,
dc_sink))
goto fail_add_sink;
edid_status = dm_helpers_parse_edid_caps(
- core_link->ctx,
+ link->ctx,
&dc_sink->dc_edid,
&dc_sink->edid_caps);
return NULL;
}
-void dc_link_set_sink(const struct dc_link *link, struct dc_sink *sink)
+void dc_link_set_sink(struct dc_link *link, struct dc_sink *sink)
{
- struct core_link *core_link = DC_LINK_TO_LINK(link);
- struct dc_link *dc_link = &core_link->public;
-
- dc_link->local_sink = sink;
+ link->local_sink = sink;
if (sink == NULL) {
- dc_link->type = dc_connection_none;
+ link->type = dc_connection_none;
} else {
- dc_link->type = dc_connection_single;
+ link->type = dc_connection_single;
}
}
-void dc_link_remove_remote_sink(const struct dc_link *link, const struct dc_sink *sink)
+void dc_link_remove_remote_sink(struct dc_link *link, struct dc_sink *sink)
{
int i;
- struct core_link *core_link = DC_LINK_TO_LINK(link);
- struct dc_link *dc_link = &core_link->public;
if (!link->sink_count) {
BREAK_TO_DEBUGGER();
return;
}
- for (i = 0; i < dc_link->sink_count; i++) {
- if (dc_link->remote_sinks[i] == sink) {
+ for (i = 0; i < link->sink_count; i++) {
+ if (link->remote_sinks[i] == sink) {
dc_sink_release(sink);
- dc_link->remote_sinks[i] = NULL;
+ link->remote_sinks[i] = NULL;
/* shrink array to remove empty place */
- while (i < dc_link->sink_count - 1) {
- dc_link->remote_sinks[i] = dc_link->remote_sinks[i+1];
+ while (i < link->sink_count - 1) {
+ link->remote_sinks[i] = link->remote_sinks[i+1];
i++;
}
- dc_link->remote_sinks[i] = NULL;
- dc_link->sink_count--;
+ link->remote_sinks[i] = NULL;
+ link->sink_count--;
return;
}
}
return false;
}
- if (mi->funcs->mem_input_update_dchub)
- mi->funcs->mem_input_update_dchub(mi, dh_data);
+ if (core_dc->hwss.update_dchub)
+ core_dc->hwss.update_dchub(core_dc->hwseq, dh_data);
else
- ASSERT(mi->funcs->mem_input_update_dchub);
+ ASSERT(core_dc->hwss.update_dchub);
return true;
}
+void dc_log_hw_state(struct dc *dc)
+{
+ struct core_dc *core_dc = DC_TO_CORE(dc);
+
+ if (core_dc->hwss.log_hw_state)
+ core_dc->hwss.log_hw_state(core_dc);
+}