提交 ab2541b6 编写于 作者: A Aric Cyr 提交者: Alex Deucher

drm/amd/display: Remove dc_target object

dc_target does not fit well into DRM framework so removed it.
This will prevent the driver from leveraging the pipe-split
code for tiled displays, so will have to be handled at a higher
level.  Most places that used dc_target now directly use dc_stream
instead.
Signed-off-by: NAric Cyr <aric.cyr@amd.com>
Acked-by: NHarry Wentland <Harry.Wentland@amd.com>
Signed-off-by: NAlex Deucher <alexander.deucher@amd.com>
上级 624d7c47
...@@ -428,8 +428,8 @@ struct amdgpu_crtc { ...@@ -428,8 +428,8 @@ struct amdgpu_crtc {
int otg_inst; int otg_inst;
uint32_t flip_flags; uint32_t flip_flags;
/* After Set Mode target will be non-NULL */ /* After Set Mode stream will be non-NULL */
struct dc_target *target; const struct dc_stream *stream;
}; };
struct amdgpu_encoder_atom_dig { struct amdgpu_encoder_atom_dig {
...@@ -550,7 +550,7 @@ struct amdgpu_connector { ...@@ -550,7 +550,7 @@ struct amdgpu_connector {
const struct dc_sink *dc_sink; const struct dc_sink *dc_sink;
const struct dc_link *dc_link; const struct dc_link *dc_link;
const struct dc_sink *dc_em_sink; const struct dc_sink *dc_em_sink;
const struct dc_target *target; const struct dc_stream *stream;
void *con_priv; void *con_priv;
bool dac_load_detect; bool dac_load_detect;
bool detected_by_load; /* if the connection status was determined by load */ bool detected_by_load; /* if the connection status was determined by load */
......
...@@ -68,12 +68,12 @@ static u32 dm_vblank_get_counter(struct amdgpu_device *adev, int crtc) ...@@ -68,12 +68,12 @@ static u32 dm_vblank_get_counter(struct amdgpu_device *adev, int crtc)
else { else {
struct amdgpu_crtc *acrtc = adev->mode_info.crtcs[crtc]; struct amdgpu_crtc *acrtc = adev->mode_info.crtcs[crtc];
if (NULL == acrtc->target) { if (NULL == acrtc->stream) {
DRM_ERROR("dc_target is NULL for crtc '%d'!\n", crtc); DRM_ERROR("dc_stream is NULL for crtc '%d'!\n", crtc);
return 0; return 0;
} }
return dc_target_get_vblank_counter(acrtc->target); return dc_stream_get_vblank_counter(acrtc->stream);
} }
} }
...@@ -85,12 +85,12 @@ static int dm_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc, ...@@ -85,12 +85,12 @@ static int dm_crtc_get_scanoutpos(struct amdgpu_device *adev, int crtc,
else { else {
struct amdgpu_crtc *acrtc = adev->mode_info.crtcs[crtc]; struct amdgpu_crtc *acrtc = adev->mode_info.crtcs[crtc];
if (NULL == acrtc->target) { if (NULL == acrtc->stream) {
DRM_ERROR("dc_target is NULL for crtc '%d'!\n", crtc); DRM_ERROR("dc_stream is NULL for crtc '%d'!\n", crtc);
return 0; return 0;
} }
return dc_target_get_scanoutpos(acrtc->target, vbl, position); return dc_stream_get_scanoutpos(acrtc->stream, vbl, position);
} }
return 0; return 0;
...@@ -461,7 +461,7 @@ static int dm_suspend(void *handle) ...@@ -461,7 +461,7 @@ static int dm_suspend(void *handle)
drm_modeset_lock_all(adev->ddev); drm_modeset_lock_all(adev->ddev);
list_for_each_entry(crtc, &adev->ddev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &adev->ddev->mode_config.crtc_list, head) {
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
if (acrtc->target) if (acrtc->stream)
drm_crtc_vblank_off(crtc); drm_crtc_vblank_off(crtc);
} }
drm_modeset_unlock_all(adev->ddev); drm_modeset_unlock_all(adev->ddev);
...@@ -655,7 +655,7 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev ) ...@@ -655,7 +655,7 @@ int amdgpu_dm_display_resume(struct amdgpu_device *adev )
drm_modeset_lock_all(ddev); drm_modeset_lock_all(ddev);
list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) {
struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc);
if (acrtc->target) if (acrtc->stream)
drm_crtc_vblank_on(crtc); drm_crtc_vblank_on(crtc);
} }
drm_modeset_unlock_all(ddev); drm_modeset_unlock_all(ddev);
...@@ -740,7 +740,7 @@ void amdgpu_dm_update_connector_after_detect( ...@@ -740,7 +740,7 @@ void amdgpu_dm_update_connector_after_detect(
if (aconnector->base.force != DRM_FORCE_UNSPECIFIED if (aconnector->base.force != DRM_FORCE_UNSPECIFIED
&& aconnector->dc_em_sink) { && aconnector->dc_em_sink) {
/* For S3 resume with headless use eml_sink to fake target /* For S3 resume with headless use eml_sink to fake stream
* because on resume connecotr->sink is set ti NULL * because on resume connecotr->sink is set ti NULL
*/ */
mutex_lock(&dev->mode_config.mutex); mutex_lock(&dev->mode_config.mutex);
...@@ -1184,7 +1184,7 @@ int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) ...@@ -1184,7 +1184,7 @@ int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
return -1; return -1;
} }
for (i = 0; i < dm->dc->caps.max_targets; i++) { for (i = 0; i < dm->dc->caps.max_streams; i++) {
acrtc = kzalloc(sizeof(struct amdgpu_crtc), GFP_KERNEL); acrtc = kzalloc(sizeof(struct amdgpu_crtc), GFP_KERNEL);
if (!acrtc) if (!acrtc)
goto fail; goto fail;
...@@ -1199,7 +1199,7 @@ int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) ...@@ -1199,7 +1199,7 @@ int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
} }
} }
dm->display_indexes_num = dm->dc->caps.max_targets; dm->display_indexes_num = dm->dc->caps.max_streams;
/* loops over all connectors on the board */ /* loops over all connectors on the board */
for (i = 0; i < link_cnt; i++) { for (i = 0; i < link_cnt; i++) {
...@@ -1318,7 +1318,7 @@ static void dm_page_flip(struct amdgpu_device *adev, ...@@ -1318,7 +1318,7 @@ static void dm_page_flip(struct amdgpu_device *adev,
int crtc_id, u64 crtc_base, bool async) int crtc_id, u64 crtc_base, bool async)
{ {
struct amdgpu_crtc *acrtc; struct amdgpu_crtc *acrtc;
struct dc_target *target; const struct dc_stream *stream;
struct dc_flip_addrs addr = { {0} }; struct dc_flip_addrs addr = { {0} };
/* /*
...@@ -1336,7 +1336,7 @@ static void dm_page_flip(struct amdgpu_device *adev, ...@@ -1336,7 +1336,7 @@ static void dm_page_flip(struct amdgpu_device *adev,
* a little longer to lock up all cores. * a little longer to lock up all cores.
* *
* The reason we should lock on dal_mutex is so that we can be sure * The reason we should lock on dal_mutex is so that we can be sure
* nobody messes with acrtc->target after we read and check its value. * nobody messes with acrtc->stream after we read and check its value.
* *
* We might be able to fix our concurrency issues with a work queue * We might be able to fix our concurrency issues with a work queue
* where we schedule all work items (mode_set, page_flip, etc.) and * where we schedule all work items (mode_set, page_flip, etc.) and
...@@ -1345,14 +1345,14 @@ static void dm_page_flip(struct amdgpu_device *adev, ...@@ -1345,14 +1345,14 @@ static void dm_page_flip(struct amdgpu_device *adev,
*/ */
acrtc = adev->mode_info.crtcs[crtc_id]; acrtc = adev->mode_info.crtcs[crtc_id];
target = acrtc->target; stream = acrtc->stream;
/* /*
* Received a page flip call after the display has been reset. * Received a page flip call after the display has been reset.
* Just return in this case. Everything should be clean-up on reset. * Just return in this case. Everything should be clean-up on reset.
*/ */
if (!target) { if (!stream) {
WARN_ON(1); WARN_ON(1);
return; return;
} }
...@@ -1368,7 +1368,7 @@ static void dm_page_flip(struct amdgpu_device *adev, ...@@ -1368,7 +1368,7 @@ static void dm_page_flip(struct amdgpu_device *adev,
dc_flip_surface_addrs( dc_flip_surface_addrs(
adev->dm.dc, adev->dm.dc,
dc_target_get_status(target)->surfaces, dc_stream_get_status(stream)->surfaces,
&addr, 1); &addr, 1);
} }
...@@ -1376,25 +1376,22 @@ static int amdgpu_notify_freesync(struct drm_device *dev, void *data, ...@@ -1376,25 +1376,22 @@ static int amdgpu_notify_freesync(struct drm_device *dev, void *data,
struct drm_file *filp) struct drm_file *filp)
{ {
struct mod_freesync_params freesync_params; struct mod_freesync_params freesync_params;
uint8_t num_targets; uint8_t num_streams;
uint8_t i; uint8_t i;
struct dc_target *target;
struct amdgpu_device *adev = dev->dev_private; struct amdgpu_device *adev = dev->dev_private;
int r = 0; int r = 0;
/* Get freesync enable flag from DRM */ /* Get freesync enable flag from DRM */
num_targets = dc_get_current_target_count(adev->dm.dc); num_streams = dc_get_current_stream_count(adev->dm.dc);
for (i = 0; i < num_targets; i++) { for (i = 0; i < num_streams; i++) {
const struct dc_stream *stream;
target = dc_get_target_at_index(adev->dm.dc, i); stream = dc_get_stream_at_index(adev->dm.dc, i);
mod_freesync_update_state(adev->dm.freesync_module, mod_freesync_update_state(adev->dm.freesync_module,
target->streams, &stream, 1, &freesync_params);
target->stream_count,
&freesync_params);
} }
return r; return r;
......
...@@ -59,7 +59,7 @@ int amdgpu_dm_atomic_commit( ...@@ -59,7 +59,7 @@ int amdgpu_dm_atomic_commit(
int amdgpu_dm_atomic_check(struct drm_device *dev, int amdgpu_dm_atomic_check(struct drm_device *dev,
struct drm_atomic_state *state); struct drm_atomic_state *state);
int dm_create_validation_set_for_target( int dm_create_validation_set_for_stream(
struct drm_connector *connector, struct drm_connector *connector,
struct drm_display_mode *mode, struct drm_display_mode *mode,
struct dc_validation_set *val_set); struct dc_validation_set *val_set);
......
...@@ -13,7 +13,7 @@ AMD_DC = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/dc/,$(DC_LI ...@@ -13,7 +13,7 @@ AMD_DC = $(addsuffix /Makefile, $(addprefix $(FULL_AMD_DISPLAY_PATH)/dc/,$(DC_LI
include $(AMD_DC) include $(AMD_DC)
DISPLAY_CORE = dc.o dc_link.o dc_resource.o dc_hw_sequencer.o dc_target.o dc_sink.o \ DISPLAY_CORE = dc.o dc_link.o dc_resource.o dc_hw_sequencer.o dc_sink.o \
dc_surface.o dc_link_hwss.o dc_link_dp.o dc_link_ddc.o dc_debug.o dc_stream.o dc_surface.o dc_link_hwss.o dc_link_dp.o dc_link_ddc.o dc_debug.o dc_stream.o
AMD_DISPLAY_CORE = $(addprefix $(AMDDALPATH)/dc/core/,$(DISPLAY_CORE)) AMD_DISPLAY_CORE = $(addprefix $(AMDDALPATH)/dc/core/,$(DISPLAY_CORE))
......
...@@ -49,15 +49,6 @@ ...@@ -49,15 +49,6 @@
#include "dm_helpers.h" #include "dm_helpers.h"
#include "mem_input.h" #include "mem_input.h"
/*******************************************************************************
* Private structures
******************************************************************************/
struct dc_target_sync_report {
uint32_t h_count;
uint32_t v_count;
};
/******************************************************************************* /*******************************************************************************
* Private functions * Private functions
******************************************************************************/ ******************************************************************************/
...@@ -221,7 +212,7 @@ static void stream_update_scaling( ...@@ -221,7 +212,7 @@ static void stream_update_scaling(
struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream); struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream);
struct core_dc *core_dc = DC_TO_CORE(dc); struct core_dc *core_dc = DC_TO_CORE(dc);
struct validate_context *cur_ctx = core_dc->current_context; struct validate_context *cur_ctx = core_dc->current_context;
int i, j; int i;
if (src) if (src)
stream->public.src = *src; stream->public.src = *src;
...@@ -229,20 +220,18 @@ static void stream_update_scaling( ...@@ -229,20 +220,18 @@ static void stream_update_scaling(
if (dst) if (dst)
stream->public.dst = *dst; stream->public.dst = *dst;
for (i = 0; i < cur_ctx->target_count; i++) { for (i = 0; i < cur_ctx->stream_count; i++) {
struct core_target *target = cur_ctx->targets[i]; struct core_stream *cur_stream = cur_ctx->streams[i];
struct dc_target_status *status = &cur_ctx->target_status[i];
for (j = 0; j < target->public.stream_count; j++) { if (stream == cur_stream) {
if (target->public.streams[j] != dc_stream) struct dc_stream_status *status = &cur_ctx->stream_status[i];
continue;
if (status->surface_count) if (status->surface_count)
if (!dc_commit_surfaces_to_target( if (!dc_commit_surfaces_to_stream(
&core_dc->public, &core_dc->public,
status->surfaces, status->surfaces,
status->surface_count, status->surface_count,
&target->public)) &cur_stream->public))
/* Need to debug validation */ /* Need to debug validation */
BREAK_TO_DEBUGGER(); BREAK_TO_DEBUGGER();
...@@ -634,7 +623,7 @@ struct dc *dc_create(const struct dc_init_data *init_params) ...@@ -634,7 +623,7 @@ struct dc *dc_create(const struct dc_init_data *init_params)
full_pipe_count = core_dc->res_pool->pipe_count; full_pipe_count = core_dc->res_pool->pipe_count;
if (core_dc->res_pool->underlay_pipe_index >= 0) if (core_dc->res_pool->underlay_pipe_index >= 0)
full_pipe_count--; full_pipe_count--;
core_dc->public.caps.max_targets = min( core_dc->public.caps.max_streams = min(
full_pipe_count, full_pipe_count,
core_dc->res_pool->stream_enc_count); core_dc->res_pool->stream_enc_count);
...@@ -675,20 +664,20 @@ static bool is_validation_required( ...@@ -675,20 +664,20 @@ static bool is_validation_required(
const struct validate_context *context = dc->current_context; const struct validate_context *context = dc->current_context;
int i, j; int i, j;
if (context->target_count != set_count) if (context->stream_count != set_count)
return true; return true;
for (i = 0; i < set_count; i++) { for (i = 0; i < set_count; i++) {
if (set[i].surface_count != context->target_status[i].surface_count) if (set[i].surface_count != context->stream_status[i].surface_count)
return true; return true;
if (!is_target_unchanged(DC_TARGET_TO_CORE(set[i].target), context->targets[i])) if (!is_stream_unchanged(DC_STREAM_TO_CORE(set[i].stream), context->streams[i]))
return true; return true;
for (j = 0; j < set[i].surface_count; j++) { for (j = 0; j < set[i].surface_count; j++) {
struct dc_surface temp_surf = { 0 }; struct dc_surface temp_surf = { 0 };
temp_surf = *context->target_status[i].surfaces[j]; temp_surf = *context->stream_status[i].surfaces[j];
temp_surf.clip_rect = set[i].surfaces[j]->clip_rect; temp_surf.clip_rect = set[i].surfaces[j]->clip_rect;
temp_surf.dst_rect.x = set[i].surfaces[j]->dst_rect.x; temp_surf.dst_rect.x = set[i].surfaces[j]->dst_rect.x;
temp_surf.dst_rect.y = set[i].surfaces[j]->dst_rect.y; temp_surf.dst_rect.y = set[i].surfaces[j]->dst_rect.y;
...@@ -737,7 +726,7 @@ bool dc_validate_resources( ...@@ -737,7 +726,7 @@ bool dc_validate_resources(
bool dc_validate_guaranteed( bool dc_validate_guaranteed(
const struct dc *dc, const struct dc *dc,
const struct dc_target *dc_target) const struct dc_stream *stream)
{ {
struct core_dc *core_dc = DC_TO_CORE(dc); struct core_dc *core_dc = DC_TO_CORE(dc);
enum dc_status result = DC_ERROR_UNEXPECTED; enum dc_status result = DC_ERROR_UNEXPECTED;
...@@ -748,7 +737,7 @@ bool dc_validate_guaranteed( ...@@ -748,7 +737,7 @@ bool dc_validate_guaranteed(
goto context_alloc_fail; goto context_alloc_fail;
result = core_dc->res_pool->funcs->validate_guaranteed( result = core_dc->res_pool->funcs->validate_guaranteed(
core_dc, dc_target, context); core_dc, stream, context);
resource_validate_ctx_destruct(context); resource_validate_ctx_destruct(context);
dm_free(context); dm_free(context);
...@@ -838,18 +827,18 @@ static void program_timing_sync( ...@@ -838,18 +827,18 @@ static void program_timing_sync(
} }
} }
static bool targets_changed( static bool streams_changed(
struct core_dc *dc, struct core_dc *dc,
struct dc_target *targets[], const struct dc_stream *streams[],
uint8_t target_count) uint8_t stream_count)
{ {
uint8_t i; uint8_t i;
if (target_count != dc->current_context->target_count) if (stream_count != dc->current_context->stream_count)
return true; return true;
for (i = 0; i < dc->current_context->target_count; i++) { for (i = 0; i < dc->current_context->stream_count; i++) {
if (&dc->current_context->targets[i]->public != targets[i]) if (&dc->current_context->streams[i]->public != streams[i])
return true; return true;
} }
...@@ -860,74 +849,72 @@ static void fill_display_configs( ...@@ -860,74 +849,72 @@ static void fill_display_configs(
const struct validate_context *context, const struct validate_context *context,
struct dm_pp_display_configuration *pp_display_cfg) struct dm_pp_display_configuration *pp_display_cfg)
{ {
uint8_t i, j, k; int j;
uint8_t num_cfgs = 0; int num_cfgs = 0;
for (i = 0; i < context->target_count; i++) {
const struct core_target *target = context->targets[i];
for (j = 0; j < target->public.stream_count; j++) {
const struct core_stream *stream =
DC_STREAM_TO_CORE(target->public.streams[j]);
struct dm_pp_single_disp_config *cfg =
&pp_display_cfg->disp_configs[num_cfgs];
const struct pipe_ctx *pipe_ctx = NULL;
for (k = 0; k < MAX_PIPES; k++)
if (stream ==
context->res_ctx.pipe_ctx[k].stream) {
pipe_ctx = &context->res_ctx.pipe_ctx[k];
break;
}
ASSERT(pipe_ctx != NULL); for (j = 0; j < context->stream_count; j++) {
int k;
num_cfgs++;
cfg->signal = pipe_ctx->stream->signal; const struct core_stream *stream = context->streams[j];
cfg->pipe_idx = pipe_ctx->pipe_idx; struct dm_pp_single_disp_config *cfg =
cfg->src_height = stream->public.src.height; &pp_display_cfg->disp_configs[num_cfgs];
cfg->src_width = stream->public.src.width; const struct pipe_ctx *pipe_ctx = NULL;
cfg->ddi_channel_mapping =
stream->sink->link->ddi_channel_mapping.raw; for (k = 0; k < MAX_PIPES; k++)
cfg->transmitter = if (stream == context->res_ctx.pipe_ctx[k].stream) {
stream->sink->link->link_enc->transmitter; pipe_ctx = &context->res_ctx.pipe_ctx[k];
cfg->link_settings.lane_count = stream->sink->link->public.cur_link_settings.lane_count; break;
cfg->link_settings.link_rate = stream->sink->link->public.cur_link_settings.link_rate; }
cfg->link_settings.link_spread = stream->sink->link->public.cur_link_settings.link_spread;
cfg->sym_clock = stream->phy_pix_clk; ASSERT(pipe_ctx != NULL);
/* Round v_refresh*/
cfg->v_refresh = stream->public.timing.pix_clk_khz * 1000; num_cfgs++;
cfg->v_refresh /= stream->public.timing.h_total; cfg->signal = pipe_ctx->stream->signal;
cfg->v_refresh = (cfg->v_refresh + stream->public.timing.v_total / 2) cfg->pipe_idx = pipe_ctx->pipe_idx;
/ stream->public.timing.v_total; cfg->src_height = stream->public.src.height;
} cfg->src_width = stream->public.src.width;
cfg->ddi_channel_mapping =
stream->sink->link->ddi_channel_mapping.raw;
cfg->transmitter =
stream->sink->link->link_enc->transmitter;
cfg->link_settings.lane_count =
stream->sink->link->public.cur_link_settings.lane_count;
cfg->link_settings.link_rate =
stream->sink->link->public.cur_link_settings.link_rate;
cfg->link_settings.link_spread =
stream->sink->link->public.cur_link_settings.link_spread;
cfg->sym_clock = stream->phy_pix_clk;
/* Round v_refresh*/
cfg->v_refresh = stream->public.timing.pix_clk_khz * 1000;
cfg->v_refresh /= stream->public.timing.h_total;
cfg->v_refresh = (cfg->v_refresh + stream->public.timing.v_total / 2)
/ stream->public.timing.v_total;
} }
pp_display_cfg->display_count = num_cfgs; pp_display_cfg->display_count = num_cfgs;
} }
static uint32_t get_min_vblank_time_us(const struct validate_context *context) static uint32_t get_min_vblank_time_us(const struct validate_context *context)
{ {
uint8_t i, j; uint8_t j;
uint32_t min_vertical_blank_time = -1; uint32_t min_vertical_blank_time = -1;
for (i = 0; i < context->target_count; i++) { for (j = 0; j < context->stream_count; j++) {
const struct core_target *target = context->targets[i]; const struct dc_stream *stream = &context->streams[j]->public;
for (j = 0; j < target->public.stream_count; j++) {
const struct dc_stream *stream =
target->public.streams[j];
uint32_t vertical_blank_in_pixels = 0; uint32_t vertical_blank_in_pixels = 0;
uint32_t vertical_blank_time = 0; uint32_t vertical_blank_time = 0;
vertical_blank_in_pixels = stream->timing.h_total * vertical_blank_in_pixels = stream->timing.h_total *
(stream->timing.v_total (stream->timing.v_total
- stream->timing.v_addressable); - stream->timing.v_addressable);
vertical_blank_time = vertical_blank_in_pixels vertical_blank_time = vertical_blank_in_pixels
* 1000 / stream->timing.pix_clk_khz; * 1000 / stream->timing.pix_clk_khz;
if (min_vertical_blank_time > vertical_blank_time) if (min_vertical_blank_time > vertical_blank_time)
min_vertical_blank_time = vertical_blank_time; min_vertical_blank_time = vertical_blank_time;
} }
}
return min_vertical_blank_time; return min_vertical_blank_time;
} }
...@@ -995,7 +982,7 @@ void pplib_apply_display_requirements( ...@@ -995,7 +982,7 @@ void pplib_apply_display_requirements(
/* TODO: is this still applicable?*/ /* TODO: is this still applicable?*/
if (pp_display_cfg->display_count == 1) { if (pp_display_cfg->display_count == 1) {
const struct dc_crtc_timing *timing = const struct dc_crtc_timing *timing =
&context->targets[0]->public.streams[0]->timing; &context->streams[0]->public.timing;
pp_display_cfg->crtc_index = pp_display_cfg->crtc_index =
pp_display_cfg->disp_configs[0].pipe_idx; pp_display_cfg->disp_configs[0].pipe_idx;
...@@ -1011,34 +998,32 @@ void pplib_apply_display_requirements( ...@@ -1011,34 +998,32 @@ void pplib_apply_display_requirements(
} }
bool dc_commit_targets( bool dc_commit_streams(
struct dc *dc, struct dc *dc,
struct dc_target *targets[], const struct dc_stream *streams[],
uint8_t target_count) uint8_t stream_count)
{ {
struct core_dc *core_dc = DC_TO_CORE(dc); struct core_dc *core_dc = DC_TO_CORE(dc);
struct dc_bios *dcb = core_dc->ctx->dc_bios; struct dc_bios *dcb = core_dc->ctx->dc_bios;
enum dc_status result = DC_ERROR_UNEXPECTED; enum dc_status result = DC_ERROR_UNEXPECTED;
struct validate_context *context; struct validate_context *context;
struct dc_validation_set set[MAX_TARGETS]; struct dc_validation_set set[MAX_STREAMS];
int i, j, k; int i, j, k;
if (false == targets_changed(core_dc, targets, target_count)) if (false == streams_changed(core_dc, streams, stream_count))
return DC_OK; return DC_OK;
dm_logger_write(core_dc->ctx->logger, LOG_DC, dm_logger_write(core_dc->ctx->logger, LOG_DC, "%s: %d streams\n",
"%s: %d targets\n", __func__, stream_count);
__func__,
target_count);
for (i = 0; i < target_count; i++) { for (i = 0; i < stream_count; i++) {
struct dc_target *target = targets[i]; const struct dc_stream *stream = streams[i];
dc_target_log(target, dc_stream_log(stream,
core_dc->ctx->logger, core_dc->ctx->logger,
LOG_DC); LOG_DC);
set[i].target = targets[i]; set[i].stream = stream;
set[i].surface_count = 0; set[i].surface_count = 0;
} }
...@@ -1047,7 +1032,7 @@ bool dc_commit_targets( ...@@ -1047,7 +1032,7 @@ bool dc_commit_targets(
if (context == NULL) if (context == NULL)
goto context_alloc_fail; goto context_alloc_fail;
result = core_dc->res_pool->funcs->validate_with_context(core_dc, set, target_count, context); result = core_dc->res_pool->funcs->validate_with_context(core_dc, set, stream_count, context);
if (result != DC_OK){ if (result != DC_OK){
dm_logger_write(core_dc->ctx->logger, LOG_ERROR, dm_logger_write(core_dc->ctx->logger, LOG_ERROR,
"%s: Context validation failed! dc_status:%d\n", "%s: Context validation failed! dc_status:%d\n",
...@@ -1068,13 +1053,12 @@ bool dc_commit_targets( ...@@ -1068,13 +1053,12 @@ bool dc_commit_targets(
program_timing_sync(core_dc, context); program_timing_sync(core_dc, context);
for (i = 0; i < context->target_count; i++) { for (i = 0; i < context->stream_count; i++) {
struct dc_target *dc_target = &context->targets[i]->public; const struct core_sink *sink = context->streams[i]->sink;
struct core_sink *sink = DC_SINK_TO_CORE(dc_target->streams[0]->sink);
for (j = 0; j < context->target_status[i].surface_count; j++) { for (j = 0; j < context->stream_status[i].surface_count; j++) {
const struct dc_surface *dc_surface = const struct dc_surface *dc_surface =
context->target_status[i].surfaces[j]; context->stream_status[i].surfaces[j];
for (k = 0; k < context->res_ctx.pool->pipe_count; k++) { for (k = 0; k < context->res_ctx.pool->pipe_count; k++) {
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[k]; struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[k];
...@@ -1088,11 +1072,11 @@ bool dc_commit_targets( ...@@ -1088,11 +1072,11 @@ bool dc_commit_targets(
} }
CONN_MSG_MODE(sink->link, "{%dx%d, %dx%d@%dKhz}", CONN_MSG_MODE(sink->link, "{%dx%d, %dx%d@%dKhz}",
dc_target->streams[0]->timing.h_addressable, context->streams[i]->public.timing.h_addressable,
dc_target->streams[0]->timing.v_addressable, context->streams[i]->public.timing.v_addressable,
dc_target->streams[0]->timing.h_total, context->streams[i]->public.timing.h_total,
dc_target->streams[0]->timing.v_total, context->streams[i]->public.timing.v_total,
dc_target->streams[0]->timing.pix_clk_khz); context->streams[i]->public.timing.pix_clk_khz);
} }
pplib_apply_display_requirements(core_dc, pplib_apply_display_requirements(core_dc,
...@@ -1116,43 +1100,42 @@ bool dc_commit_targets( ...@@ -1116,43 +1100,42 @@ bool dc_commit_targets(
return (result == DC_OK); return (result == DC_OK);
} }
bool dc_pre_update_surfaces_to_target( bool dc_pre_update_surfaces_to_stream(
struct dc *dc, struct dc *dc,
const struct dc_surface *const *new_surfaces, const struct dc_surface *const *new_surfaces,
uint8_t new_surface_count, uint8_t new_surface_count,
struct dc_target *dc_target) const struct dc_stream *dc_stream)
{ {
int i, j; int i, j;
struct core_dc *core_dc = DC_TO_CORE(dc); struct core_dc *core_dc = DC_TO_CORE(dc);
uint32_t prev_disp_clk = core_dc->current_context->bw_results.dispclk_khz; uint32_t prev_disp_clk = core_dc->current_context->bw_results.dispclk_khz;
struct core_target *target = DC_TARGET_TO_CORE(dc_target); struct dc_stream_status *stream_status = NULL;
struct dc_target_status *target_status = NULL;
struct validate_context *context; struct validate_context *context;
struct validate_context *temp_context; struct validate_context *temp_context;
bool ret = true; bool ret = true;
pre_surface_trace(dc, new_surfaces, new_surface_count); pre_surface_trace(dc, new_surfaces, new_surface_count);
if (core_dc->current_context->target_count == 0) if (core_dc->current_context->stream_count == 0)
return false; return false;
/* Cannot commit surface to a target that is not commited */ /* Cannot commit surface to a stream that is not commited */
for (i = 0; i < core_dc->current_context->target_count; i++) for (i = 0; i < core_dc->current_context->stream_count; i++)
if (target == core_dc->current_context->targets[i]) if (dc_stream == &core_dc->current_context->streams[i]->public)
break; break;
if (i == core_dc->current_context->target_count) if (i == core_dc->current_context->stream_count)
return false; return false;
target_status = &core_dc->current_context->target_status[i]; stream_status = &core_dc->current_context->stream_status[i];
if (new_surface_count == target_status->surface_count) { if (new_surface_count == stream_status->surface_count) {
bool skip_pre = true; bool skip_pre = true;
for (i = 0; i < target_status->surface_count; i++) { for (i = 0; i < stream_status->surface_count; i++) {
struct dc_surface temp_surf = { 0 }; struct dc_surface temp_surf = { 0 };
temp_surf = *target_status->surfaces[i]; temp_surf = *stream_status->surfaces[i];
temp_surf.clip_rect = new_surfaces[i]->clip_rect; temp_surf.clip_rect = new_surfaces[i]->clip_rect;
temp_surf.dst_rect.x = new_surfaces[i]->dst_rect.x; temp_surf.dst_rect.x = new_surfaces[i]->dst_rect.x;
temp_surf.dst_rect.y = new_surfaces[i]->dst_rect.y; temp_surf.dst_rect.y = new_surfaces[i]->dst_rect.y;
...@@ -1178,13 +1161,13 @@ bool dc_pre_update_surfaces_to_target( ...@@ -1178,13 +1161,13 @@ bool dc_pre_update_surfaces_to_target(
resource_validate_ctx_copy_construct(core_dc->current_context, context); resource_validate_ctx_copy_construct(core_dc->current_context, context);
dm_logger_write(core_dc->ctx->logger, LOG_DC, dm_logger_write(core_dc->ctx->logger, LOG_DC,
"%s: commit %d surfaces to target 0x%x\n", "%s: commit %d surfaces to stream 0x%x\n",
__func__, __func__,
new_surface_count, new_surface_count,
dc_target); dc_stream);
if (!resource_attach_surfaces_to_context( if (!resource_attach_surfaces_to_context(
new_surfaces, new_surface_count, dc_target, context)) { new_surfaces, new_surface_count, dc_stream, context)) {
BREAK_TO_DEBUGGER(); BREAK_TO_DEBUGGER();
ret = false; ret = false;
goto unexpected_fail; goto unexpected_fail;
...@@ -1256,7 +1239,7 @@ bool dc_pre_update_surfaces_to_target( ...@@ -1256,7 +1239,7 @@ bool dc_pre_update_surfaces_to_target(
return ret; return ret;
} }
bool dc_post_update_surfaces_to_target(struct dc *dc) bool dc_post_update_surfaces_to_stream(struct dc *dc)
{ {
struct core_dc *core_dc = DC_TO_CORE(dc); struct core_dc *core_dc = DC_TO_CORE(dc);
int i; int i;
...@@ -1282,22 +1265,27 @@ bool dc_post_update_surfaces_to_target(struct dc *dc) ...@@ -1282,22 +1265,27 @@ bool dc_post_update_surfaces_to_target(struct dc *dc)
return true; return true;
} }
bool dc_commit_surfaces_to_target( bool dc_commit_surfaces_to_stream(
struct dc *dc, struct dc *dc,
const struct dc_surface **new_surfaces, const struct dc_surface **new_surfaces,
uint8_t new_surface_count, uint8_t new_surface_count,
struct dc_target *dc_target) const struct dc_stream *dc_stream)
{ {
struct dc_surface_update updates[MAX_SURFACES] = { 0 }; struct dc_surface_update updates[MAX_SURFACES];
struct dc_flip_addrs flip_addr[MAX_SURFACES] = { 0 }; struct dc_flip_addrs flip_addr[MAX_SURFACES];
struct dc_plane_info plane_info[MAX_SURFACES] = { 0 }; struct dc_plane_info plane_info[MAX_SURFACES];
struct dc_scaling_info scaling_info[MAX_SURFACES] = { 0 }; struct dc_scaling_info scaling_info[MAX_SURFACES];
int i; int i;
if (!dc_pre_update_surfaces_to_target( if (!dc_pre_update_surfaces_to_stream(
dc, new_surfaces, new_surface_count, dc_target)) dc, new_surfaces, new_surface_count, dc_stream))
return false; return false;
memset(updates, 0, sizeof(updates));
memset(flip_addr, 0, sizeof(flip_addr));
memset(plane_info, 0, sizeof(plane_info));
memset(scaling_info, 0, sizeof(scaling_info));
for (i = 0; i < new_surface_count; i++) { for (i = 0; i < new_surface_count; i++) {
updates[i].surface = new_surfaces[i]; updates[i].surface = new_surfaces[i];
updates[i].gamma = updates[i].gamma =
...@@ -1321,13 +1309,13 @@ bool dc_commit_surfaces_to_target( ...@@ -1321,13 +1309,13 @@ bool dc_commit_surfaces_to_target(
updates[i].plane_info = &plane_info[i]; updates[i].plane_info = &plane_info[i];
updates[i].scaling_info = &scaling_info[i]; updates[i].scaling_info = &scaling_info[i];
} }
dc_update_surfaces_for_target(dc, updates, new_surface_count, dc_target); dc_update_surfaces_for_stream(dc, updates, new_surface_count, dc_stream);
return dc_post_update_surfaces_to_target(dc); return dc_post_update_surfaces_to_stream(dc);
} }
void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *updates, void dc_update_surfaces_for_stream(struct dc *dc, struct dc_surface_update *updates,
int surface_count, struct dc_target *dc_target) int surface_count, const struct dc_stream *dc_stream)
{ {
struct core_dc *core_dc = DC_TO_CORE(dc); struct core_dc *core_dc = DC_TO_CORE(dc);
struct validate_context *context = core_dc->temp_flip_context; struct validate_context *context = core_dc->temp_flip_context;
...@@ -1377,21 +1365,21 @@ void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *upda ...@@ -1377,21 +1365,21 @@ void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *upda
can_skip_context_building = false; can_skip_context_building = false;
} }
if (!can_skip_context_building && dc_target) { if (!can_skip_context_building && dc_stream) {
struct core_target *target = DC_TARGET_TO_CORE(dc_target); const struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream);
if (core_dc->current_context->target_count == 0) if (core_dc->current_context->stream_count == 0)
return; return;
/* Cannot commit surface to a target that is not commited */ /* Cannot commit surface to a stream that is not commited */
for (i = 0; i < core_dc->current_context->target_count; i++) for (i = 0; i < core_dc->current_context->stream_count; i++)
if (target == core_dc->current_context->targets[i]) if (stream == core_dc->current_context->streams[i])
break; break;
if (i == core_dc->current_context->target_count) if (i == core_dc->current_context->stream_count)
return; return;
if (!resource_attach_surfaces_to_context( if (!resource_attach_surfaces_to_context(
new_surfaces, surface_count, dc_target, context)) { new_surfaces, surface_count, dc_stream, context)) {
BREAK_TO_DEBUGGER(); BREAK_TO_DEBUGGER();
return; return;
} }
...@@ -1578,17 +1566,17 @@ void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *upda ...@@ -1578,17 +1566,17 @@ void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *upda
core_dc->current_context = context; core_dc->current_context = context;
} }
uint8_t dc_get_current_target_count(const struct dc *dc) uint8_t dc_get_current_stream_count(const struct dc *dc)
{ {
struct core_dc *core_dc = DC_TO_CORE(dc); struct core_dc *core_dc = DC_TO_CORE(dc);
return core_dc->current_context->target_count; return core_dc->current_context->stream_count;
} }
struct dc_target *dc_get_target_at_index(const struct dc *dc, uint8_t i) struct dc_stream *dc_get_stream_at_index(const struct dc *dc, uint8_t i)
{ {
struct core_dc *core_dc = DC_TO_CORE(dc); struct core_dc *core_dc = DC_TO_CORE(dc);
if (i < core_dc->current_context->target_count) if (i < core_dc->current_context->stream_count)
return &(core_dc->current_context->targets[i]->public); return &(core_dc->current_context->streams[i]->public);
return NULL; return NULL;
} }
...@@ -1687,8 +1675,8 @@ void dc_set_power_state( ...@@ -1687,8 +1675,8 @@ void dc_set_power_state(
core_dc->hwss.init_hw(core_dc); core_dc->hwss.init_hw(core_dc);
break; break;
default: default:
/* NULL means "reset/release all DC targets" */ /* NULL means "reset/release all DC streams" */
dc_commit_targets(dc, NULL, 0); dc_commit_streams(dc, NULL, 0);
core_dc->hwss.power_down(core_dc); core_dc->hwss.power_down(core_dc);
...@@ -1882,11 +1870,3 @@ void dc_link_remove_remote_sink(const struct dc_link *link, const struct dc_sink ...@@ -1882,11 +1870,3 @@ void dc_link_remove_remote_sink(const struct dc_link *link, const struct dc_sink
} }
} }
const struct dc_stream_status *dc_stream_get_status(
const struct dc_stream *dc_stream)
{
struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream);
return &stream->status;
}
...@@ -591,12 +591,12 @@ enum dc_status resource_build_scaling_params_for_context( ...@@ -591,12 +591,12 @@ enum dc_status resource_build_scaling_params_for_context(
return DC_OK; return DC_OK;
} }
static void detach_surfaces_for_target( static void detach_surfaces_for_stream(
struct validate_context *context, struct validate_context *context,
const struct dc_target *dc_target) const struct dc_stream *dc_stream)
{ {
int i; int i;
struct core_stream *stream = DC_STREAM_TO_CORE(dc_target->streams[0]); struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream);
for (i = 0; i < context->res_ctx.pool->pipe_count; i++) { for (i = 0; i < context->res_ctx.pool->pipe_count; i++) {
struct pipe_ctx *cur_pipe = &context->res_ctx.pipe_ctx[i]; struct pipe_ctx *cur_pipe = &context->res_ctx.pipe_ctx[i];
...@@ -646,15 +646,15 @@ struct pipe_ctx *resource_get_head_pipe_for_stream( ...@@ -646,15 +646,15 @@ struct pipe_ctx *resource_get_head_pipe_for_stream(
} }
/* /*
* A free_pipe for a target is defined here as a pipe with a stream that belongs * A free_pipe for a stream is defined here as a pipe
* to the target but has no surface attached yet * that has no surface attached yet
*/ */
static struct pipe_ctx *acquire_free_pipe_for_target( static struct pipe_ctx *acquire_free_pipe_for_stream(
struct resource_context *res_ctx, struct resource_context *res_ctx,
const struct dc_target *dc_target) const struct dc_stream *dc_stream)
{ {
int i; int i;
struct core_stream *stream = DC_STREAM_TO_CORE(dc_target->streams[0]); struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream);
struct pipe_ctx *head_pipe = NULL; struct pipe_ctx *head_pipe = NULL;
...@@ -688,12 +688,12 @@ static struct pipe_ctx *acquire_free_pipe_for_target( ...@@ -688,12 +688,12 @@ static struct pipe_ctx *acquire_free_pipe_for_target(
} }
static void release_free_pipes_for_target( static void release_free_pipes_for_stream(
struct resource_context *res_ctx, struct resource_context *res_ctx,
const struct dc_target *dc_target) const struct dc_stream *dc_stream)
{ {
int i; int i;
struct core_stream *stream = DC_STREAM_TO_CORE(dc_target->streams[0]); struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream);
for (i = res_ctx->pool->pipe_count - 1; i >= 0; i--) { for (i = res_ctx->pool->pipe_count - 1; i >= 0; i--) {
if (res_ctx->pipe_ctx[i].stream == stream && if (res_ctx->pipe_ctx[i].stream == stream &&
...@@ -706,12 +706,12 @@ static void release_free_pipes_for_target( ...@@ -706,12 +706,12 @@ static void release_free_pipes_for_target(
bool resource_attach_surfaces_to_context( bool resource_attach_surfaces_to_context(
const struct dc_surface * const *surfaces, const struct dc_surface * const *surfaces,
int surface_count, int surface_count,
const struct dc_target *dc_target, const struct dc_stream *dc_stream,
struct validate_context *context) struct validate_context *context)
{ {
int i; int i;
struct pipe_ctx *tail_pipe; struct pipe_ctx *tail_pipe;
struct dc_target_status *target_status = NULL; struct dc_stream_status *stream_status = NULL;
if (surface_count > MAX_SURFACE_NUM) { if (surface_count > MAX_SURFACE_NUM) {
...@@ -720,13 +720,13 @@ bool resource_attach_surfaces_to_context( ...@@ -720,13 +720,13 @@ bool resource_attach_surfaces_to_context(
return false; return false;
} }
for (i = 0; i < context->target_count; i++) for (i = 0; i < context->stream_count; i++)
if (&context->targets[i]->public == dc_target) { if (&context->streams[i]->public == dc_stream) {
target_status = &context->target_status[i]; stream_status = &context->stream_status[i];
break; break;
} }
if (target_status == NULL) { if (stream_status == NULL) {
dm_error("Existing target not found; failed to attach surfaces\n"); dm_error("Existing stream not found; failed to attach surfaces\n");
return false; return false;
} }
...@@ -734,16 +734,16 @@ bool resource_attach_surfaces_to_context( ...@@ -734,16 +734,16 @@ bool resource_attach_surfaces_to_context(
for (i = 0; i < surface_count; i++) for (i = 0; i < surface_count; i++)
dc_surface_retain(surfaces[i]); dc_surface_retain(surfaces[i]);
detach_surfaces_for_target(context, dc_target); detach_surfaces_for_stream(context, dc_stream);
/* release existing surfaces*/ /* release existing surfaces*/
for (i = 0; i < target_status->surface_count; i++) for (i = 0; i < stream_status->surface_count; i++)
dc_surface_release(target_status->surfaces[i]); dc_surface_release(stream_status->surfaces[i]);
for (i = surface_count; i < target_status->surface_count; i++) for (i = surface_count; i < stream_status->surface_count; i++)
target_status->surfaces[i] = NULL; stream_status->surfaces[i] = NULL;
target_status->surface_count = 0; stream_status->surface_count = 0;
if (surface_count == 0) if (surface_count == 0)
return true; return true;
...@@ -751,11 +751,11 @@ bool resource_attach_surfaces_to_context( ...@@ -751,11 +751,11 @@ bool resource_attach_surfaces_to_context(
tail_pipe = NULL; tail_pipe = NULL;
for (i = 0; i < surface_count; i++) { for (i = 0; i < surface_count; i++) {
struct core_surface *surface = DC_SURFACE_TO_CORE(surfaces[i]); struct core_surface *surface = DC_SURFACE_TO_CORE(surfaces[i]);
struct pipe_ctx *free_pipe = acquire_free_pipe_for_target( struct pipe_ctx *free_pipe = acquire_free_pipe_for_stream(
&context->res_ctx, dc_target); &context->res_ctx, dc_stream);
if (!free_pipe) { if (!free_pipe) {
target_status->surfaces[i] = NULL; stream_status->surfaces[i] = NULL;
return false; return false;
} }
...@@ -769,13 +769,13 @@ bool resource_attach_surfaces_to_context( ...@@ -769,13 +769,13 @@ bool resource_attach_surfaces_to_context(
tail_pipe = free_pipe; tail_pipe = free_pipe;
} }
release_free_pipes_for_target(&context->res_ctx, dc_target); release_free_pipes_for_stream(&context->res_ctx, dc_stream);
/* assign new surfaces*/ /* assign new surfaces*/
for (i = 0; i < surface_count; i++) for (i = 0; i < surface_count; i++)
target_status->surfaces[i] = surfaces[i]; stream_status->surfaces[i] = surfaces[i];
target_status->surface_count = surface_count; stream_status->surface_count = surface_count;
return true; return true;
} }
...@@ -819,25 +819,14 @@ static bool are_stream_backends_same( ...@@ -819,25 +819,14 @@ static bool are_stream_backends_same(
return true; return true;
} }
bool is_target_unchanged( bool is_stream_unchanged(
const struct core_target *old_target, const struct core_target *target) const struct core_stream *old_stream, const struct core_stream *stream)
{ {
int i; if (old_stream == stream)
if (old_target == target)
return true; return true;
if (old_target->public.stream_count != target->public.stream_count)
return false;
for (i = 0; i < old_target->public.stream_count; i++) {
const struct core_stream *old_stream = DC_STREAM_TO_CORE(
old_target->public.streams[i]);
const struct core_stream *stream = DC_STREAM_TO_CORE(
target->public.streams[i]);
if (!are_stream_backends_same(old_stream, stream)) if (!are_stream_backends_same(old_stream, stream))
return false; return false;
}
return true; return true;
} }
...@@ -851,23 +840,23 @@ bool resource_validate_attach_surfaces( ...@@ -851,23 +840,23 @@ bool resource_validate_attach_surfaces(
int i, j; int i, j;
for (i = 0; i < set_count; i++) { for (i = 0; i < set_count; i++) {
for (j = 0; j < old_context->target_count; j++) for (j = 0; j < old_context->stream_count; j++)
if (is_target_unchanged( if (is_stream_unchanged(
old_context->targets[j], old_context->streams[j],
context->targets[i])) { context->streams[i])) {
if (!resource_attach_surfaces_to_context( if (!resource_attach_surfaces_to_context(
old_context->target_status[j].surfaces, old_context->stream_status[j].surfaces,
old_context->target_status[j].surface_count, old_context->stream_status[j].surface_count,
&context->targets[i]->public, &context->streams[i]->public,
context)) context))
return false; return false;
context->target_status[i] = old_context->target_status[j]; context->stream_status[i] = old_context->stream_status[j];
} }
if (set[i].surface_count != 0) if (set[i].surface_count != 0)
if (!resource_attach_surfaces_to_context( if (!resource_attach_surfaces_to_context(
set[i].surfaces, set[i].surfaces,
set[i].surface_count, set[i].surface_count,
&context->targets[i]->public, &context->streams[i]->public,
context)) context))
return false; return false;
...@@ -1001,20 +990,15 @@ static void update_stream_signal(struct core_stream *stream) ...@@ -1001,20 +990,15 @@ static void update_stream_signal(struct core_stream *stream)
} }
bool resource_is_stream_unchanged( bool resource_is_stream_unchanged(
const struct validate_context *old_context, struct core_stream *stream) const struct validate_context *old_context, const struct core_stream *stream)
{ {
int i, j; int i;
for (i = 0; i < old_context->target_count; i++) {
struct core_target *old_target = old_context->targets[i];
for (j = 0; j < old_target->public.stream_count; j++) { for (i = 0; i < old_context->stream_count; i++) {
struct core_stream *old_stream = const struct core_stream *old_stream = old_context->streams[i];
DC_STREAM_TO_CORE(old_target->public.streams[j]);
if (are_stream_backends_same(old_stream, stream)) if (are_stream_backends_same(old_stream, stream))
return true; return true;
}
} }
return false; return false;
...@@ -1036,23 +1020,19 @@ static struct core_stream *find_pll_sharable_stream( ...@@ -1036,23 +1020,19 @@ static struct core_stream *find_pll_sharable_stream(
const struct core_stream *stream_needs_pll, const struct core_stream *stream_needs_pll,
struct validate_context *context) struct validate_context *context)
{ {
int i, j; int i;
for (i = 0; i < context->target_count; i++) { for (i = 0; i < context->stream_count; i++) {
struct core_target *target = context->targets[i]; struct core_stream *stream_has_pll = context->streams[i];
for (j = 0; j < target->public.stream_count; j++) { /* We are looking for non dp, non virtual stream */
struct core_stream *stream_has_pll = if (resource_are_streams_timing_synchronizable(
DC_STREAM_TO_CORE(target->public.streams[j]); stream_needs_pll, stream_has_pll)
&& !dc_is_dp_signal(stream_has_pll->signal)
&& stream_has_pll->sink->link->public.connector_signal
!= SIGNAL_TYPE_VIRTUAL)
return stream_has_pll;
/* We are looking for non dp, non virtual stream */
if (resource_are_streams_timing_synchronizable(
stream_needs_pll, stream_has_pll)
&& !dc_is_dp_signal(stream_has_pll->signal)
&& stream_has_pll->sink->link->public.connector_signal
!= SIGNAL_TYPE_VIRTUAL)
return stream_has_pll;
}
} }
return NULL; return NULL;
...@@ -1091,25 +1071,20 @@ static void calculate_phy_pix_clks( ...@@ -1091,25 +1071,20 @@ static void calculate_phy_pix_clks(
const struct core_dc *dc, const struct core_dc *dc,
struct validate_context *context) struct validate_context *context)
{ {
int i, j; int i;
for (i = 0; i < context->target_count; i++) {
struct core_target *target = context->targets[i];
for (j = 0; j < target->public.stream_count; j++) { for (i = 0; i < context->stream_count; i++) {
struct core_stream *stream = struct core_stream *stream = context->streams[i];
DC_STREAM_TO_CORE(target->public.streams[j]);
update_stream_signal(stream); update_stream_signal(stream);
/* update actual pixel clock on all streams */ /* update actual pixel clock on all streams */
if (dc_is_hdmi_signal(stream->signal)) if (dc_is_hdmi_signal(stream->signal))
stream->phy_pix_clk = get_norm_pix_clk( stream->phy_pix_clk = get_norm_pix_clk(
&stream->public.timing); &stream->public.timing);
else else
stream->phy_pix_clk = stream->phy_pix_clk =
stream->public.timing.pix_clk_khz; stream->public.timing.pix_clk_khz;
}
} }
} }
...@@ -1117,136 +1092,122 @@ enum dc_status resource_map_pool_resources( ...@@ -1117,136 +1092,122 @@ enum dc_status resource_map_pool_resources(
const struct core_dc *dc, const struct core_dc *dc,
struct validate_context *context) struct validate_context *context)
{ {
int i, j, k; int i, j;
calculate_phy_pix_clks(dc, context); calculate_phy_pix_clks(dc, context);
for (i = 0; i < context->target_count; i++) { for (i = 0; i < context->stream_count; i++) {
struct core_target *target = context->targets[i]; struct core_stream *stream = context->streams[i];
for (j = 0; j < target->public.stream_count; j++) {
struct core_stream *stream =
DC_STREAM_TO_CORE(target->public.streams[j]);
if (!resource_is_stream_unchanged(dc->current_context, stream))
continue;
/* mark resources used for stream that is already active */
for (k = 0; k < MAX_PIPES; k++) {
struct pipe_ctx *pipe_ctx =
&context->res_ctx.pipe_ctx[k];
const struct pipe_ctx *old_pipe_ctx =
&dc->current_context->res_ctx.pipe_ctx[k];
if (!are_stream_backends_same(old_pipe_ctx->stream, stream)) if (!resource_is_stream_unchanged(dc->current_context, stream))
continue; continue;
pipe_ctx->stream = stream; /* mark resources used for stream that is already active */
copy_pipe_ctx(old_pipe_ctx, pipe_ctx); for (j = 0; j < MAX_PIPES; j++) {
struct pipe_ctx *pipe_ctx =
&context->res_ctx.pipe_ctx[j];
const struct pipe_ctx *old_pipe_ctx =
&dc->current_context->res_ctx.pipe_ctx[j];
/* Split pipe resource, do not acquire back end */ if (!are_stream_backends_same(old_pipe_ctx->stream, stream))
if (!pipe_ctx->stream_enc) continue;
continue;
set_stream_engine_in_use( pipe_ctx->stream = stream;
&context->res_ctx, copy_pipe_ctx(old_pipe_ctx, pipe_ctx);
pipe_ctx->stream_enc);
/* Switch to dp clock source only if there is
* no non dp stream that shares the same timing
* with the dp stream.
*/
if (dc_is_dp_signal(pipe_ctx->stream->signal) &&
!find_pll_sharable_stream(stream, context))
pipe_ctx->clock_source =
context->res_ctx.pool->dp_clock_source;
resource_reference_clock_source( /* Split pipe resource, do not acquire back end */
&context->res_ctx, if (!pipe_ctx->stream_enc)
pipe_ctx->clock_source); continue;
set_audio_in_use(&context->res_ctx, set_stream_engine_in_use(
pipe_ctx->audio); &context->res_ctx,
} pipe_ctx->stream_enc);
/* Switch to dp clock source only if there is
* no non dp stream that shares the same timing
* with the dp stream.
*/
if (dc_is_dp_signal(pipe_ctx->stream->signal) &&
!find_pll_sharable_stream(stream, context))
pipe_ctx->clock_source =
context->res_ctx.pool->dp_clock_source;
resource_reference_clock_source(
&context->res_ctx,
pipe_ctx->clock_source);
set_audio_in_use(&context->res_ctx,
pipe_ctx->audio);
} }
} }
for (i = 0; i < context->target_count; i++) { for (i = 0; i < context->stream_count; i++) {
struct core_target *target = context->targets[i]; struct core_stream *stream = context->streams[i];
struct pipe_ctx *pipe_ctx = NULL;
for (j = 0; j < target->public.stream_count; j++) { int pipe_idx = -1;
struct core_stream *stream =
DC_STREAM_TO_CORE(target->public.streams[j]);
struct pipe_ctx *pipe_ctx = NULL;
int pipe_idx = -1;
if (resource_is_stream_unchanged(dc->current_context, stream))
continue;
/* acquire new resources */
pipe_idx = acquire_first_free_pipe(
&context->res_ctx, stream);
if (pipe_idx < 0)
return DC_NO_CONTROLLER_RESOURCE;
pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
pipe_ctx->stream_enc = if (resource_is_stream_unchanged(dc->current_context, stream))
find_first_free_match_stream_enc_for_link( continue;
&context->res_ctx, stream); /* acquire new resources */
pipe_idx = acquire_first_free_pipe(&context->res_ctx, stream);
if (!pipe_ctx->stream_enc) if (pipe_idx < 0)
return DC_NO_STREAM_ENG_RESOURCE; return DC_NO_CONTROLLER_RESOURCE;
set_stream_engine_in_use(
pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx];
pipe_ctx->stream_enc =
find_first_free_match_stream_enc_for_link(
&context->res_ctx, stream);
if (!pipe_ctx->stream_enc)
return DC_NO_STREAM_ENG_RESOURCE;
set_stream_engine_in_use(
&context->res_ctx,
pipe_ctx->stream_enc);
/* TODO: Add check if ASIC support and EDID audio */
if (!stream->sink->converter_disable_audio &&
dc_is_audio_capable_signal(pipe_ctx->stream->signal) &&
stream->public.audio_info.mode_count) {
pipe_ctx->audio = find_first_free_audio(
&context->res_ctx);
/*
* Audio assigned in order first come first get.
* There are asics which has number of audio
* resources less then number of pipes
*/
if (pipe_ctx->audio)
set_audio_in_use(
&context->res_ctx, &context->res_ctx,
pipe_ctx->stream_enc); pipe_ctx->audio);
/* TODO: Add check if ASIC support and EDID audio */
if (!stream->sink->converter_disable_audio &&
dc_is_audio_capable_signal(pipe_ctx->stream->signal) &&
stream->public.audio_info.mode_count) {
pipe_ctx->audio = find_first_free_audio(
&context->res_ctx);
/*
* Audio assigned in order first come first get.
* There are asics which has number of audio
* resources less then number of pipes
*/
if (pipe_ctx->audio)
set_audio_in_use(
&context->res_ctx,
pipe_ctx->audio);
}
if (j == 0) {
context->target_status[i].primary_otg_inst =
pipe_ctx->tg->inst;
}
} }
context->stream_status[i].primary_otg_inst = pipe_ctx->tg->inst;
} }
return DC_OK; return DC_OK;
} }
/* first target in the context is used to populate the rest */ /* first stream in the context is used to populate the rest */
void validate_guaranteed_copy_target( void validate_guaranteed_copy_streams(
struct validate_context *context, struct validate_context *context,
int max_targets) int max_streams)
{ {
int i; int i;
for (i = 1; i < max_targets; i++) { for (i = 1; i < max_streams; i++) {
context->targets[i] = context->targets[0]; context->streams[i] = context->streams[0];
copy_pipe_ctx(&context->res_ctx.pipe_ctx[0], copy_pipe_ctx(&context->res_ctx.pipe_ctx[0],
&context->res_ctx.pipe_ctx[i]); &context->res_ctx.pipe_ctx[i]);
context->res_ctx.pipe_ctx[i].stream = context->res_ctx.pipe_ctx[i].stream =
context->res_ctx.pipe_ctx[0].stream; context->res_ctx.pipe_ctx[0].stream;
dc_target_retain(&context->targets[i]->public); dc_stream_retain(&context->streams[i]->public);
context->target_count++; context->stream_count++;
} }
} }
...@@ -1875,18 +1836,19 @@ void resource_validate_ctx_destruct(struct validate_context *context) ...@@ -1875,18 +1836,19 @@ void resource_validate_ctx_destruct(struct validate_context *context)
{ {
int i, j; int i, j;
for (i = 0; i < context->target_count; i++) { for (i = 0; i < context->stream_count; i++) {
for (j = 0; j < context->target_status[i].surface_count; j++) for (j = 0; j < context->stream_status[i].surface_count; j++)
dc_surface_release( dc_surface_release(
context->target_status[i].surfaces[j]); context->stream_status[i].surfaces[j]);
context->target_status[i].surface_count = 0; context->stream_status[i].surface_count = 0;
dc_target_release(&context->targets[i]->public); dc_stream_release(&context->streams[i]->public);
context->streams[i] = NULL;
} }
} }
/* /*
* Copy src_ctx into dst_ctx and retain all surfaces and targets referenced * Copy src_ctx into dst_ctx and retain all surfaces and streams referenced
* by the src_ctx * by the src_ctx
*/ */
void resource_validate_ctx_copy_construct( void resource_validate_ctx_copy_construct(
...@@ -1908,11 +1870,11 @@ void resource_validate_ctx_copy_construct( ...@@ -1908,11 +1870,11 @@ void resource_validate_ctx_copy_construct(
} }
for (i = 0; i < dst_ctx->target_count; i++) { for (i = 0; i < dst_ctx->stream_count; i++) {
dc_target_retain(&dst_ctx->targets[i]->public); dc_stream_retain(&dst_ctx->streams[i]->public);
for (j = 0; j < dst_ctx->target_status[i].surface_count; j++) for (j = 0; j < dst_ctx->stream_status[i].surface_count; j++)
dc_surface_retain( dc_surface_retain(
dst_ctx->target_status[i].surfaces[j]); dst_ctx->stream_status[i].surfaces[j]);
} }
} }
...@@ -1968,53 +1930,48 @@ enum dc_status resource_map_clock_resources( ...@@ -1968,53 +1930,48 @@ enum dc_status resource_map_clock_resources(
const struct core_dc *dc, const struct core_dc *dc,
struct validate_context *context) struct validate_context *context)
{ {
int i, j, k; int i, j;
/* acquire new resources */ /* acquire new resources */
for (i = 0; i < context->target_count; i++) { for (i = 0; i < context->stream_count; i++) {
struct core_target *target = context->targets[i]; const struct core_stream *stream = context->streams[i];
for (j = 0; j < target->public.stream_count; j++) { if (resource_is_stream_unchanged(dc->current_context, stream))
struct core_stream *stream = continue;
DC_STREAM_TO_CORE(target->public.streams[j]);
for (j = 0; j < MAX_PIPES; j++) {
struct pipe_ctx *pipe_ctx =
&context->res_ctx.pipe_ctx[j];
if (resource_is_stream_unchanged(dc->current_context, stream)) if (context->res_ctx.pipe_ctx[j].stream != stream)
continue; continue;
for (k = 0; k < MAX_PIPES; k++) { if (dc_is_dp_signal(pipe_ctx->stream->signal)
struct pipe_ctx *pipe_ctx = || pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL)
&context->res_ctx.pipe_ctx[k]; pipe_ctx->clock_source =
context->res_ctx.pool->dp_clock_source;
else {
pipe_ctx->clock_source = NULL;
if (context->res_ctx.pipe_ctx[k].stream != stream) if (!dc->public.config.disable_disp_pll_sharing)
continue; resource_find_used_clk_src_for_sharing(
&context->res_ctx,
pipe_ctx);
if (dc_is_dp_signal(pipe_ctx->stream->signal) if (pipe_ctx->clock_source == NULL)
|| pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL)
pipe_ctx->clock_source = pipe_ctx->clock_source =
context->res_ctx.pool->dp_clock_source; dc_resource_find_first_free_pll(&context->res_ctx);
else { }
pipe_ctx->clock_source = NULL;
if (!dc->public.config.disable_disp_pll_sharing)
resource_find_used_clk_src_for_sharing(
&context->res_ctx,
pipe_ctx);
if (pipe_ctx->clock_source == NULL)
pipe_ctx->clock_source =
dc_resource_find_first_free_pll(&context->res_ctx);
}
if (pipe_ctx->clock_source == NULL) if (pipe_ctx->clock_source == NULL)
return DC_NO_CLOCK_SOURCE_RESOURCE; return DC_NO_CLOCK_SOURCE_RESOURCE;
resource_reference_clock_source( resource_reference_clock_source(
&context->res_ctx, &context->res_ctx,
pipe_ctx->clock_source); pipe_ctx->clock_source);
/* only one cs per stream regardless of mpo */ /* only one cs per stream regardless of mpo */
break; break;
}
} }
} }
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include "dc.h" #include "dc.h"
#include "core_types.h" #include "core_types.h"
#include "resource.h" #include "resource.h"
#include "ipp.h"
#include "timing_generator.h"
/******************************************************************************* /*******************************************************************************
* Private definitions * Private definitions
...@@ -146,3 +148,184 @@ struct dc_stream *dc_create_stream_for_sink( ...@@ -146,3 +148,184 @@ struct dc_stream *dc_create_stream_for_sink(
alloc_fail: alloc_fail:
return NULL; return NULL;
} }
const struct dc_stream_status *dc_stream_get_status(
const struct dc_stream *dc_stream)
{
uint8_t i;
struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream);
struct core_dc *dc = DC_TO_CORE(stream->ctx->dc);
for (i = 0; i < dc->current_context->stream_count; i++)
if (stream == dc->current_context->streams[i])
return &dc->current_context->stream_status[i];
return NULL;
}
/**
* Update the cursor attributes and set cursor surface address
*/
bool dc_stream_set_cursor_attributes(
const struct dc_stream *dc_stream,
const struct dc_cursor_attributes *attributes)
{
int i;
struct core_stream *stream;
struct core_dc *core_dc;
struct resource_context *res_ctx;
bool ret = false;
if (NULL == dc_stream) {
dm_error("DC: dc_stream is NULL!\n");
return false;
}
if (NULL == attributes) {
dm_error("DC: attributes is NULL!\n");
return false;
}
stream = DC_STREAM_TO_CORE(dc_stream);
core_dc = DC_TO_CORE(stream->ctx->dc);
res_ctx = &core_dc->current_context->res_ctx;
for (i = 0; i < MAX_PIPES; i++) {
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
if (pipe_ctx->stream == stream) {
struct input_pixel_processor *ipp = pipe_ctx->ipp;
if (ipp->funcs->ipp_cursor_set_attributes(
ipp, attributes))
ret = true;
}
}
return ret;
}
bool dc_stream_set_cursor_position(
const struct dc_stream *dc_stream,
const struct dc_cursor_position *position)
{
int i;
struct core_stream *stream;
struct core_dc *core_dc;
struct resource_context *res_ctx;
bool ret = false;
if (NULL == dc_stream) {
dm_error("DC: dc_stream is NULL!\n");
return false;
}
if (NULL == position) {
dm_error("DC: cursor position is NULL!\n");
return false;
}
stream = DC_STREAM_TO_CORE(dc_stream);
core_dc = DC_TO_CORE(stream->ctx->dc);
res_ctx = &core_dc->current_context->res_ctx;
for (i = 0; i < MAX_PIPES; i++) {
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[i];
if (pipe_ctx->stream == stream) {
struct input_pixel_processor *ipp = pipe_ctx->ipp;
struct dc_cursor_mi_param param = {
.pixel_clk_khz = dc_stream->timing.pix_clk_khz,
.ref_clk_khz = 48000,/*todo refclk*/
.viewport_x_start = pipe_ctx->scl_data.viewport.x,
.viewport_width = pipe_ctx->scl_data.viewport.width,
.h_scale_ratio = pipe_ctx->scl_data.ratios.horz,
};
ipp->funcs->ipp_cursor_set_position(ipp, position, &param);
ret = true;
}
}
return ret;
}
uint32_t dc_stream_get_vblank_counter(const struct dc_stream *dc_stream)
{
uint8_t i;
struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream);
struct core_dc *core_dc = DC_TO_CORE(stream->ctx->dc);
struct resource_context *res_ctx =
&core_dc->current_context->res_ctx;
for (i = 0; i < MAX_PIPES; i++) {
struct timing_generator *tg = res_ctx->pipe_ctx[i].tg;
if (res_ctx->pipe_ctx[i].stream != stream)
continue;
return tg->funcs->get_frame_count(tg);
}
return 0;
}
uint32_t dc_stream_get_scanoutpos(
const struct dc_stream *dc_stream,
uint32_t *vbl,
uint32_t *position)
{
uint8_t i;
struct core_stream *stream = DC_STREAM_TO_CORE(dc_stream);
struct core_dc *core_dc = DC_TO_CORE(stream->ctx->dc);
struct resource_context *res_ctx =
&core_dc->current_context->res_ctx;
for (i = 0; i < MAX_PIPES; i++) {
struct timing_generator *tg = res_ctx->pipe_ctx[i].tg;
if (res_ctx->pipe_ctx[i].stream != stream)
continue;
return tg->funcs->get_scanoutpos(tg, vbl, position);
}
return 0;
}
void dc_stream_log(
const struct dc_stream *stream,
struct dal_logger *dm_logger,
enum dc_log_type log_type)
{
const struct core_stream *core_stream =
DC_STREAM_TO_CORE(stream);
dm_logger_write(dm_logger,
log_type,
"core_stream 0x%x: src: %d, %d, %d, %d; dst: %d, %d, %d, %d;\n",
core_stream,
core_stream->public.src.x,
core_stream->public.src.y,
core_stream->public.src.width,
core_stream->public.src.height,
core_stream->public.dst.x,
core_stream->public.dst.y,
core_stream->public.dst.width,
core_stream->public.dst.height);
dm_logger_write(dm_logger,
log_type,
"\tpix_clk_khz: %d, h_total: %d, v_total: %d\n",
core_stream->public.timing.pix_clk_khz,
core_stream->public.timing.h_total,
core_stream->public.timing.v_total);
dm_logger_write(dm_logger,
log_type,
"\tsink name: %s, serial: %d\n",
core_stream->sink->public.edid_caps.display_name,
core_stream->sink->public.edid_caps.serial_number);
dm_logger_write(dm_logger,
log_type,
"\tlink: %d\n",
core_stream->sink->link->public.link_index);
}
/*
* 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 "core_types.h"
#include "hw_sequencer.h"
#include "resource.h"
#include "ipp.h"
#include "timing_generator.h"
struct target {
struct core_target protected;
int ref_count;
};
#define DC_TARGET_TO_TARGET(dc_target) \
container_of(dc_target, struct target, protected.public)
#define CORE_TARGET_TO_TARGET(core_target) \
container_of(core_target, struct target, protected)
static void construct(
struct core_target *target,
struct dc_context *ctx,
struct dc_stream *dc_streams[],
uint8_t stream_count)
{
uint8_t i;
for (i = 0; i < stream_count; i++) {
target->public.streams[i] = dc_streams[i];
dc_stream_retain(dc_streams[i]);
}
target->ctx = ctx;
target->public.stream_count = stream_count;
}
static void destruct(struct core_target *core_target)
{
int i;
for (i = 0; i < core_target->public.stream_count; i++) {
dc_stream_release(
(struct dc_stream *)core_target->public.streams[i]);
core_target->public.streams[i] = NULL;
}
}
void dc_target_retain(const struct dc_target *dc_target)
{
struct target *target = DC_TARGET_TO_TARGET(dc_target);
ASSERT(target->ref_count > 0);
target->ref_count++;
}
void dc_target_release(const struct dc_target *dc_target)
{
struct target *target = DC_TARGET_TO_TARGET(dc_target);
struct core_target *protected = DC_TARGET_TO_CORE(dc_target);
ASSERT(target->ref_count > 0);
target->ref_count--;
if (target->ref_count == 0) {
destruct(protected);
dm_free(target);
}
}
const struct dc_target_status *dc_target_get_status(
const struct dc_target* dc_target)
{
uint8_t i;
struct core_target* target = DC_TARGET_TO_CORE(dc_target);
struct core_dc *dc = DC_TO_CORE(target->ctx->dc);
for (i = 0; i < dc->current_context->target_count; i++)
if (target == dc->current_context->targets[i])
return &dc->current_context->target_status[i];
return NULL;
}
struct dc_target *dc_create_target_for_streams(
struct dc_stream *dc_streams[],
uint8_t stream_count)
{
struct core_stream *stream;
struct target *target;
if (0 == stream_count)
goto target_alloc_fail;
stream = DC_STREAM_TO_CORE(dc_streams[0]);
target = dm_alloc(sizeof(struct target));
if (NULL == target)
goto target_alloc_fail;
construct(&target->protected, stream->ctx, dc_streams, stream_count);
target->ref_count++;
return &target->protected.public;
target_alloc_fail:
return NULL;
}
bool dc_target_is_connected_to_sink(
const struct dc_target * dc_target,
const struct dc_sink *dc_sink)
{
struct core_target *target = DC_TARGET_TO_CORE(dc_target);
uint8_t i;
for (i = 0; i < target->public.stream_count; i++) {
if (target->public.streams[i]->sink == dc_sink)
return true;
}
return false;
}
/**
* Update the cursor attributes and set cursor surface address
*/
bool dc_target_set_cursor_attributes(
struct dc_target *dc_target,
const struct dc_cursor_attributes *attributes)
{
int i, j;
struct core_target *target;
struct core_dc *core_dc;
struct resource_context *res_ctx;
bool ret = false;
if (NULL == dc_target) {
dm_error("DC: dc_target is NULL!\n");
return false;
}
if (NULL == attributes) {
dm_error("DC: attributes is NULL!\n");
return false;
}
target = DC_TARGET_TO_CORE(dc_target);
core_dc = DC_TO_CORE(target->ctx->dc);
res_ctx = &core_dc->current_context->res_ctx;
for (i = 0; i < dc_target->stream_count; i++) {
const struct dc_stream *stream = dc_target->streams[i];
for (j = 0; j < MAX_PIPES; j++) {
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[j];
if (&pipe_ctx->stream->public == stream) {
struct input_pixel_processor *ipp = pipe_ctx->ipp;
if (ipp->funcs->ipp_cursor_set_attributes(
ipp, attributes))
ret = true;
}
}
}
return ret;
}
bool dc_target_set_cursor_position(
struct dc_target *dc_target,
const struct dc_cursor_position *position)
{
int i, j;
struct core_target *target = DC_TARGET_TO_CORE(dc_target);
struct core_dc *core_dc = DC_TO_CORE(target->ctx->dc);
struct resource_context *res_ctx = &core_dc->current_context->res_ctx;
bool ret = false;
if (NULL == dc_target) {
dm_error("DC: dc_target is NULL!\n");
return false;
}
if (NULL == position) {
dm_error("DC: cursor position is NULL!\n");
return false;
}
for (i = 0; i < dc_target->stream_count; i++) {
const struct dc_stream *stream = dc_target->streams[i];
for (j = 0; j < MAX_PIPES; j++) {
struct pipe_ctx *pipe_ctx = &res_ctx->pipe_ctx[j];
if (&pipe_ctx->stream->public == stream) {
struct input_pixel_processor *ipp = pipe_ctx->ipp;
struct dc_cursor_mi_param param = {
.pixel_clk_khz = stream->timing.pix_clk_khz,
.ref_clk_khz = 48000,/*todo refclk*/
.viewport_x_start = pipe_ctx->scl_data.viewport.x,
.viewport_width = pipe_ctx->scl_data.viewport.width,
.h_scale_ratio = pipe_ctx->scl_data.ratios.horz,
};
ipp->funcs->ipp_cursor_set_position(ipp, position, &param);
ret = true;
}
}
}
return ret;
}
uint32_t dc_target_get_vblank_counter(const struct dc_target *dc_target)
{
uint8_t i, j;
struct core_target *target = DC_TARGET_TO_CORE(dc_target);
struct core_dc *core_dc = DC_TO_CORE(target->ctx->dc);
struct resource_context *res_ctx =
&core_dc->current_context->res_ctx;
for (i = 0; i < target->public.stream_count; i++) {
for (j = 0; j < MAX_PIPES; j++) {
struct timing_generator *tg = res_ctx->pipe_ctx[j].tg;
if (res_ctx->pipe_ctx[j].stream !=
DC_STREAM_TO_CORE(target->public.streams[i]))
continue;
return tg->funcs->get_frame_count(tg);
}
}
return 0;
}
uint32_t dc_target_get_scanoutpos(
const struct dc_target *dc_target,
uint32_t *vbl,
uint32_t *position)
{
uint8_t i, j;
struct core_target *target = DC_TARGET_TO_CORE(dc_target);
struct core_dc *core_dc = DC_TO_CORE(target->ctx->dc);
struct resource_context *res_ctx =
&core_dc->current_context->res_ctx;
for (i = 0; i < target->public.stream_count; i++) {
for (j = 0; j < MAX_PIPES; j++) {
struct timing_generator *tg = res_ctx->pipe_ctx[j].tg;
if (res_ctx->pipe_ctx[j].stream !=
DC_STREAM_TO_CORE(target->public.streams[i]))
continue;
return tg->funcs->get_scanoutpos(tg, vbl, position);
}
}
return 0;
}
void dc_target_log(
const struct dc_target *dc_target,
struct dal_logger *dm_logger,
enum dc_log_type log_type)
{
int i;
const struct core_target *core_target =
CONST_DC_TARGET_TO_CORE(dc_target);
dm_logger_write(dm_logger,
log_type,
"core_target 0x%x: stream_count=%d\n",
core_target,
core_target->public.stream_count);
for (i = 0; i < core_target->public.stream_count; i++) {
const struct core_stream *core_stream =
DC_STREAM_TO_CORE(core_target->public.streams[i]);
dm_logger_write(dm_logger,
log_type,
"core_stream 0x%x: src: %d, %d, %d, %d; dst: %d, %d, %d, %d;\n",
core_stream,
core_stream->public.src.x,
core_stream->public.src.y,
core_stream->public.src.width,
core_stream->public.src.height,
core_stream->public.dst.x,
core_stream->public.dst.y,
core_stream->public.dst.width,
core_stream->public.dst.height);
dm_logger_write(dm_logger,
log_type,
"\tpix_clk_khz: %d, h_total: %d, v_total: %d\n",
core_stream->public.timing.pix_clk_khz,
core_stream->public.timing.h_total,
core_stream->public.timing.v_total);
dm_logger_write(dm_logger,
log_type,
"\tsink name: %s, serial: %d\n",
core_stream->sink->public.edid_caps.display_name,
core_stream->sink->public.edid_caps.serial_number);
dm_logger_write(dm_logger,
log_type,
"\tlink: %d\n",
core_stream->sink->link->public.link_index);
}
}
...@@ -32,8 +32,8 @@ ...@@ -32,8 +32,8 @@
#include "gpio_types.h" #include "gpio_types.h"
#include "link_service_types.h" #include "link_service_types.h"
#define MAX_TARGETS 6
#define MAX_SURFACES 3 #define MAX_SURFACES 3
#define MAX_STREAMS 6
#define MAX_SINKS_PER_LINK 4 #define MAX_SINKS_PER_LINK 4
/******************************************************************************* /*******************************************************************************
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
******************************************************************************/ ******************************************************************************/
struct dc_caps { struct dc_caps {
uint32_t max_targets; uint32_t max_streams;
uint32_t max_links; uint32_t max_links;
uint32_t max_audios; uint32_t max_audios;
uint32_t max_slave_planes; uint32_t max_slave_planes;
...@@ -139,7 +139,6 @@ struct dc_config { ...@@ -139,7 +139,6 @@ struct dc_config {
struct dc_debug { struct dc_debug {
bool surface_visual_confirm; bool surface_visual_confirm;
bool max_disp_clk; bool max_disp_clk;
bool target_trace;
bool surface_trace; bool surface_trace;
bool timing_trace; bool timing_trace;
bool validation_trace; bool validation_trace;
...@@ -351,95 +350,91 @@ void dc_flip_surface_addrs(struct dc *dc, ...@@ -351,95 +350,91 @@ void dc_flip_surface_addrs(struct dc *dc,
uint32_t count); uint32_t count);
/* /*
* Set up surface attributes and associate to a target * Set up surface attributes and associate to a stream
* The surfaces parameter is an absolute set of all surface active for the target. * The surfaces parameter is an absolute set of all surface active for the stream.
* If no surfaces are provided, the target will be blanked; no memory read. * If no surfaces are provided, the stream will be blanked; no memory read.
* Any flip related attribute changes must be done through this interface. * Any flip related attribute changes must be done through this interface.
* *
* After this call: * After this call:
* Surfaces attributes are programmed and configured to be composed into target. * Surfaces attributes are programmed and configured to be composed into stream.
* This does not trigger a flip. No surface address is programmed. * This does not trigger a flip. No surface address is programmed.
*/ */
bool dc_commit_surfaces_to_target( bool dc_commit_surfaces_to_stream(
struct dc *dc, struct dc *dc,
const struct dc_surface **dc_surfaces, const struct dc_surface **dc_surfaces,
uint8_t surface_count, uint8_t surface_count,
struct dc_target *dc_target); const struct dc_stream *stream);
bool dc_pre_update_surfaces_to_target( bool dc_pre_update_surfaces_to_stream(
struct dc *dc, struct dc *dc,
const struct dc_surface *const *new_surfaces, const struct dc_surface *const *new_surfaces,
uint8_t new_surface_count, uint8_t new_surface_count,
struct dc_target *dc_target); const struct dc_stream *stream);
bool dc_post_update_surfaces_to_target( bool dc_post_update_surfaces_to_stream(
struct dc *dc); struct dc *dc);
void dc_update_surfaces_for_target(struct dc *dc, struct dc_surface_update *updates, void dc_update_surfaces_for_stream(struct dc *dc, struct dc_surface_update *updates,
int surface_count, struct dc_target *dc_target); int surface_count, const struct dc_stream *stream);
/******************************************************************************* /*******************************************************************************
* Target Interfaces * Stream Interfaces
******************************************************************************/ ******************************************************************************/
#define MAX_STREAM_NUM 1 struct dc_stream {
const struct dc_sink *sink;
struct dc_crtc_timing timing;
struct dc_target { enum dc_color_space output_color_space;
uint8_t stream_count;
const struct dc_stream *streams[MAX_STREAM_NUM];
};
/* struct rect src; /* composition area */
* Target status is returned from dc_target_get_status in order to get the struct rect dst; /* stream addressable area */
* the IRQ source, current frame counter and currently attached surfaces.
*/
struct dc_target_status {
int primary_otg_inst;
int cur_frame_count;
int surface_count;
const struct dc_surface *surfaces[MAX_SURFACE_NUM];
};
struct dc_target *dc_create_target_for_streams( struct audio_info audio_info;
struct dc_stream *dc_streams[],
uint8_t stream_count); bool ignore_msa_timing_param;
struct freesync_context freesync_ctx;
const struct dc_transfer_func *out_transfer_func;
struct colorspace_transform gamut_remap_matrix;
struct csc_transform csc_color_matrix;
/* TODO: dithering */
/* TODO: custom INFO packets */
/* TODO: ABM info (DMCU) */
/* TODO: PSR info */
/* TODO: CEA VIC */
};
/* /*
* Get the current target status. * Log the current stream state.
*/ */
const struct dc_target_status *dc_target_get_status( void dc_stream_log(
const struct dc_target* dc_target); const struct dc_stream *stream,
void dc_target_retain(const struct dc_target *dc_target);
void dc_target_release(const struct dc_target *dc_target);
void dc_target_log(
const struct dc_target *dc_target,
struct dal_logger *dc_logger, struct dal_logger *dc_logger,
enum dc_log_type log_type); enum dc_log_type log_type);
uint8_t dc_get_current_target_count(const struct dc *dc); uint8_t dc_get_current_stream_count(const struct dc *dc);
struct dc_target *dc_get_target_at_index(const struct dc *dc, uint8_t i); struct dc_stream *dc_get_stream_at_index(const struct dc *dc, uint8_t i);
bool dc_target_is_connected_to_sink( /*
const struct dc_target *dc_target, * Return the current frame counter.
const struct dc_sink *dc_sink); */
uint32_t dc_stream_get_vblank_counter(const struct dc_stream *stream);
uint32_t dc_target_get_vblank_counter(const struct dc_target *dc_target);
/* TODO: Return parsed values rather than direct register read /* TODO: Return parsed values rather than direct register read
* This has a dependency on the caller (amdgpu_get_crtc_scanoutpos) * This has a dependency on the caller (amdgpu_get_crtc_scanoutpos)
* being refactored properly to be dce-specific * being refactored properly to be dce-specific
*/ */
uint32_t dc_target_get_scanoutpos( uint32_t dc_stream_get_scanoutpos(
const struct dc_target *dc_target, const struct dc_stream *stream, uint32_t *vbl, uint32_t *position);
uint32_t *vbl,
uint32_t *position);
/* /*
* Structure to store surface/target associations for validation * Structure to store surface/stream associations for validation
*/ */
struct dc_validation_set { struct dc_validation_set {
const struct dc_target *target; const struct dc_stream *stream;
const struct dc_surface *surfaces[MAX_SURFACES]; const struct dc_surface *surfaces[MAX_SURFACES];
uint8_t surface_count; uint8_t surface_count;
}; };
...@@ -456,8 +451,8 @@ bool dc_validate_resources( ...@@ -456,8 +451,8 @@ bool dc_validate_resources(
uint8_t set_count); uint8_t set_count);
/* /*
* This function takes a target and checks if it is guaranteed to be supported. * This function takes a stream and checks if it is guaranteed to be supported.
* Guaranteed means that MAX_COFUNC*target is supported. * Guaranteed means that MAX_COFUNC similar streams are supported.
* *
* After this call: * After this call:
* No hardware is programmed for call. Only validation is done. * No hardware is programmed for call. Only validation is done.
...@@ -465,49 +460,20 @@ bool dc_validate_resources( ...@@ -465,49 +460,20 @@ bool dc_validate_resources(
bool dc_validate_guaranteed( bool dc_validate_guaranteed(
const struct dc *dc, const struct dc *dc,
const struct dc_target *dc_target); const struct dc_stream *stream);
/* /*
* Set up streams and links associated to targets to drive sinks * Set up streams and links associated to drive sinks
* The targets parameter is an absolute set of all active targets. * The streams parameter is an absolute set of all active streams.
* *
* After this call: * After this call:
* Phy, Encoder, Timing Generator are programmed and enabled. * Phy, Encoder, Timing Generator are programmed and enabled.
* New targets are enabled with blank stream; no memory read. * New streams are enabled with blank stream; no memory read.
*/ */
bool dc_commit_targets( bool dc_commit_streams(
struct dc *dc, struct dc *dc,
struct dc_target *targets[], const struct dc_stream *streams[],
uint8_t target_count); uint8_t stream_count);
/*******************************************************************************
* Stream Interfaces
******************************************************************************/
struct dc_stream {
const struct dc_sink *sink;
struct dc_crtc_timing timing;
enum dc_color_space output_color_space;
struct rect src; /* viewport in target space*/
struct rect dst; /* stream addressable area */
struct audio_info audio_info;
bool ignore_msa_timing_param;
struct freesync_context freesync_ctx;
const struct dc_transfer_func *out_transfer_func;
struct colorspace_transform gamut_remap_matrix;
struct csc_transform csc_color_matrix;
/* TODO: dithering */
/* TODO: custom INFO packets */
/* TODO: ABM info (DMCU) */
/* TODO: PSR info */
/* TODO: CEA VIC */
};
/** /**
* Create a new default stream for the requested sink * Create a new default stream for the requested sink
...@@ -518,6 +484,10 @@ void dc_stream_retain(const struct dc_stream *dc_stream); ...@@ -518,6 +484,10 @@ void dc_stream_retain(const struct dc_stream *dc_stream);
void dc_stream_release(const struct dc_stream *dc_stream); void dc_stream_release(const struct dc_stream *dc_stream);
struct dc_stream_status { struct dc_stream_status {
int primary_otg_inst;
int surface_count;
const struct dc_surface *surfaces[MAX_SURFACE_NUM];
/* /*
* link this stream passes through * link this stream passes through
*/ */
...@@ -691,15 +661,15 @@ struct dc_sink_init_data { ...@@ -691,15 +661,15 @@ struct dc_sink_init_data {
struct dc_sink *dc_sink_create(const struct dc_sink_init_data *init_params); struct dc_sink *dc_sink_create(const struct dc_sink_init_data *init_params);
/******************************************************************************* /*******************************************************************************
* Cursor interfaces - To manages the cursor within a target * Cursor interfaces - To manages the cursor within a stream
******************************************************************************/ ******************************************************************************/
/* TODO: Deprecated once we switch to dc_set_cursor_position */ /* TODO: Deprecated once we switch to dc_set_cursor_position */
bool dc_target_set_cursor_attributes( bool dc_stream_set_cursor_attributes(
struct dc_target *dc_target, const struct dc_stream *stream,
const struct dc_cursor_attributes *attributes); const struct dc_cursor_attributes *attributes);
bool dc_target_set_cursor_position( bool dc_stream_set_cursor_position(
struct dc_target *dc_target, const struct dc_stream *stream,
const struct dc_cursor_position *position); const struct dc_cursor_position *position);
/* Newer interfaces */ /* Newer interfaces */
...@@ -708,36 +678,6 @@ struct dc_cursor { ...@@ -708,36 +678,6 @@ struct dc_cursor {
struct dc_cursor_attributes attributes; struct dc_cursor_attributes attributes;
}; };
/*
* Create a new cursor with default values for a given target.
*/
struct dc_cursor *dc_create_cursor_for_target(
const struct dc *dc,
struct dc_target *dc_target);
/**
* Commit cursor attribute changes such as pixel format and dimensions and
* surface address.
*
* After this call:
* Cursor address and format is programmed to the new values.
* Cursor position is unmodified.
*/
bool dc_commit_cursor(
const struct dc *dc,
struct dc_cursor *cursor);
/*
* Optimized cursor position update
*
* After this call:
* Cursor position will be programmed as well as enable/disable bit.
*/
bool dc_set_cursor_position(
const struct dc *dc,
struct dc_cursor *cursor,
struct dc_cursor_position *pos);
/******************************************************************************* /*******************************************************************************
* Interrupt interfaces * Interrupt interfaces
******************************************************************************/ ******************************************************************************/
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
/* forward declarations */ /* forward declarations */
struct dc_surface; struct dc_surface;
struct dc_target;
struct dc_stream; struct dc_stream;
struct dc_link; struct dc_link;
struct dc_sink; struct dc_sink;
......
...@@ -741,53 +741,48 @@ static enum dc_status validate_mapped_resource( ...@@ -741,53 +741,48 @@ static enum dc_status validate_mapped_resource(
struct validate_context *context) struct validate_context *context)
{ {
enum dc_status status = DC_OK; enum dc_status status = DC_OK;
uint8_t i, j, k; uint8_t i, j;
for (i = 0; i < context->target_count; i++) { for (i = 0; i < context->stream_count; i++) {
struct core_target *target = context->targets[i]; struct core_stream *stream = context->streams[i];
struct core_link *link = stream->sink->link;
for (j = 0; j < target->public.stream_count; j++) { if (resource_is_stream_unchanged(dc->current_context, stream))
struct core_stream *stream = continue;
DC_STREAM_TO_CORE(target->public.streams[j]);
struct core_link *link = stream->sink->link;
if (resource_is_stream_unchanged(dc->current_context, stream))
continue;
for (k = 0; k < MAX_PIPES; k++) { for (j = 0; j < MAX_PIPES; j++) {
struct pipe_ctx *pipe_ctx = struct pipe_ctx *pipe_ctx =
&context->res_ctx.pipe_ctx[k]; &context->res_ctx.pipe_ctx[j];
if (context->res_ctx.pipe_ctx[k].stream != stream) if (context->res_ctx.pipe_ctx[j].stream != stream)
continue; continue;
if (!pipe_ctx->tg->funcs->validate_timing( if (!pipe_ctx->tg->funcs->validate_timing(
pipe_ctx->tg, &stream->public.timing)) pipe_ctx->tg, &stream->public.timing))
return DC_FAIL_CONTROLLER_VALIDATE; return DC_FAIL_CONTROLLER_VALIDATE;
status = dce110_resource_build_pipe_hw_param(pipe_ctx); status = dce110_resource_build_pipe_hw_param(pipe_ctx);
if (status != DC_OK) if (status != DC_OK)
return status; return status;
if (!link->link_enc->funcs->validate_output_with_stream( if (!link->link_enc->funcs->validate_output_with_stream(
link->link_enc, link->link_enc,
pipe_ctx)) pipe_ctx))
return DC_FAIL_ENC_VALIDATE; return DC_FAIL_ENC_VALIDATE;
/* TODO: validate audio ASIC caps, encoder */ /* TODO: validate audio ASIC caps, encoder */
status = dc_link_validate_mode_timing(stream, status = dc_link_validate_mode_timing(stream,
link, link,
&stream->public.timing); &stream->public.timing);
if (status != DC_OK) if (status != DC_OK)
return status; return status;
resource_build_info_frame(pipe_ctx); resource_build_info_frame(pipe_ctx);
/* do not need to validate non root pipes */ /* do not need to validate non root pipes */
break; break;
}
} }
} }
...@@ -818,9 +813,9 @@ static bool dce100_validate_surface_sets( ...@@ -818,9 +813,9 @@ static bool dce100_validate_surface_sets(
return false; return false;
if (set[i].surfaces[0]->clip_rect.width if (set[i].surfaces[0]->clip_rect.width
!= set[i].target->streams[0]->src.width != set[i].stream->src.width
|| set[i].surfaces[0]->clip_rect.height || set[i].surfaces[0]->clip_rect.height
!= set[i].target->streams[0]->src.height) != set[i].stream->src.height)
return false; return false;
if (set[i].surfaces[0]->format if (set[i].surfaces[0]->format
>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
...@@ -846,9 +841,9 @@ enum dc_status dce100_validate_with_context( ...@@ -846,9 +841,9 @@ enum dc_status dce100_validate_with_context(
context->res_ctx.pool = dc->res_pool; context->res_ctx.pool = dc->res_pool;
for (i = 0; i < set_count; i++) { for (i = 0; i < set_count; i++) {
context->targets[i] = DC_TARGET_TO_CORE(set[i].target); context->streams[i] = DC_STREAM_TO_CORE(set[i].stream);
dc_target_retain(&context->targets[i]->public); dc_stream_retain(&context->streams[i]->public);
context->target_count++; context->stream_count++;
} }
result = resource_map_pool_resources(dc, context); result = resource_map_pool_resources(dc, context);
...@@ -858,7 +853,7 @@ enum dc_status dce100_validate_with_context( ...@@ -858,7 +853,7 @@ enum dc_status dce100_validate_with_context(
if (!resource_validate_attach_surfaces( if (!resource_validate_attach_surfaces(
set, set_count, dc->current_context, context)) { set, set_count, dc->current_context, context)) {
DC_ERROR("Failed to attach surface to target!\n"); DC_ERROR("Failed to attach surface to stream!\n");
return DC_FAIL_ATTACH_SURFACES; return DC_FAIL_ATTACH_SURFACES;
} }
...@@ -876,16 +871,16 @@ enum dc_status dce100_validate_with_context( ...@@ -876,16 +871,16 @@ enum dc_status dce100_validate_with_context(
enum dc_status dce100_validate_guaranteed( enum dc_status dce100_validate_guaranteed(
const struct core_dc *dc, const struct core_dc *dc,
const struct dc_target *dc_target, const struct dc_stream *dc_stream,
struct validate_context *context) struct validate_context *context)
{ {
enum dc_status result = DC_ERROR_UNEXPECTED; enum dc_status result = DC_ERROR_UNEXPECTED;
context->res_ctx.pool = dc->res_pool; context->res_ctx.pool = dc->res_pool;
context->targets[0] = DC_TARGET_TO_CORE(dc_target); context->streams[0] = DC_STREAM_TO_CORE(dc_stream);
dc_target_retain(&context->targets[0]->public); dc_stream_retain(&context->streams[0]->public);
context->target_count++; context->stream_count++;
result = resource_map_pool_resources(dc, context); result = resource_map_pool_resources(dc, context);
...@@ -896,8 +891,8 @@ enum dc_status dce100_validate_guaranteed( ...@@ -896,8 +891,8 @@ enum dc_status dce100_validate_guaranteed(
result = validate_mapped_resource(dc, context); result = validate_mapped_resource(dc, context);
if (result == DC_OK) { if (result == DC_OK) {
validate_guaranteed_copy_target( validate_guaranteed_copy_streams(
context, dc->public.caps.max_targets); context, dc->public.caps.max_streams);
result = resource_build_scaling_params_for_context(dc, context); result = resource_build_scaling_params_for_context(dc, context);
} }
......
...@@ -753,7 +753,7 @@ static enum dc_status apply_single_controller_ctx_to_hw( ...@@ -753,7 +753,7 @@ static enum dc_status apply_single_controller_ctx_to_hw(
stream->public.timing.h_total, stream->public.timing.h_total,
stream->public.timing.v_total, stream->public.timing.v_total,
stream->public.timing.pix_clk_khz, stream->public.timing.pix_clk_khz,
context->target_count); context->stream_count);
return DC_OK; return DC_OK;
} }
...@@ -1055,7 +1055,7 @@ static void reset_single_pipe_hw_ctx( ...@@ -1055,7 +1055,7 @@ static void reset_single_pipe_hw_ctx(
} }
pipe_ctx->tg->funcs->disable_crtc(pipe_ctx->tg); pipe_ctx->tg->funcs->disable_crtc(pipe_ctx->tg);
pipe_ctx->mi->funcs->free_mem_input( pipe_ctx->mi->funcs->free_mem_input(
pipe_ctx->mi, context->target_count); pipe_ctx->mi, context->stream_count);
resource_unreference_clock_source( resource_unreference_clock_source(
&context->res_ctx, &pipe_ctx->clock_source); &context->res_ctx, &pipe_ctx->clock_source);
...@@ -1254,7 +1254,7 @@ enum dc_status dce110_apply_ctx_to_hw( ...@@ -1254,7 +1254,7 @@ enum dc_status dce110_apply_ctx_to_hw(
dc->hwss.reset_hw_ctx_wrap(dc, context); dc->hwss.reset_hw_ctx_wrap(dc, context);
/* Skip applying if no targets */ /* Skip applying if no targets */
if (context->target_count <= 0) if (context->stream_count <= 0)
return DC_OK; return DC_OK;
if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) { if (IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment)) {
...@@ -1761,7 +1761,7 @@ static void dce110_power_on_pipe_if_needed( ...@@ -1761,7 +1761,7 @@ static void dce110_power_on_pipe_if_needed(
pipe_ctx->stream->public.timing.h_total, pipe_ctx->stream->public.timing.h_total,
pipe_ctx->stream->public.timing.v_total, pipe_ctx->stream->public.timing.v_total,
pipe_ctx->stream->public.timing.pix_clk_khz, pipe_ctx->stream->public.timing.pix_clk_khz,
context->target_count); context->stream_count);
/* TODO unhardcode*/ /* TODO unhardcode*/
color_space_to_black_color(dc, color_space_to_black_color(dc,
......
...@@ -817,58 +817,53 @@ static enum dc_status validate_mapped_resource( ...@@ -817,58 +817,53 @@ static enum dc_status validate_mapped_resource(
struct validate_context *context) struct validate_context *context)
{ {
enum dc_status status = DC_OK; enum dc_status status = DC_OK;
uint8_t i, j, k; uint8_t i, j;
for (i = 0; i < context->target_count; i++) { for (i = 0; i < context->stream_count; i++) {
struct core_target *target = context->targets[i]; struct core_stream *stream = context->streams[i];
struct core_link *link = stream->sink->link;
for (j = 0; j < target->public.stream_count; j++) { if (resource_is_stream_unchanged(dc->current_context, stream))
struct core_stream *stream = continue;
DC_STREAM_TO_CORE(target->public.streams[j]);
struct core_link *link = stream->sink->link;
if (resource_is_stream_unchanged(dc->current_context, stream))
continue;
for (k = 0; k < MAX_PIPES; k++) { for (j = 0; j < MAX_PIPES; j++) {
struct pipe_ctx *pipe_ctx = struct pipe_ctx *pipe_ctx =
&context->res_ctx.pipe_ctx[k]; &context->res_ctx.pipe_ctx[j];
if (context->res_ctx.pipe_ctx[k].stream != stream) if (context->res_ctx.pipe_ctx[j].stream != stream)
continue; continue;
if (!is_surface_pixel_format_supported(pipe_ctx, if (!is_surface_pixel_format_supported(pipe_ctx,
context->res_ctx.pool->underlay_pipe_index)) context->res_ctx.pool->underlay_pipe_index))
return DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED; return DC_SURFACE_PIXEL_FORMAT_UNSUPPORTED;
if (!pipe_ctx->tg->funcs->validate_timing( if (!pipe_ctx->tg->funcs->validate_timing(
pipe_ctx->tg, &stream->public.timing)) pipe_ctx->tg, &stream->public.timing))
return DC_FAIL_CONTROLLER_VALIDATE; return DC_FAIL_CONTROLLER_VALIDATE;
status = dce110_resource_build_pipe_hw_param(pipe_ctx); status = dce110_resource_build_pipe_hw_param(pipe_ctx);
if (status != DC_OK) if (status != DC_OK)
return status; return status;
if (!link->link_enc->funcs->validate_output_with_stream( if (!link->link_enc->funcs->validate_output_with_stream(
link->link_enc, link->link_enc,
pipe_ctx)) pipe_ctx))
return DC_FAIL_ENC_VALIDATE; return DC_FAIL_ENC_VALIDATE;
/* TODO: validate audio ASIC caps, encoder */ /* TODO: validate audio ASIC caps, encoder */
status = dc_link_validate_mode_timing(stream, status = dc_link_validate_mode_timing(stream,
link, link,
&stream->public.timing); &stream->public.timing);
if (status != DC_OK) if (status != DC_OK)
return status; return status;
resource_build_info_frame(pipe_ctx); resource_build_info_frame(pipe_ctx);
/* do not need to validate non root pipes */ /* do not need to validate non root pipes */
break; break;
}
} }
} }
...@@ -901,9 +896,9 @@ enum dc_status dce110_validate_bandwidth( ...@@ -901,9 +896,9 @@ enum dc_status dce110_validate_bandwidth(
dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_VALIDATION, dm_logger_write(dc->ctx->logger, LOG_BANDWIDTH_VALIDATION,
"%s: %dx%d@%d Bandwidth validation failed!\n", "%s: %dx%d@%d Bandwidth validation failed!\n",
__func__, __func__,
context->targets[0]->public.streams[0]->timing.h_addressable, context->streams[0]->public.timing.h_addressable,
context->targets[0]->public.streams[0]->timing.v_addressable, context->streams[0]->public.timing.v_addressable,
context->targets[0]->public.streams[0]->timing.pix_clk_khz); context->streams[0]->public.timing.pix_clk_khz);
if (memcmp(&dc->current_context->bw_results, if (memcmp(&dc->current_context->bw_results,
&context->bw_results, sizeof(context->bw_results))) { &context->bw_results, sizeof(context->bw_results))) {
...@@ -972,9 +967,9 @@ static bool dce110_validate_surface_sets( ...@@ -972,9 +967,9 @@ static bool dce110_validate_surface_sets(
return false; return false;
if (set[i].surfaces[0]->src_rect.width if (set[i].surfaces[0]->src_rect.width
!= set[i].target->streams[0]->src.width != set[i].stream->src.width
|| set[i].surfaces[0]->src_rect.height || set[i].surfaces[0]->src_rect.height
!= set[i].target->streams[0]->src.height) != set[i].stream->src.height)
return false; return false;
if (set[i].surfaces[0]->format if (set[i].surfaces[0]->format
>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
...@@ -988,7 +983,7 @@ static bool dce110_validate_surface_sets( ...@@ -988,7 +983,7 @@ static bool dce110_validate_surface_sets(
|| set[i].surfaces[1]->src_rect.height > 1080) || set[i].surfaces[1]->src_rect.height > 1080)
return false; return false;
if (set[i].target->streams[0]->timing.pixel_encoding != PIXEL_ENCODING_RGB) if (set[i].stream->timing.pixel_encoding != PIXEL_ENCODING_RGB)
return false; return false;
} }
} }
...@@ -1012,9 +1007,9 @@ enum dc_status dce110_validate_with_context( ...@@ -1012,9 +1007,9 @@ enum dc_status dce110_validate_with_context(
context->res_ctx.pool = dc->res_pool; context->res_ctx.pool = dc->res_pool;
for (i = 0; i < set_count; i++) { for (i = 0; i < set_count; i++) {
context->targets[i] = DC_TARGET_TO_CORE(set[i].target); context->streams[i] = DC_STREAM_TO_CORE(set[i].stream);
dc_target_retain(&context->targets[i]->public); dc_stream_retain(&context->streams[i]->public);
context->target_count++; context->stream_count++;
} }
result = resource_map_pool_resources(dc, context); result = resource_map_pool_resources(dc, context);
...@@ -1024,7 +1019,7 @@ enum dc_status dce110_validate_with_context( ...@@ -1024,7 +1019,7 @@ enum dc_status dce110_validate_with_context(
if (!resource_validate_attach_surfaces( if (!resource_validate_attach_surfaces(
set, set_count, dc->current_context, context)) { set, set_count, dc->current_context, context)) {
DC_ERROR("Failed to attach surface to target!\n"); DC_ERROR("Failed to attach surface to stream!\n");
return DC_FAIL_ATTACH_SURFACES; return DC_FAIL_ATTACH_SURFACES;
} }
...@@ -1042,16 +1037,16 @@ enum dc_status dce110_validate_with_context( ...@@ -1042,16 +1037,16 @@ enum dc_status dce110_validate_with_context(
enum dc_status dce110_validate_guaranteed( enum dc_status dce110_validate_guaranteed(
const struct core_dc *dc, const struct core_dc *dc,
const struct dc_target *dc_target, const struct dc_stream *dc_stream,
struct validate_context *context) struct validate_context *context)
{ {
enum dc_status result = DC_ERROR_UNEXPECTED; enum dc_status result = DC_ERROR_UNEXPECTED;
context->res_ctx.pool = dc->res_pool; context->res_ctx.pool = dc->res_pool;
context->targets[0] = DC_TARGET_TO_CORE(dc_target); context->streams[0] = DC_STREAM_TO_CORE(dc_stream);
dc_target_retain(&context->targets[0]->public); dc_stream_retain(&context->streams[0]->public);
context->target_count++; context->stream_count++;
result = resource_map_pool_resources(dc, context); result = resource_map_pool_resources(dc, context);
...@@ -1062,8 +1057,8 @@ enum dc_status dce110_validate_guaranteed( ...@@ -1062,8 +1057,8 @@ enum dc_status dce110_validate_guaranteed(
result = validate_mapped_resource(dc, context); result = validate_mapped_resource(dc, context);
if (result == DC_OK) { if (result == DC_OK) {
validate_guaranteed_copy_target( validate_guaranteed_copy_streams(
context, dc->public.caps.max_targets); context, dc->public.caps.max_streams);
result = resource_build_scaling_params_for_context(dc, context); result = resource_build_scaling_params_for_context(dc, context);
} }
......
...@@ -779,54 +779,49 @@ static enum dc_status validate_mapped_resource( ...@@ -779,54 +779,49 @@ static enum dc_status validate_mapped_resource(
struct validate_context *context) struct validate_context *context)
{ {
enum dc_status status = DC_OK; enum dc_status status = DC_OK;
uint8_t i, j, k; uint8_t i, j;
for (i = 0; i < context->target_count; i++) { for (i = 0; i < context->stream_count; i++) {
struct core_target *target = context->targets[i]; struct core_stream *stream = context->streams[i];
struct core_link *link = stream->sink->link;
for (j = 0; j < target->public.stream_count; j++) { if (resource_is_stream_unchanged(dc->current_context, stream))
struct core_stream *stream = continue;
DC_STREAM_TO_CORE(target->public.streams[j]);
struct core_link *link = stream->sink->link;
if (resource_is_stream_unchanged(dc->current_context, stream))
continue;
for (k = 0; k < MAX_PIPES; k++) { for (j = 0; j < MAX_PIPES; j++) {
struct pipe_ctx *pipe_ctx = struct pipe_ctx *pipe_ctx =
&context->res_ctx.pipe_ctx[k]; &context->res_ctx.pipe_ctx[j];
if (context->res_ctx.pipe_ctx[k].stream != stream) if (context->res_ctx.pipe_ctx[j].stream != stream)
continue; continue;
if (!pipe_ctx->tg->funcs->validate_timing( if (!pipe_ctx->tg->funcs->validate_timing(
pipe_ctx->tg, &stream->public.timing)) pipe_ctx->tg, &stream->public.timing))
return DC_FAIL_CONTROLLER_VALIDATE; return DC_FAIL_CONTROLLER_VALIDATE;
status = dce110_resource_build_pipe_hw_param(pipe_ctx); status = dce110_resource_build_pipe_hw_param(pipe_ctx);
if (status != DC_OK) if (status != DC_OK)
return status; return status;
if (!link->link_enc->funcs->validate_output_with_stream( if (!link->link_enc->funcs->validate_output_with_stream(
link->link_enc, link->link_enc,
pipe_ctx)) pipe_ctx))
return DC_FAIL_ENC_VALIDATE; return DC_FAIL_ENC_VALIDATE;
/* TODO: validate audio ASIC caps, encoder */ /* TODO: validate audio ASIC caps, encoder */
status = dc_link_validate_mode_timing(stream, status = dc_link_validate_mode_timing(stream,
link, link,
&stream->public.timing); &stream->public.timing);
if (status != DC_OK) if (status != DC_OK)
return status; return status;
resource_build_info_frame(pipe_ctx); resource_build_info_frame(pipe_ctx);
/* do not need to validate non root pipes */ /* do not need to validate non root pipes */
break; break;
}
} }
} }
...@@ -917,45 +912,40 @@ enum dc_status resource_map_phy_clock_resources( ...@@ -917,45 +912,40 @@ enum dc_status resource_map_phy_clock_resources(
const struct core_dc *dc, const struct core_dc *dc,
struct validate_context *context) struct validate_context *context)
{ {
uint8_t i, j, k; uint8_t i, j;
/* acquire new resources */ /* acquire new resources */
for (i = 0; i < context->target_count; i++) { for (i = 0; i < context->stream_count; i++) {
struct core_target *target = context->targets[i]; struct core_stream *stream = context->streams[i];
for (j = 0; j < target->public.stream_count; j++) { if (resource_is_stream_unchanged(dc->current_context, stream))
struct core_stream *stream = continue;
DC_STREAM_TO_CORE(target->public.streams[j]);
if (resource_is_stream_unchanged(dc->current_context, stream))
continue;
for (k = 0; k < MAX_PIPES; k++) { for (j = 0; j < MAX_PIPES; j++) {
struct pipe_ctx *pipe_ctx = struct pipe_ctx *pipe_ctx =
&context->res_ctx.pipe_ctx[k]; &context->res_ctx.pipe_ctx[j];
if (context->res_ctx.pipe_ctx[k].stream != stream) if (context->res_ctx.pipe_ctx[j].stream != stream)
continue; continue;
if (dc_is_dp_signal(pipe_ctx->stream->signal) if (dc_is_dp_signal(pipe_ctx->stream->signal)
|| pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL) || pipe_ctx->stream->signal == SIGNAL_TYPE_VIRTUAL)
pipe_ctx->clock_source = pipe_ctx->clock_source =
context->res_ctx.pool->dp_clock_source; context->res_ctx.pool->dp_clock_source;
else else
pipe_ctx->clock_source = pipe_ctx->clock_source =
find_matching_pll(&context->res_ctx, find_matching_pll(&context->res_ctx,
stream); stream);
if (pipe_ctx->clock_source == NULL) if (pipe_ctx->clock_source == NULL)
return DC_NO_CLOCK_SOURCE_RESOURCE; return DC_NO_CLOCK_SOURCE_RESOURCE;
resource_reference_clock_source( resource_reference_clock_source(
&context->res_ctx, &context->res_ctx,
pipe_ctx->clock_source); pipe_ctx->clock_source);
/* only one cs per stream regardless of mpo */ /* only one cs per stream regardless of mpo */
break; break;
}
} }
} }
...@@ -976,9 +966,9 @@ static bool dce112_validate_surface_sets( ...@@ -976,9 +966,9 @@ static bool dce112_validate_surface_sets(
return false; return false;
if (set[i].surfaces[0]->clip_rect.width if (set[i].surfaces[0]->clip_rect.width
!= set[i].target->streams[0]->src.width != set[i].stream->src.width
|| set[i].surfaces[0]->clip_rect.height || set[i].surfaces[0]->clip_rect.height
!= set[i].target->streams[0]->src.height) != set[i].stream->src.height)
return false; return false;
if (set[i].surfaces[0]->format if (set[i].surfaces[0]->format
>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
...@@ -1004,9 +994,9 @@ enum dc_status dce112_validate_with_context( ...@@ -1004,9 +994,9 @@ enum dc_status dce112_validate_with_context(
context->res_ctx.pool = dc->res_pool; context->res_ctx.pool = dc->res_pool;
for (i = 0; i < set_count; i++) { for (i = 0; i < set_count; i++) {
context->targets[i] = DC_TARGET_TO_CORE(set[i].target); context->streams[i] = DC_STREAM_TO_CORE(set[i].stream);
dc_target_retain(&context->targets[i]->public); dc_stream_retain(&context->streams[i]->public);
context->target_count++; context->stream_count++;
} }
result = resource_map_pool_resources(dc, context); result = resource_map_pool_resources(dc, context);
...@@ -1016,7 +1006,7 @@ enum dc_status dce112_validate_with_context( ...@@ -1016,7 +1006,7 @@ enum dc_status dce112_validate_with_context(
if (!resource_validate_attach_surfaces( if (!resource_validate_attach_surfaces(
set, set_count, dc->current_context, context)) { set, set_count, dc->current_context, context)) {
DC_ERROR("Failed to attach surface to target!\n"); DC_ERROR("Failed to attach surface to stream!\n");
return DC_FAIL_ATTACH_SURFACES; return DC_FAIL_ATTACH_SURFACES;
} }
...@@ -1034,16 +1024,16 @@ enum dc_status dce112_validate_with_context( ...@@ -1034,16 +1024,16 @@ enum dc_status dce112_validate_with_context(
enum dc_status dce112_validate_guaranteed( enum dc_status dce112_validate_guaranteed(
const struct core_dc *dc, const struct core_dc *dc,
const struct dc_target *dc_target, const struct dc_stream *dc_stream,
struct validate_context *context) struct validate_context *context)
{ {
enum dc_status result = DC_ERROR_UNEXPECTED; enum dc_status result = DC_ERROR_UNEXPECTED;
context->res_ctx.pool = dc->res_pool; context->res_ctx.pool = dc->res_pool;
context->targets[0] = DC_TARGET_TO_CORE(dc_target); context->streams[0] = DC_STREAM_TO_CORE(dc_stream);
dc_target_retain(&context->targets[0]->public); dc_stream_retain(&context->streams[0]->public);
context->target_count++; context->stream_count++;
result = resource_map_pool_resources(dc, context); result = resource_map_pool_resources(dc, context);
...@@ -1054,8 +1044,8 @@ enum dc_status dce112_validate_guaranteed( ...@@ -1054,8 +1044,8 @@ enum dc_status dce112_validate_guaranteed(
result = validate_mapped_resource(dc, context); result = validate_mapped_resource(dc, context);
if (result == DC_OK) { if (result == DC_OK) {
validate_guaranteed_copy_target( validate_guaranteed_copy_streams(
context, dc->public.caps.max_targets); context, dc->public.caps.max_streams);
result = resource_build_scaling_params_for_context(dc, context); result = resource_build_scaling_params_for_context(dc, context);
} }
......
...@@ -43,7 +43,7 @@ enum dc_status dce112_validate_with_context( ...@@ -43,7 +43,7 @@ enum dc_status dce112_validate_with_context(
enum dc_status dce112_validate_guaranteed( enum dc_status dce112_validate_guaranteed(
const struct core_dc *dc, const struct core_dc *dc,
const struct dc_target *dc_target, const struct dc_stream *dc_stream,
struct validate_context *context); struct validate_context *context);
enum dc_status dce112_validate_bandwidth( enum dc_status dce112_validate_bandwidth(
......
...@@ -731,54 +731,49 @@ static enum dc_status validate_mapped_resource( ...@@ -731,54 +731,49 @@ static enum dc_status validate_mapped_resource(
struct validate_context *context) struct validate_context *context)
{ {
enum dc_status status = DC_OK; enum dc_status status = DC_OK;
uint8_t i, j, k; uint8_t i, j;
for (i = 0; i < context->target_count; i++) { for (i = 0; i < context->stream_count; i++) {
struct core_target *target = context->targets[i]; struct core_stream *stream = context->streams[i];
struct core_link *link = stream->sink->link;
for (j = 0; j < target->public.stream_count; j++) { if (resource_is_stream_unchanged(dc->current_context, stream))
struct core_stream *stream = continue;
DC_STREAM_TO_CORE(target->public.streams[j]);
struct core_link *link = stream->sink->link;
if (resource_is_stream_unchanged(dc->current_context, stream))
continue;
for (k = 0; k < MAX_PIPES; k++) { for (j = 0; j < MAX_PIPES; j++) {
struct pipe_ctx *pipe_ctx = struct pipe_ctx *pipe_ctx =
&context->res_ctx.pipe_ctx[k]; &context->res_ctx.pipe_ctx[j];
if (context->res_ctx.pipe_ctx[k].stream != stream) if (context->res_ctx.pipe_ctx[j].stream != stream)
continue; continue;
if (!pipe_ctx->tg->funcs->validate_timing( if (!pipe_ctx->tg->funcs->validate_timing(
pipe_ctx->tg, &stream->public.timing)) pipe_ctx->tg, &stream->public.timing))
return DC_FAIL_CONTROLLER_VALIDATE; return DC_FAIL_CONTROLLER_VALIDATE;
status = dce110_resource_build_pipe_hw_param(pipe_ctx); status = dce110_resource_build_pipe_hw_param(pipe_ctx);
if (status != DC_OK) if (status != DC_OK)
return status; return status;
if (!link->link_enc->funcs->validate_output_with_stream( if (!link->link_enc->funcs->validate_output_with_stream(
link->link_enc, link->link_enc,
pipe_ctx)) pipe_ctx))
return DC_FAIL_ENC_VALIDATE; return DC_FAIL_ENC_VALIDATE;
/* TODO: validate audio ASIC caps, encoder */ /* TODO: validate audio ASIC caps, encoder */
status = dc_link_validate_mode_timing(stream, status = dc_link_validate_mode_timing(stream,
link, link,
&stream->public.timing); &stream->public.timing);
if (status != DC_OK) if (status != DC_OK)
return status; return status;
resource_build_info_frame(pipe_ctx); resource_build_info_frame(pipe_ctx);
/* do not need to validate non root pipes */ /* do not need to validate non root pipes */
break; break;
}
} }
} }
...@@ -810,9 +805,9 @@ static bool dce80_validate_surface_sets( ...@@ -810,9 +805,9 @@ static bool dce80_validate_surface_sets(
return false; return false;
if (set[i].surfaces[0]->clip_rect.width if (set[i].surfaces[0]->clip_rect.width
!= set[i].target->streams[0]->src.width != set[i].stream->src.width
|| set[i].surfaces[0]->clip_rect.height || set[i].surfaces[0]->clip_rect.height
!= set[i].target->streams[0]->src.height) != set[i].stream->src.height)
return false; return false;
if (set[i].surfaces[0]->format if (set[i].surfaces[0]->format
>= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN) >= SURFACE_PIXEL_FORMAT_VIDEO_BEGIN)
...@@ -838,9 +833,9 @@ enum dc_status dce80_validate_with_context( ...@@ -838,9 +833,9 @@ enum dc_status dce80_validate_with_context(
context->res_ctx.pool = dc->res_pool; context->res_ctx.pool = dc->res_pool;
for (i = 0; i < set_count; i++) { for (i = 0; i < set_count; i++) {
context->targets[i] = DC_TARGET_TO_CORE(set[i].target); context->streams[i] = DC_STREAM_TO_CORE(set[i].stream);
dc_target_retain(&context->targets[i]->public); dc_stream_retain(&context->streams[i]->public);
context->target_count++; context->stream_count++;
} }
result = resource_map_pool_resources(dc, context); result = resource_map_pool_resources(dc, context);
...@@ -850,7 +845,7 @@ enum dc_status dce80_validate_with_context( ...@@ -850,7 +845,7 @@ enum dc_status dce80_validate_with_context(
if (!resource_validate_attach_surfaces( if (!resource_validate_attach_surfaces(
set, set_count, dc->current_context, context)) { set, set_count, dc->current_context, context)) {
DC_ERROR("Failed to attach surface to target!\n"); DC_ERROR("Failed to attach surface to stream!\n");
return DC_FAIL_ATTACH_SURFACES; return DC_FAIL_ATTACH_SURFACES;
} }
...@@ -868,16 +863,16 @@ enum dc_status dce80_validate_with_context( ...@@ -868,16 +863,16 @@ enum dc_status dce80_validate_with_context(
enum dc_status dce80_validate_guaranteed( enum dc_status dce80_validate_guaranteed(
const struct core_dc *dc, const struct core_dc *dc,
const struct dc_target *dc_target, const struct dc_stream *dc_stream,
struct validate_context *context) struct validate_context *context)
{ {
enum dc_status result = DC_ERROR_UNEXPECTED; enum dc_status result = DC_ERROR_UNEXPECTED;
context->res_ctx.pool = dc->res_pool; context->res_ctx.pool = dc->res_pool;
context->targets[0] = DC_TARGET_TO_CORE(dc_target); context->streams[0] = DC_STREAM_TO_CORE(dc_stream);
dc_target_retain(&context->targets[0]->public); dc_stream_retain(&context->streams[0]->public);
context->target_count++; context->stream_count++;
result = resource_map_pool_resources(dc, context); result = resource_map_pool_resources(dc, context);
...@@ -888,8 +883,8 @@ enum dc_status dce80_validate_guaranteed( ...@@ -888,8 +883,8 @@ enum dc_status dce80_validate_guaranteed(
result = validate_mapped_resource(dc, context); result = validate_mapped_resource(dc, context);
if (result == DC_OK) { if (result == DC_OK) {
validate_guaranteed_copy_target( validate_guaranteed_copy_streams(
context, dc->public.caps.max_targets); context, dc->public.caps.max_streams);
result = resource_build_scaling_params_for_context(dc, context); result = resource_build_scaling_params_for_context(dc, context);
} }
......
...@@ -21,7 +21,6 @@ struct core_dc { ...@@ -21,7 +21,6 @@ struct core_dc {
uint8_t link_count; uint8_t link_count;
struct core_link *links[MAX_PIPES * 2]; struct core_link *links[MAX_PIPES * 2];
/* TODO: determine max number of targets*/
struct validate_context *current_context; struct validate_context *current_context;
struct validate_context *temp_flip_context; struct validate_context *temp_flip_context;
struct validate_context *scratch_val_ctx; struct validate_context *scratch_val_ctx;
......
...@@ -32,21 +32,10 @@ ...@@ -32,21 +32,10 @@
#include "dc_bios_types.h" #include "dc_bios_types.h"
struct core_stream; struct core_stream;
/********* core_target *************/
#define CONST_DC_TARGET_TO_CORE(dc_target) \
container_of(dc_target, const struct core_target, public)
#define DC_TARGET_TO_CORE(dc_target) \
container_of(dc_target, struct core_target, public)
#define MAX_PIPES 6 #define MAX_PIPES 6
#define MAX_CLOCK_SOURCES 7 #define MAX_CLOCK_SOURCES 7
struct core_target {
struct dc_target public;
struct dc_context *ctx;
};
/********* core_surface **********/ /********* core_surface **********/
#define DC_SURFACE_TO_CORE(dc_surface) \ #define DC_SURFACE_TO_CORE(dc_surface) \
...@@ -215,7 +204,7 @@ struct resource_funcs { ...@@ -215,7 +204,7 @@ struct resource_funcs {
enum dc_status (*validate_guaranteed)( enum dc_status (*validate_guaranteed)(
const struct core_dc *dc, const struct core_dc *dc,
const struct dc_target *dc_target, const struct dc_stream *stream,
struct validate_context *context); struct validate_context *context);
enum dc_status (*validate_bandwidth)( enum dc_status (*validate_bandwidth)(
...@@ -312,9 +301,9 @@ struct resource_context { ...@@ -312,9 +301,9 @@ struct resource_context {
}; };
struct validate_context { struct validate_context {
struct core_target *targets[MAX_PIPES]; struct core_stream *streams[MAX_PIPES];
struct dc_target_status target_status[MAX_PIPES]; struct dc_stream_status stream_status[MAX_PIPES];
uint8_t target_count; uint8_t stream_count;
struct resource_context res_ctx; struct resource_context res_ctx;
......
...@@ -118,25 +118,26 @@ struct pipe_ctx *resource_get_head_pipe_for_stream( ...@@ -118,25 +118,26 @@ struct pipe_ctx *resource_get_head_pipe_for_stream(
bool resource_attach_surfaces_to_context( bool resource_attach_surfaces_to_context(
const struct dc_surface *const *surfaces, const struct dc_surface *const *surfaces,
int surface_count, int surface_count,
const struct dc_target *dc_target, const struct dc_stream *dc_stream,
struct validate_context *context); struct validate_context *context);
struct pipe_ctx *find_idle_secondary_pipe(struct resource_context *res_ctx); struct pipe_ctx *find_idle_secondary_pipe(struct resource_context *res_ctx);
bool resource_is_stream_unchanged( bool resource_is_stream_unchanged(
const struct validate_context *old_context, struct core_stream *stream); const struct validate_context *old_context, const struct core_stream *stream);
bool is_stream_unchanged(
const struct core_stream *old_stream, const struct core_stream *stream);
bool is_target_unchanged(
const struct core_target *old_target, const struct core_target *target);
bool resource_validate_attach_surfaces( bool resource_validate_attach_surfaces(
const struct dc_validation_set set[], const struct dc_validation_set set[],
int set_count, int set_count,
const struct validate_context *old_context, const struct validate_context *old_context,
struct validate_context *context); struct validate_context *context);
void validate_guaranteed_copy_target( void validate_guaranteed_copy_streams(
struct validate_context *context, struct validate_context *context,
int max_targets); int max_streams);
void resource_validate_ctx_update_pointer_after_copy( void resource_validate_ctx_update_pointer_after_copy(
const struct validate_context *src_ctx, const struct validate_context *src_ctx,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册