Merge tag 'noinstr-lds-2020-05-19' into core/rcu
Get the noinstr section and annotation markers to base the RCU parts on.
This commit is contained in:
@@ -3372,15 +3372,12 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon)
|
||||
}
|
||||
}
|
||||
|
||||
amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
|
||||
amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);
|
||||
|
||||
amdgpu_amdkfd_suspend(adev, !fbcon);
|
||||
|
||||
amdgpu_ras_suspend(adev);
|
||||
|
||||
r = amdgpu_device_ip_suspend_phase1(adev);
|
||||
|
||||
amdgpu_amdkfd_suspend(adev, !fbcon);
|
||||
|
||||
/* evict vram memory */
|
||||
amdgpu_bo_evict_vram(adev);
|
||||
|
||||
|
||||
@@ -85,9 +85,10 @@
|
||||
* - 3.34.0 - Non-DC can flip correctly between buffers with different pitches
|
||||
* - 3.35.0 - Add drm_amdgpu_info_device::tcc_disabled_mask
|
||||
* - 3.36.0 - Allow reading more status registers on si/cik
|
||||
* - 3.37.0 - L2 is invalidated before SDMA IBs, needed for correctness
|
||||
*/
|
||||
#define KMS_DRIVER_MAJOR 3
|
||||
#define KMS_DRIVER_MINOR 36
|
||||
#define KMS_DRIVER_MINOR 37
|
||||
#define KMS_DRIVER_PATCHLEVEL 0
|
||||
|
||||
int amdgpu_vram_limit = 0;
|
||||
|
||||
@@ -73,6 +73,22 @@
|
||||
#define SDMA_OP_AQL_COPY 0
|
||||
#define SDMA_OP_AQL_BARRIER_OR 0
|
||||
|
||||
#define SDMA_GCR_RANGE_IS_PA (1 << 18)
|
||||
#define SDMA_GCR_SEQ(x) (((x) & 0x3) << 16)
|
||||
#define SDMA_GCR_GL2_WB (1 << 15)
|
||||
#define SDMA_GCR_GL2_INV (1 << 14)
|
||||
#define SDMA_GCR_GL2_DISCARD (1 << 13)
|
||||
#define SDMA_GCR_GL2_RANGE(x) (((x) & 0x3) << 11)
|
||||
#define SDMA_GCR_GL2_US (1 << 10)
|
||||
#define SDMA_GCR_GL1_INV (1 << 9)
|
||||
#define SDMA_GCR_GLV_INV (1 << 8)
|
||||
#define SDMA_GCR_GLK_INV (1 << 7)
|
||||
#define SDMA_GCR_GLK_WB (1 << 6)
|
||||
#define SDMA_GCR_GLM_INV (1 << 5)
|
||||
#define SDMA_GCR_GLM_WB (1 << 4)
|
||||
#define SDMA_GCR_GL1_RANGE(x) (((x) & 0x3) << 2)
|
||||
#define SDMA_GCR_GLI_INV(x) (((x) & 0x3) << 0)
|
||||
|
||||
/*define for op field*/
|
||||
#define SDMA_PKT_HEADER_op_offset 0
|
||||
#define SDMA_PKT_HEADER_op_mask 0x000000FF
|
||||
|
||||
@@ -382,6 +382,18 @@ static void sdma_v5_0_ring_emit_ib(struct amdgpu_ring *ring,
|
||||
unsigned vmid = AMDGPU_JOB_GET_VMID(job);
|
||||
uint64_t csa_mc_addr = amdgpu_sdma_get_csa_mc_addr(ring, vmid);
|
||||
|
||||
/* Invalidate L2, because if we don't do it, we might get stale cache
|
||||
* lines from previous IBs.
|
||||
*/
|
||||
amdgpu_ring_write(ring, SDMA_PKT_HEADER_OP(SDMA_OP_GCR_REQ));
|
||||
amdgpu_ring_write(ring, 0);
|
||||
amdgpu_ring_write(ring, (SDMA_GCR_GL2_INV |
|
||||
SDMA_GCR_GL2_WB |
|
||||
SDMA_GCR_GLM_INV |
|
||||
SDMA_GCR_GLM_WB) << 16);
|
||||
amdgpu_ring_write(ring, 0xffffff80);
|
||||
amdgpu_ring_write(ring, 0xffff);
|
||||
|
||||
/* An IB packet must end on a 8 DW boundary--the next dword
|
||||
* must be on a 8-dword boundary. Our IB packet below is 6
|
||||
* dwords long, thus add x number of NOPs, such that, in
|
||||
@@ -1595,7 +1607,7 @@ static const struct amdgpu_ring_funcs sdma_v5_0_ring_funcs = {
|
||||
SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
|
||||
SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 6 * 2 +
|
||||
10 + 10 + 10, /* sdma_v5_0_ring_emit_fence x3 for user fence, vm fence */
|
||||
.emit_ib_size = 7 + 6, /* sdma_v5_0_ring_emit_ib */
|
||||
.emit_ib_size = 5 + 7 + 6, /* sdma_v5_0_ring_emit_ib */
|
||||
.emit_ib = sdma_v5_0_ring_emit_ib,
|
||||
.emit_fence = sdma_v5_0_ring_emit_fence,
|
||||
.emit_pipeline_sync = sdma_v5_0_ring_emit_pipeline_sync,
|
||||
|
||||
@@ -2008,17 +2008,22 @@ void amdgpu_dm_update_connector_after_detect(
|
||||
dc_sink_retain(aconnector->dc_sink);
|
||||
if (sink->dc_edid.length == 0) {
|
||||
aconnector->edid = NULL;
|
||||
drm_dp_cec_unset_edid(&aconnector->dm_dp_aux.aux);
|
||||
if (aconnector->dc_link->aux_mode) {
|
||||
drm_dp_cec_unset_edid(
|
||||
&aconnector->dm_dp_aux.aux);
|
||||
}
|
||||
} else {
|
||||
aconnector->edid =
|
||||
(struct edid *) sink->dc_edid.raw_edid;
|
||||
|
||||
(struct edid *)sink->dc_edid.raw_edid;
|
||||
|
||||
drm_connector_update_edid_property(connector,
|
||||
aconnector->edid);
|
||||
drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux,
|
||||
aconnector->edid);
|
||||
aconnector->edid);
|
||||
|
||||
if (aconnector->dc_link->aux_mode)
|
||||
drm_dp_cec_set_edid(&aconnector->dm_dp_aux.aux,
|
||||
aconnector->edid);
|
||||
}
|
||||
|
||||
amdgpu_dm_update_freesync_caps(connector, aconnector->edid);
|
||||
update_connector_ext_caps(aconnector);
|
||||
} else {
|
||||
@@ -3340,7 +3345,8 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
|
||||
const union dc_tiling_info *tiling_info,
|
||||
const uint64_t info,
|
||||
struct dc_plane_dcc_param *dcc,
|
||||
struct dc_plane_address *address)
|
||||
struct dc_plane_address *address,
|
||||
bool force_disable_dcc)
|
||||
{
|
||||
struct dc *dc = adev->dm.dc;
|
||||
struct dc_dcc_surface_param input;
|
||||
@@ -3352,6 +3358,9 @@ fill_plane_dcc_attributes(struct amdgpu_device *adev,
|
||||
memset(&input, 0, sizeof(input));
|
||||
memset(&output, 0, sizeof(output));
|
||||
|
||||
if (force_disable_dcc)
|
||||
return 0;
|
||||
|
||||
if (!offset)
|
||||
return 0;
|
||||
|
||||
@@ -3401,7 +3410,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
|
||||
union dc_tiling_info *tiling_info,
|
||||
struct plane_size *plane_size,
|
||||
struct dc_plane_dcc_param *dcc,
|
||||
struct dc_plane_address *address)
|
||||
struct dc_plane_address *address,
|
||||
bool force_disable_dcc)
|
||||
{
|
||||
const struct drm_framebuffer *fb = &afb->base;
|
||||
int ret;
|
||||
@@ -3507,7 +3517,8 @@ fill_plane_buffer_attributes(struct amdgpu_device *adev,
|
||||
|
||||
ret = fill_plane_dcc_attributes(adev, afb, format, rotation,
|
||||
plane_size, tiling_info,
|
||||
tiling_flags, dcc, address);
|
||||
tiling_flags, dcc, address,
|
||||
force_disable_dcc);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@@ -3599,7 +3610,8 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
|
||||
const struct drm_plane_state *plane_state,
|
||||
const uint64_t tiling_flags,
|
||||
struct dc_plane_info *plane_info,
|
||||
struct dc_plane_address *address)
|
||||
struct dc_plane_address *address,
|
||||
bool force_disable_dcc)
|
||||
{
|
||||
const struct drm_framebuffer *fb = plane_state->fb;
|
||||
const struct amdgpu_framebuffer *afb =
|
||||
@@ -3681,7 +3693,8 @@ fill_dc_plane_info_and_addr(struct amdgpu_device *adev,
|
||||
plane_info->rotation, tiling_flags,
|
||||
&plane_info->tiling_info,
|
||||
&plane_info->plane_size,
|
||||
&plane_info->dcc, address);
|
||||
&plane_info->dcc, address,
|
||||
force_disable_dcc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -3704,6 +3717,7 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
|
||||
struct dc_plane_info plane_info;
|
||||
uint64_t tiling_flags;
|
||||
int ret;
|
||||
bool force_disable_dcc = false;
|
||||
|
||||
ret = fill_dc_scaling_info(plane_state, &scaling_info);
|
||||
if (ret)
|
||||
@@ -3718,9 +3732,11 @@ static int fill_dc_plane_attributes(struct amdgpu_device *adev,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend;
|
||||
ret = fill_dc_plane_info_and_addr(adev, plane_state, tiling_flags,
|
||||
&plane_info,
|
||||
&dc_plane_state->address);
|
||||
&dc_plane_state->address,
|
||||
force_disable_dcc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -4664,6 +4680,7 @@ static void amdgpu_dm_connector_destroy(struct drm_connector *connector)
|
||||
i2c_del_adapter(&aconnector->i2c->base);
|
||||
kfree(aconnector->i2c);
|
||||
}
|
||||
kfree(aconnector->dm_dp_aux.aux.name);
|
||||
|
||||
kfree(connector);
|
||||
}
|
||||
@@ -4723,10 +4740,19 @@ amdgpu_dm_connector_atomic_duplicate_state(struct drm_connector *connector)
|
||||
static int
|
||||
amdgpu_dm_connector_late_register(struct drm_connector *connector)
|
||||
{
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
struct amdgpu_dm_connector *amdgpu_dm_connector =
|
||||
to_amdgpu_dm_connector(connector);
|
||||
int r;
|
||||
|
||||
if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
|
||||
(connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
|
||||
amdgpu_dm_connector->dm_dp_aux.aux.dev = connector->kdev;
|
||||
r = drm_dp_aux_register(&amdgpu_dm_connector->dm_dp_aux.aux);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
connector_debugfs_init(amdgpu_dm_connector);
|
||||
#endif
|
||||
|
||||
@@ -5332,6 +5358,7 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
|
||||
uint64_t tiling_flags;
|
||||
uint32_t domain;
|
||||
int r;
|
||||
bool force_disable_dcc = false;
|
||||
|
||||
dm_plane_state_old = to_dm_plane_state(plane->state);
|
||||
dm_plane_state_new = to_dm_plane_state(new_state);
|
||||
@@ -5390,11 +5417,13 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
|
||||
dm_plane_state_old->dc_state != dm_plane_state_new->dc_state) {
|
||||
struct dc_plane_state *plane_state = dm_plane_state_new->dc_state;
|
||||
|
||||
force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend;
|
||||
fill_plane_buffer_attributes(
|
||||
adev, afb, plane_state->format, plane_state->rotation,
|
||||
tiling_flags, &plane_state->tiling_info,
|
||||
&plane_state->plane_size, &plane_state->dcc,
|
||||
&plane_state->address);
|
||||
&plane_state->address,
|
||||
force_disable_dcc);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -6092,7 +6121,7 @@ static int amdgpu_dm_connector_init(struct amdgpu_display_manager *dm,
|
||||
|
||||
if (connector_type == DRM_MODE_CONNECTOR_DisplayPort
|
||||
|| connector_type == DRM_MODE_CONNECTOR_eDP)
|
||||
amdgpu_dm_initialize_dp_connector(dm, aconnector);
|
||||
amdgpu_dm_initialize_dp_connector(dm, aconnector, link->link_index);
|
||||
|
||||
out_free:
|
||||
if (res) {
|
||||
@@ -6666,7 +6695,12 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
|
||||
fill_dc_plane_info_and_addr(
|
||||
dm->adev, new_plane_state, tiling_flags,
|
||||
&bundle->plane_infos[planes_count],
|
||||
&bundle->flip_addrs[planes_count].address);
|
||||
&bundle->flip_addrs[planes_count].address,
|
||||
false);
|
||||
|
||||
DRM_DEBUG_DRIVER("plane: id=%d dcc_en=%d\n",
|
||||
new_plane_state->plane->index,
|
||||
bundle->plane_infos[planes_count].dcc.enable);
|
||||
|
||||
bundle->surface_updates[planes_count].plane_info =
|
||||
&bundle->plane_infos[planes_count];
|
||||
@@ -8086,7 +8120,8 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm,
|
||||
ret = fill_dc_plane_info_and_addr(
|
||||
dm->adev, new_plane_state, tiling_flags,
|
||||
plane_info,
|
||||
&flip_addr->address);
|
||||
&flip_addr->address,
|
||||
false);
|
||||
if (ret)
|
||||
goto cleanup;
|
||||
|
||||
|
||||
@@ -156,16 +156,16 @@ amdgpu_dm_mst_connector_late_register(struct drm_connector *connector)
|
||||
to_amdgpu_dm_connector(connector);
|
||||
int r;
|
||||
|
||||
amdgpu_dm_connector->dm_dp_aux.aux.dev = connector->kdev;
|
||||
r = drm_dp_aux_register(&amdgpu_dm_connector->dm_dp_aux.aux);
|
||||
if (r)
|
||||
r = drm_dp_mst_connector_late_register(connector,
|
||||
amdgpu_dm_connector->port);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
connector_debugfs_init(amdgpu_dm_connector);
|
||||
#endif
|
||||
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -472,9 +472,12 @@ static const struct drm_dp_mst_topology_cbs dm_mst_cbs = {
|
||||
};
|
||||
|
||||
void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
|
||||
struct amdgpu_dm_connector *aconnector)
|
||||
struct amdgpu_dm_connector *aconnector,
|
||||
int link_index)
|
||||
{
|
||||
aconnector->dm_dp_aux.aux.name = "dmdc";
|
||||
aconnector->dm_dp_aux.aux.name =
|
||||
kasprintf(GFP_KERNEL, "AMDGPU DM aux hw bus %d",
|
||||
link_index);
|
||||
aconnector->dm_dp_aux.aux.transfer = dm_dp_aux_transfer;
|
||||
aconnector->dm_dp_aux.ddc_service = aconnector->dc_link->ddc;
|
||||
|
||||
|
||||
@@ -32,7 +32,8 @@ struct amdgpu_dm_connector;
|
||||
int dm_mst_get_pbn_divider(struct dc_link *link);
|
||||
|
||||
void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm,
|
||||
struct amdgpu_dm_connector *aconnector);
|
||||
struct amdgpu_dm_connector *aconnector,
|
||||
int link_index);
|
||||
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
bool compute_mst_dsc_configs_for_state(struct drm_atomic_state *state,
|
||||
|
||||
@@ -834,11 +834,10 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
|
||||
static void wait_for_no_pipes_pending(struct dc *dc, struct dc_state *context)
|
||||
{
|
||||
int i;
|
||||
int count = 0;
|
||||
struct pipe_ctx *pipe;
|
||||
PERF_TRACE();
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe = &context->res_ctx.pipe_ctx[i];
|
||||
int count = 0;
|
||||
struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
|
||||
|
||||
if (!pipe->plane_state)
|
||||
continue;
|
||||
|
||||
@@ -2908,6 +2908,12 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd
|
||||
sizeof(hpd_irq_dpcd_data),
|
||||
"Status: ");
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link)
|
||||
link->dc->hwss.blank_stream(pipe_ctx);
|
||||
}
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link)
|
||||
@@ -2927,6 +2933,12 @@ bool dc_link_handle_hpd_rx_irq(struct dc_link *link, union hpd_irq_data *out_hpd
|
||||
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
|
||||
dc_link_reallocate_mst_payload(link);
|
||||
|
||||
for (i = 0; i < MAX_PIPES; i++) {
|
||||
pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
|
||||
if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link)
|
||||
link->dc->hwss.unblank_stream(pipe_ctx, &previous_link_settings);
|
||||
}
|
||||
|
||||
status = false;
|
||||
if (out_link_loss)
|
||||
*out_link_loss = true;
|
||||
@@ -4227,6 +4239,21 @@ void dp_set_fec_enable(struct dc_link *link, bool enable)
|
||||
void dpcd_set_source_specific_data(struct dc_link *link)
|
||||
{
|
||||
const uint32_t post_oui_delay = 30; // 30ms
|
||||
uint8_t dspc = 0;
|
||||
enum dc_status ret = DC_ERROR_UNEXPECTED;
|
||||
|
||||
ret = core_link_read_dpcd(link, DP_DOWN_STREAM_PORT_COUNT, &dspc,
|
||||
sizeof(dspc));
|
||||
|
||||
if (ret != DC_OK) {
|
||||
DC_LOG_ERROR("Error in DP aux read transaction,"
|
||||
" not writing source specific data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Return if OUI unsupported */
|
||||
if (!(dspc & DP_OUI_SUPPORT))
|
||||
return;
|
||||
|
||||
if (!link->dc->vendor_signature.is_valid) {
|
||||
struct dpcd_amd_signature amd_signature;
|
||||
|
||||
@@ -231,34 +231,6 @@ struct dc_stream_status *dc_stream_get_status(
|
||||
return dc_stream_get_status_from_state(dc->current_state, stream);
|
||||
}
|
||||
|
||||
static void delay_cursor_until_vupdate(struct pipe_ctx *pipe_ctx, struct dc *dc)
|
||||
{
|
||||
#if defined(CONFIG_DRM_AMD_DC_DCN)
|
||||
unsigned int vupdate_line;
|
||||
unsigned int lines_to_vupdate, us_to_vupdate, vpos, nvpos;
|
||||
struct dc_stream_state *stream = pipe_ctx->stream;
|
||||
unsigned int us_per_line;
|
||||
|
||||
if (stream->ctx->asic_id.chip_family == FAMILY_RV &&
|
||||
ASICREV_IS_RAVEN(stream->ctx->asic_id.hw_internal_rev)) {
|
||||
|
||||
vupdate_line = dc->hwss.get_vupdate_offset_from_vsync(pipe_ctx);
|
||||
if (!dc_stream_get_crtc_position(dc, &stream, 1, &vpos, &nvpos))
|
||||
return;
|
||||
|
||||
if (vpos >= vupdate_line)
|
||||
return;
|
||||
|
||||
us_per_line = stream->timing.h_total * 10000 / stream->timing.pix_clk_100hz;
|
||||
lines_to_vupdate = vupdate_line - vpos;
|
||||
us_to_vupdate = lines_to_vupdate * us_per_line;
|
||||
|
||||
/* 70 us is a conservative estimate of cursor update time*/
|
||||
if (us_to_vupdate < 70)
|
||||
udelay(us_to_vupdate);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* dc_stream_set_cursor_attributes() - Update cursor attributes and set cursor surface address
|
||||
@@ -298,9 +270,7 @@ bool dc_stream_set_cursor_attributes(
|
||||
|
||||
if (!pipe_to_program) {
|
||||
pipe_to_program = pipe_ctx;
|
||||
|
||||
delay_cursor_until_vupdate(pipe_ctx, dc);
|
||||
dc->hwss.pipe_control_lock(dc, pipe_to_program, true);
|
||||
dc->hwss.cursor_lock(dc, pipe_to_program, true);
|
||||
}
|
||||
|
||||
dc->hwss.set_cursor_attribute(pipe_ctx);
|
||||
@@ -309,7 +279,7 @@ bool dc_stream_set_cursor_attributes(
|
||||
}
|
||||
|
||||
if (pipe_to_program)
|
||||
dc->hwss.pipe_control_lock(dc, pipe_to_program, false);
|
||||
dc->hwss.cursor_lock(dc, pipe_to_program, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -349,16 +319,14 @@ bool dc_stream_set_cursor_position(
|
||||
|
||||
if (!pipe_to_program) {
|
||||
pipe_to_program = pipe_ctx;
|
||||
|
||||
delay_cursor_until_vupdate(pipe_ctx, dc);
|
||||
dc->hwss.pipe_control_lock(dc, pipe_to_program, true);
|
||||
dc->hwss.cursor_lock(dc, pipe_to_program, true);
|
||||
}
|
||||
|
||||
dc->hwss.set_cursor_position(pipe_ctx);
|
||||
}
|
||||
|
||||
if (pipe_to_program)
|
||||
dc->hwss.pipe_control_lock(dc, pipe_to_program, false);
|
||||
dc->hwss.cursor_lock(dc, pipe_to_program, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2757,6 +2757,7 @@ static const struct hw_sequencer_funcs dce110_funcs = {
|
||||
.disable_plane = dce110_power_down_fe,
|
||||
.pipe_control_lock = dce_pipe_control_lock,
|
||||
.interdependent_update_lock = NULL,
|
||||
.cursor_lock = dce_pipe_control_lock,
|
||||
.prepare_bandwidth = dce110_prepare_bandwidth,
|
||||
.optimize_bandwidth = dce110_optimize_bandwidth,
|
||||
.set_drr = set_drr,
|
||||
|
||||
@@ -1625,6 +1625,16 @@ void dcn10_pipe_control_lock(
|
||||
hws->funcs.verify_allow_pstate_change_high(dc);
|
||||
}
|
||||
|
||||
void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock)
|
||||
{
|
||||
/* cursor lock is per MPCC tree, so only need to lock one pipe per stream */
|
||||
if (!pipe || pipe->top_pipe)
|
||||
return;
|
||||
|
||||
dc->res_pool->mpc->funcs->cursor_lock(dc->res_pool->mpc,
|
||||
pipe->stream_res.opp->inst, lock);
|
||||
}
|
||||
|
||||
static bool wait_for_reset_trigger_to_occur(
|
||||
struct dc_context *dc_ctx,
|
||||
struct timing_generator *tg)
|
||||
|
||||
@@ -49,6 +49,7 @@ void dcn10_pipe_control_lock(
|
||||
struct dc *dc,
|
||||
struct pipe_ctx *pipe,
|
||||
bool lock);
|
||||
void dcn10_cursor_lock(struct dc *dc, struct pipe_ctx *pipe, bool lock);
|
||||
void dcn10_blank_pixel_data(
|
||||
struct dc *dc,
|
||||
struct pipe_ctx *pipe_ctx,
|
||||
|
||||
@@ -50,6 +50,7 @@ static const struct hw_sequencer_funcs dcn10_funcs = {
|
||||
.disable_audio_stream = dce110_disable_audio_stream,
|
||||
.disable_plane = dcn10_disable_plane,
|
||||
.pipe_control_lock = dcn10_pipe_control_lock,
|
||||
.cursor_lock = dcn10_cursor_lock,
|
||||
.interdependent_update_lock = dcn10_lock_all_pipes,
|
||||
.prepare_bandwidth = dcn10_prepare_bandwidth,
|
||||
.optimize_bandwidth = dcn10_optimize_bandwidth,
|
||||
|
||||
@@ -223,6 +223,9 @@ struct mpcc *mpc1_insert_plane(
|
||||
REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, dpp_id);
|
||||
REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, tree->opp_id);
|
||||
|
||||
/* Configure VUPDATE lock set for this MPCC to map to the OPP */
|
||||
REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, tree->opp_id);
|
||||
|
||||
/* update mpc tree mux setting */
|
||||
if (tree->opp_list == insert_above_mpcc) {
|
||||
/* insert the toppest mpcc */
|
||||
@@ -318,6 +321,7 @@ void mpc1_remove_mpcc(
|
||||
REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
|
||||
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
|
||||
REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
|
||||
REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf);
|
||||
|
||||
/* mark this mpcc as not in use */
|
||||
mpc10->mpcc_in_use_mask &= ~(1 << mpcc_id);
|
||||
@@ -328,6 +332,7 @@ void mpc1_remove_mpcc(
|
||||
REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
|
||||
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
|
||||
REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
|
||||
REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,6 +366,7 @@ void mpc1_mpc_init(struct mpc *mpc)
|
||||
REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
|
||||
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
|
||||
REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
|
||||
REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf);
|
||||
|
||||
mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id);
|
||||
}
|
||||
@@ -381,6 +387,7 @@ void mpc1_mpc_init_single_inst(struct mpc *mpc, unsigned int mpcc_id)
|
||||
REG_SET(MPCC_TOP_SEL[mpcc_id], 0, MPCC_TOP_SEL, 0xf);
|
||||
REG_SET(MPCC_BOT_SEL[mpcc_id], 0, MPCC_BOT_SEL, 0xf);
|
||||
REG_SET(MPCC_OPP_ID[mpcc_id], 0, MPCC_OPP_ID, 0xf);
|
||||
REG_SET(MPCC_UPDATE_LOCK_SEL[mpcc_id], 0, MPCC_UPDATE_LOCK_SEL, 0xf);
|
||||
|
||||
mpc1_init_mpcc(&(mpc->mpcc_array[mpcc_id]), mpcc_id);
|
||||
|
||||
@@ -453,6 +460,13 @@ void mpc1_read_mpcc_state(
|
||||
MPCC_BUSY, &s->busy);
|
||||
}
|
||||
|
||||
void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock)
|
||||
{
|
||||
struct dcn10_mpc *mpc10 = TO_DCN10_MPC(mpc);
|
||||
|
||||
REG_SET(CUR[opp_id], 0, CUR_VUPDATE_LOCK_SET, lock ? 1 : 0);
|
||||
}
|
||||
|
||||
static const struct mpc_funcs dcn10_mpc_funcs = {
|
||||
.read_mpcc_state = mpc1_read_mpcc_state,
|
||||
.insert_plane = mpc1_insert_plane,
|
||||
@@ -464,6 +478,7 @@ static const struct mpc_funcs dcn10_mpc_funcs = {
|
||||
.assert_mpcc_idle_before_connect = mpc1_assert_mpcc_idle_before_connect,
|
||||
.init_mpcc_list_from_hw = mpc1_init_mpcc_list_from_hw,
|
||||
.update_blending = mpc1_update_blending,
|
||||
.cursor_lock = mpc1_cursor_lock,
|
||||
.set_denorm = NULL,
|
||||
.set_denorm_clamp = NULL,
|
||||
.set_output_csc = NULL,
|
||||
|
||||
@@ -39,11 +39,12 @@
|
||||
SRII(MPCC_BG_G_Y, MPCC, inst),\
|
||||
SRII(MPCC_BG_R_CR, MPCC, inst),\
|
||||
SRII(MPCC_BG_B_CB, MPCC, inst),\
|
||||
SRII(MPCC_BG_B_CB, MPCC, inst),\
|
||||
SRII(MPCC_SM_CONTROL, MPCC, inst)
|
||||
SRII(MPCC_SM_CONTROL, MPCC, inst),\
|
||||
SRII(MPCC_UPDATE_LOCK_SEL, MPCC, inst)
|
||||
|
||||
#define MPC_OUT_MUX_COMMON_REG_LIST_DCN1_0(inst) \
|
||||
SRII(MUX, MPC_OUT, inst)
|
||||
SRII(MUX, MPC_OUT, inst),\
|
||||
VUPDATE_SRII(CUR, VUPDATE_LOCK_SET, inst)
|
||||
|
||||
#define MPC_COMMON_REG_VARIABLE_LIST \
|
||||
uint32_t MPCC_TOP_SEL[MAX_MPCC]; \
|
||||
@@ -55,7 +56,9 @@
|
||||
uint32_t MPCC_BG_R_CR[MAX_MPCC]; \
|
||||
uint32_t MPCC_BG_B_CB[MAX_MPCC]; \
|
||||
uint32_t MPCC_SM_CONTROL[MAX_MPCC]; \
|
||||
uint32_t MUX[MAX_OPP];
|
||||
uint32_t MUX[MAX_OPP]; \
|
||||
uint32_t MPCC_UPDATE_LOCK_SEL[MAX_MPCC]; \
|
||||
uint32_t CUR[MAX_OPP];
|
||||
|
||||
#define MPC_COMMON_MASK_SH_LIST_DCN1_0(mask_sh)\
|
||||
SF(MPCC0_MPCC_TOP_SEL, MPCC_TOP_SEL, mask_sh),\
|
||||
@@ -78,7 +81,8 @@
|
||||
SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FIELD_ALT, mask_sh),\
|
||||
SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_FRAME_POL, mask_sh),\
|
||||
SF(MPCC0_MPCC_SM_CONTROL, MPCC_SM_FORCE_NEXT_TOP_POL, mask_sh),\
|
||||
SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh)
|
||||
SF(MPC_OUT0_MUX, MPC_OUT_MUX, mask_sh),\
|
||||
SF(MPCC0_MPCC_UPDATE_LOCK_SEL, MPCC_UPDATE_LOCK_SEL, mask_sh)
|
||||
|
||||
#define MPC_REG_FIELD_LIST(type) \
|
||||
type MPCC_TOP_SEL;\
|
||||
@@ -101,7 +105,9 @@
|
||||
type MPCC_SM_FIELD_ALT;\
|
||||
type MPCC_SM_FORCE_NEXT_FRAME_POL;\
|
||||
type MPCC_SM_FORCE_NEXT_TOP_POL;\
|
||||
type MPC_OUT_MUX;
|
||||
type MPC_OUT_MUX;\
|
||||
type MPCC_UPDATE_LOCK_SEL;\
|
||||
type CUR_VUPDATE_LOCK_SET;
|
||||
|
||||
struct dcn_mpc_registers {
|
||||
MPC_COMMON_REG_VARIABLE_LIST
|
||||
@@ -192,4 +198,6 @@ void mpc1_read_mpcc_state(
|
||||
int mpcc_inst,
|
||||
struct mpcc_state *s);
|
||||
|
||||
void mpc1_cursor_lock(struct mpc *mpc, int opp_id, bool lock);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -181,6 +181,14 @@ enum dcn10_clk_src_array_id {
|
||||
.reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
|
||||
mm ## block ## id ## _ ## reg_name
|
||||
|
||||
#define VUPDATE_SRII(reg_name, block, id)\
|
||||
.reg_name[id] = BASE(mm ## reg_name ## 0 ## _ ## block ## id ## _BASE_IDX) + \
|
||||
mm ## reg_name ## 0 ## _ ## block ## id
|
||||
|
||||
/* set field/register/bitfield name */
|
||||
#define SFRB(field_name, reg_name, bitfield, post_fix)\
|
||||
.field_name = reg_name ## __ ## bitfield ## post_fix
|
||||
|
||||
/* NBIO */
|
||||
#define NBIO_BASE_INNER(seg) \
|
||||
NBIF_BASE__INST0_SEG ## seg
|
||||
@@ -419,11 +427,13 @@ static const struct dcn_mpc_registers mpc_regs = {
|
||||
};
|
||||
|
||||
static const struct dcn_mpc_shift mpc_shift = {
|
||||
MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT)
|
||||
MPC_COMMON_MASK_SH_LIST_DCN1_0(__SHIFT),\
|
||||
SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, __SHIFT)
|
||||
};
|
||||
|
||||
static const struct dcn_mpc_mask mpc_mask = {
|
||||
MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK),
|
||||
MPC_COMMON_MASK_SH_LIST_DCN1_0(_MASK),\
|
||||
SFRB(CUR_VUPDATE_LOCK_SET, CUR0_VUPDATE_LOCK_SET0, CUR0_VUPDATE_LOCK_SET, _MASK)
|
||||
};
|
||||
|
||||
#define tg_regs(id)\
|
||||
|
||||
@@ -2294,7 +2294,8 @@ void dcn20_fpga_init_hw(struct dc *dc)
|
||||
|
||||
REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_REFDIV, 2);
|
||||
REG_UPDATE(DCHUBBUB_GLOBAL_TIMER_CNTL, DCHUBBUB_GLOBAL_TIMER_ENABLE, 1);
|
||||
REG_WRITE(REFCLK_CNTL, 0);
|
||||
if (REG(REFCLK_CNTL))
|
||||
REG_WRITE(REFCLK_CNTL, 0);
|
||||
//
|
||||
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ static const struct hw_sequencer_funcs dcn20_funcs = {
|
||||
.disable_plane = dcn20_disable_plane,
|
||||
.pipe_control_lock = dcn20_pipe_control_lock,
|
||||
.interdependent_update_lock = dcn10_lock_all_pipes,
|
||||
.cursor_lock = dcn10_cursor_lock,
|
||||
.prepare_bandwidth = dcn20_prepare_bandwidth,
|
||||
.optimize_bandwidth = dcn20_optimize_bandwidth,
|
||||
.update_bandwidth = dcn20_update_bandwidth,
|
||||
|
||||
@@ -545,6 +545,7 @@ const struct mpc_funcs dcn20_mpc_funcs = {
|
||||
.mpc_init = mpc1_mpc_init,
|
||||
.mpc_init_single_inst = mpc1_mpc_init_single_inst,
|
||||
.update_blending = mpc2_update_blending,
|
||||
.cursor_lock = mpc1_cursor_lock,
|
||||
.get_mpcc_for_dpp = mpc2_get_mpcc_for_dpp,
|
||||
.wait_for_idle = mpc2_assert_idle_mpcc,
|
||||
.assert_mpcc_idle_before_connect = mpc2_assert_mpcc_idle_before_connect,
|
||||
|
||||
@@ -179,7 +179,8 @@
|
||||
SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MAX_G_Y, mask_sh),\
|
||||
SF(MPC_OUT0_DENORM_CLAMP_G_Y, MPC_OUT_DENORM_CLAMP_MIN_G_Y, mask_sh),\
|
||||
SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MAX_B_CB, mask_sh),\
|
||||
SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh)
|
||||
SF(MPC_OUT0_DENORM_CLAMP_B_CB, MPC_OUT_DENORM_CLAMP_MIN_B_CB, mask_sh),\
|
||||
SF(CUR_VUPDATE_LOCK_SET0, CUR_VUPDATE_LOCK_SET, mask_sh)
|
||||
|
||||
/*
|
||||
* DCN2 MPC_OCSC debug status register:
|
||||
|
||||
@@ -508,6 +508,10 @@ enum dcn20_clk_src_array_id {
|
||||
.block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
|
||||
mm ## block ## id ## _ ## reg_name
|
||||
|
||||
#define VUPDATE_SRII(reg_name, block, id)\
|
||||
.reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \
|
||||
mm ## reg_name ## _ ## block ## id
|
||||
|
||||
/* NBIO */
|
||||
#define NBIO_BASE_INNER(seg) \
|
||||
NBIO_BASE__INST0_SEG ## seg
|
||||
@@ -3064,25 +3068,32 @@ validate_out:
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
|
||||
bool fast_validate)
|
||||
/*
|
||||
* This must be noinline to ensure anything that deals with FP registers
|
||||
* is contained within this call; previously our compiling with hard-float
|
||||
* would result in fp instructions being emitted outside of the boundaries
|
||||
* of the DC_FP_START/END macros, which makes sense as the compiler has no
|
||||
* idea about what is wrapped and what is not
|
||||
*
|
||||
* This is largely just a workaround to avoid breakage introduced with 5.6,
|
||||
* ideally all fp-using code should be moved into its own file, only that
|
||||
* should be compiled with hard-float, and all code exported from there
|
||||
* should be strictly wrapped with DC_FP_START/END
|
||||
*/
|
||||
static noinline bool dcn20_validate_bandwidth_fp(struct dc *dc,
|
||||
struct dc_state *context, bool fast_validate)
|
||||
{
|
||||
bool voltage_supported = false;
|
||||
bool full_pstate_supported = false;
|
||||
bool dummy_pstate_supported = false;
|
||||
double p_state_latency_us;
|
||||
|
||||
DC_FP_START();
|
||||
p_state_latency_us = context->bw_ctx.dml.soc.dram_clock_change_latency_us;
|
||||
context->bw_ctx.dml.soc.disable_dram_clock_change_vactive_support =
|
||||
dc->debug.disable_dram_clock_change_vactive_support;
|
||||
|
||||
if (fast_validate) {
|
||||
voltage_supported = dcn20_validate_bandwidth_internal(dc, context, true);
|
||||
|
||||
DC_FP_END();
|
||||
return voltage_supported;
|
||||
return dcn20_validate_bandwidth_internal(dc, context, true);
|
||||
}
|
||||
|
||||
// Best case, we support full UCLK switch latency
|
||||
@@ -3111,7 +3122,15 @@ bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
|
||||
|
||||
restore_dml_state:
|
||||
context->bw_ctx.dml.soc.dram_clock_change_latency_us = p_state_latency_us;
|
||||
return voltage_supported;
|
||||
}
|
||||
|
||||
bool dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context,
|
||||
bool fast_validate)
|
||||
{
|
||||
bool voltage_supported = false;
|
||||
DC_FP_START();
|
||||
voltage_supported = dcn20_validate_bandwidth_fp(dc, context, fast_validate);
|
||||
DC_FP_END();
|
||||
return voltage_supported;
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ static const struct hw_sequencer_funcs dcn21_funcs = {
|
||||
.disable_plane = dcn20_disable_plane,
|
||||
.pipe_control_lock = dcn20_pipe_control_lock,
|
||||
.interdependent_update_lock = dcn10_lock_all_pipes,
|
||||
.cursor_lock = dcn10_cursor_lock,
|
||||
.prepare_bandwidth = dcn20_prepare_bandwidth,
|
||||
.optimize_bandwidth = dcn20_optimize_bandwidth,
|
||||
.update_bandwidth = dcn20_update_bandwidth,
|
||||
|
||||
@@ -284,7 +284,7 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
|
||||
.dram_channel_width_bytes = 4,
|
||||
.fabric_datapath_to_dcn_data_return_bytes = 32,
|
||||
.dcn_downspread_percent = 0.5,
|
||||
.downspread_percent = 0.5,
|
||||
.downspread_percent = 0.38,
|
||||
.dram_page_open_time_ns = 50.0,
|
||||
.dram_rw_turnaround_time_ns = 17.5,
|
||||
.dram_return_buffer_per_channel_bytes = 8192,
|
||||
@@ -340,6 +340,10 @@ struct _vcs_dpi_soc_bounding_box_st dcn2_1_soc = {
|
||||
.block ## _ ## reg_name[id] = BASE(mm ## block ## id ## _ ## reg_name ## _BASE_IDX) + \
|
||||
mm ## block ## id ## _ ## reg_name
|
||||
|
||||
#define VUPDATE_SRII(reg_name, block, id)\
|
||||
.reg_name[id] = BASE(mm ## reg_name ## _ ## block ## id ## _BASE_IDX) + \
|
||||
mm ## reg_name ## _ ## block ## id
|
||||
|
||||
/* NBIO */
|
||||
#define NBIO_BASE_INNER(seg) \
|
||||
NBIF0_BASE__INST0_SEG ## seg
|
||||
@@ -1374,64 +1378,49 @@ static void update_bw_bounding_box(struct dc *dc, struct clk_bw_params *bw_param
|
||||
{
|
||||
struct dcn21_resource_pool *pool = TO_DCN21_RES_POOL(dc->res_pool);
|
||||
struct clk_limit_table *clk_table = &bw_params->clk_table;
|
||||
unsigned int i, j, k;
|
||||
int closest_clk_lvl;
|
||||
struct _vcs_dpi_voltage_scaling_st clock_limits[DC__VOLTAGE_STATES];
|
||||
unsigned int i, j, closest_clk_lvl;
|
||||
|
||||
// Default clock levels are used for diags, which may lead to overclocking.
|
||||
if (!IS_FPGA_MAXIMUS_DC(dc->ctx->dce_environment) && !IS_DIAG_DC(dc->ctx->dce_environment)) {
|
||||
if (!IS_DIAG_DC(dc->ctx->dce_environment)) {
|
||||
dcn2_1_ip.max_num_otg = pool->base.res_cap->num_timing_generator;
|
||||
dcn2_1_ip.max_num_dpp = pool->base.pipe_count;
|
||||
dcn2_1_soc.num_chans = bw_params->num_channels;
|
||||
|
||||
/* Vmin: leave lowest DCN clocks, override with dcfclk, fclk, memclk from fuse */
|
||||
dcn2_1_soc.clock_limits[0].state = 0;
|
||||
dcn2_1_soc.clock_limits[0].dcfclk_mhz = clk_table->entries[0].dcfclk_mhz;
|
||||
dcn2_1_soc.clock_limits[0].fabricclk_mhz = clk_table->entries[0].fclk_mhz;
|
||||
dcn2_1_soc.clock_limits[0].socclk_mhz = clk_table->entries[0].socclk_mhz;
|
||||
dcn2_1_soc.clock_limits[0].dram_speed_mts = clk_table->entries[0].memclk_mhz * 2;
|
||||
|
||||
/*
|
||||
* Other levels: find closest DCN clocks that fit the given clock limit using dcfclk
|
||||
* as indicator
|
||||
*/
|
||||
|
||||
closest_clk_lvl = -1;
|
||||
/* index currently being filled */
|
||||
k = 1;
|
||||
for (i = 1; i < clk_table->num_entries; i++) {
|
||||
/* loop backwards, skip duplicate state*/
|
||||
for (j = dcn2_1_soc.num_states - 1; j >= k; j--) {
|
||||
ASSERT(clk_table->num_entries);
|
||||
for (i = 0; i < clk_table->num_entries; i++) {
|
||||
/* loop backwards*/
|
||||
for (closest_clk_lvl = 0, j = dcn2_1_soc.num_states - 1; j >= 0; j--) {
|
||||
if ((unsigned int) dcn2_1_soc.clock_limits[j].dcfclk_mhz <= clk_table->entries[i].dcfclk_mhz) {
|
||||
closest_clk_lvl = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if found a lvl that fits, use the DCN clks from it, if not, go to next clk limit*/
|
||||
if (closest_clk_lvl != -1) {
|
||||
dcn2_1_soc.clock_limits[k].state = i;
|
||||
dcn2_1_soc.clock_limits[k].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].socclk_mhz = clk_table->entries[i].socclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
|
||||
clock_limits[i].state = i;
|
||||
clock_limits[i].dcfclk_mhz = clk_table->entries[i].dcfclk_mhz;
|
||||
clock_limits[i].fabricclk_mhz = clk_table->entries[i].fclk_mhz;
|
||||
clock_limits[i].socclk_mhz = clk_table->entries[i].socclk_mhz;
|
||||
clock_limits[i].dram_speed_mts = clk_table->entries[i].memclk_mhz * 2;
|
||||
|
||||
dcn2_1_soc.clock_limits[k].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
|
||||
dcn2_1_soc.clock_limits[k].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
|
||||
dcn2_1_soc.clock_limits[k].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
|
||||
dcn2_1_soc.clock_limits[k].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
|
||||
k++;
|
||||
}
|
||||
clock_limits[i].dispclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dispclk_mhz;
|
||||
clock_limits[i].dppclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dppclk_mhz;
|
||||
clock_limits[i].dram_bw_per_chan_gbps = dcn2_1_soc.clock_limits[closest_clk_lvl].dram_bw_per_chan_gbps;
|
||||
clock_limits[i].dscclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dscclk_mhz;
|
||||
clock_limits[i].dtbclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].dtbclk_mhz;
|
||||
clock_limits[i].phyclk_d18_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_d18_mhz;
|
||||
clock_limits[i].phyclk_mhz = dcn2_1_soc.clock_limits[closest_clk_lvl].phyclk_mhz;
|
||||
}
|
||||
for (i = 0; i < clk_table->num_entries; i++)
|
||||
dcn2_1_soc.clock_limits[i] = clock_limits[i];
|
||||
if (clk_table->num_entries) {
|
||||
dcn2_1_soc.num_states = clk_table->num_entries;
|
||||
/* duplicate last level */
|
||||
dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1];
|
||||
dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states;
|
||||
}
|
||||
dcn2_1_soc.num_states = k;
|
||||
}
|
||||
|
||||
/* duplicate last level */
|
||||
dcn2_1_soc.clock_limits[dcn2_1_soc.num_states] = dcn2_1_soc.clock_limits[dcn2_1_soc.num_states - 1];
|
||||
dcn2_1_soc.clock_limits[dcn2_1_soc.num_states].state = dcn2_1_soc.num_states;
|
||||
|
||||
dml_init_instance(&dc->dml, &dcn2_1_soc, &dcn2_1_ip, DML_PROJECT_DCN21);
|
||||
}
|
||||
|
||||
|
||||
@@ -1200,7 +1200,7 @@ static void dml_rq_dlg_get_dlg_params(
|
||||
min_hratio_fact_l = 1.0;
|
||||
min_hratio_fact_c = 1.0;
|
||||
|
||||
if (htaps_l <= 1)
|
||||
if (hratio_l <= 1)
|
||||
min_hratio_fact_l = 2.0;
|
||||
else if (htaps_l <= 6) {
|
||||
if ((hratio_l * 2.0) > 4.0)
|
||||
@@ -1216,7 +1216,7 @@ static void dml_rq_dlg_get_dlg_params(
|
||||
|
||||
hscale_pixel_rate_l = min_hratio_fact_l * dppclk_freq_in_mhz;
|
||||
|
||||
if (htaps_c <= 1)
|
||||
if (hratio_c <= 1)
|
||||
min_hratio_fact_c = 2.0;
|
||||
else if (htaps_c <= 6) {
|
||||
if ((hratio_c * 2.0) > 4.0)
|
||||
@@ -1522,8 +1522,8 @@ static void dml_rq_dlg_get_dlg_params(
|
||||
|
||||
disp_dlg_regs->refcyc_per_vm_group_vblank = get_refcyc_per_vm_group_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;
|
||||
disp_dlg_regs->refcyc_per_vm_group_flip = get_refcyc_per_vm_group_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;
|
||||
disp_dlg_regs->refcyc_per_vm_req_vblank = get_refcyc_per_vm_req_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;
|
||||
disp_dlg_regs->refcyc_per_vm_req_flip = get_refcyc_per_vm_req_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;
|
||||
disp_dlg_regs->refcyc_per_vm_req_vblank = get_refcyc_per_vm_req_vblank(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz * dml_pow(2, 10);
|
||||
disp_dlg_regs->refcyc_per_vm_req_flip = get_refcyc_per_vm_req_flip(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz * dml_pow(2, 10);
|
||||
|
||||
// Clamp to max for now
|
||||
if (disp_dlg_regs->refcyc_per_vm_group_vblank >= (unsigned int)dml_pow(2, 23))
|
||||
|
||||
@@ -210,6 +210,22 @@ struct mpc_funcs {
|
||||
struct mpcc_blnd_cfg *blnd_cfg,
|
||||
int mpcc_id);
|
||||
|
||||
/*
|
||||
* Lock cursor updates for the specified OPP.
|
||||
* OPP defines the set of MPCC that are locked together for cursor.
|
||||
*
|
||||
* Parameters:
|
||||
* [in] mpc - MPC context.
|
||||
* [in] opp_id - The OPP to lock cursor updates on
|
||||
* [in] lock - lock/unlock the OPP
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
void (*cursor_lock)(
|
||||
struct mpc *mpc,
|
||||
int opp_id,
|
||||
bool lock);
|
||||
|
||||
struct mpcc* (*get_mpcc_for_dpp)(
|
||||
struct mpc_tree *tree,
|
||||
int dpp_id);
|
||||
|
||||
@@ -86,6 +86,7 @@ struct hw_sequencer_funcs {
|
||||
struct dc_state *context, bool lock);
|
||||
void (*set_flip_control_gsl)(struct pipe_ctx *pipe_ctx,
|
||||
bool flip_immediate);
|
||||
void (*cursor_lock)(struct dc *dc, struct pipe_ctx *pipe, bool lock);
|
||||
|
||||
/* Timing Related */
|
||||
void (*get_position)(struct pipe_ctx **pipe_ctx, int num_pipes,
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
#define ASSERT(expr) ASSERT_CRITICAL(expr)
|
||||
|
||||
#else
|
||||
#define ASSERT(expr) WARN_ON(!(expr))
|
||||
#define ASSERT(expr) WARN_ON_ONCE(!(expr))
|
||||
#endif
|
||||
|
||||
#define BREAK_TO_DEBUGGER() ASSERT(0)
|
||||
|
||||
@@ -1435,7 +1435,8 @@ static int pp_get_asic_baco_capability(void *handle, bool *cap)
|
||||
if (!hwmgr)
|
||||
return -EINVAL;
|
||||
|
||||
if (!hwmgr->pm_en || !hwmgr->hwmgr_func->get_asic_baco_capability)
|
||||
if (!(hwmgr->not_vf && amdgpu_dpm) ||
|
||||
!hwmgr->hwmgr_func->get_asic_baco_capability)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&hwmgr->smu_lock);
|
||||
@@ -1452,8 +1453,7 @@ static int pp_get_asic_baco_state(void *handle, int *state)
|
||||
if (!hwmgr)
|
||||
return -EINVAL;
|
||||
|
||||
if (!(hwmgr->not_vf && amdgpu_dpm) ||
|
||||
!hwmgr->hwmgr_func->get_asic_baco_state)
|
||||
if (!hwmgr->pm_en || !hwmgr->hwmgr_func->get_asic_baco_state)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&hwmgr->smu_lock);
|
||||
@@ -1470,7 +1470,8 @@ static int pp_set_asic_baco_state(void *handle, int state)
|
||||
if (!hwmgr)
|
||||
return -EINVAL;
|
||||
|
||||
if (!hwmgr->pm_en || !hwmgr->hwmgr_func->set_asic_baco_state)
|
||||
if (!(hwmgr->not_vf && amdgpu_dpm) ||
|
||||
!hwmgr->hwmgr_func->set_asic_baco_state)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&hwmgr->smu_lock);
|
||||
|
||||
@@ -984,6 +984,32 @@ static int init_thermal_controller(
|
||||
struct pp_hwmgr *hwmgr,
|
||||
const ATOM_PPLIB_POWERPLAYTABLE *powerplay_table)
|
||||
{
|
||||
hwmgr->thermal_controller.ucType =
|
||||
powerplay_table->sThermalController.ucType;
|
||||
hwmgr->thermal_controller.ucI2cLine =
|
||||
powerplay_table->sThermalController.ucI2cLine;
|
||||
hwmgr->thermal_controller.ucI2cAddress =
|
||||
powerplay_table->sThermalController.ucI2cAddress;
|
||||
|
||||
hwmgr->thermal_controller.fanInfo.bNoFan =
|
||||
(0 != (powerplay_table->sThermalController.ucFanParameters &
|
||||
ATOM_PP_FANPARAMETERS_NOFAN));
|
||||
|
||||
hwmgr->thermal_controller.fanInfo.ucTachometerPulsesPerRevolution =
|
||||
powerplay_table->sThermalController.ucFanParameters &
|
||||
ATOM_PP_FANPARAMETERS_TACHOMETER_PULSES_PER_REVOLUTION_MASK;
|
||||
|
||||
hwmgr->thermal_controller.fanInfo.ulMinRPM
|
||||
= powerplay_table->sThermalController.ucFanMinRPM * 100UL;
|
||||
hwmgr->thermal_controller.fanInfo.ulMaxRPM
|
||||
= powerplay_table->sThermalController.ucFanMaxRPM * 100UL;
|
||||
|
||||
set_hw_cap(hwmgr,
|
||||
ATOM_PP_THERMALCONTROLLER_NONE != hwmgr->thermal_controller.ucType,
|
||||
PHM_PlatformCaps_ThermalController);
|
||||
|
||||
hwmgr->thermal_controller.use_hw_fan_control = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -895,12 +895,17 @@ static int renoir_read_sensor(struct smu_context *smu,
|
||||
|
||||
static bool renoir_is_dpm_running(struct smu_context *smu)
|
||||
{
|
||||
struct amdgpu_device *adev = smu->adev;
|
||||
|
||||
/*
|
||||
* Util now, the pmfw hasn't exported the interface of SMU
|
||||
* feature mask to APU SKU so just force on all the feature
|
||||
* at early initial stage.
|
||||
*/
|
||||
return true;
|
||||
if (adev->in_suspend)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -485,6 +485,9 @@ static int anx6345_get_modes(struct drm_connector *connector)
|
||||
|
||||
num_modes += drm_add_edid_modes(connector, anx6345->edid);
|
||||
|
||||
/* Driver currently supports only 6bpc */
|
||||
connector->display_info.bpc = 6;
|
||||
|
||||
unlock:
|
||||
if (power_off)
|
||||
anx6345_poweroff(anx6345);
|
||||
|
||||
@@ -3442,8 +3442,12 @@ static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr,
|
||||
drm_dp_queue_down_tx(mgr, txmsg);
|
||||
|
||||
ret = drm_dp_mst_wait_tx_reply(mstb, txmsg);
|
||||
if (ret > 0 && txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK)
|
||||
ret = -EIO;
|
||||
if (ret > 0) {
|
||||
if (txmsg->reply.reply_type == DP_SIDEBAND_REPLY_NAK)
|
||||
ret = -EIO;
|
||||
else
|
||||
ret = size;
|
||||
}
|
||||
|
||||
kfree(txmsg);
|
||||
fail_put:
|
||||
@@ -4295,6 +4299,7 @@ int drm_dp_atomic_release_vcpi_slots(struct drm_atomic_state *state,
|
||||
if (pos->vcpi) {
|
||||
drm_dp_mst_put_port_malloc(port);
|
||||
pos->vcpi = 0;
|
||||
pos->pbn = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -5111,7 +5111,7 @@ static struct drm_display_mode *drm_mode_displayid_detailed(struct drm_device *d
|
||||
struct drm_display_mode *mode;
|
||||
unsigned pixel_clock = (timings->pixel_clock[0] |
|
||||
(timings->pixel_clock[1] << 8) |
|
||||
(timings->pixel_clock[2] << 16));
|
||||
(timings->pixel_clock[2] << 16)) + 1;
|
||||
unsigned hactive = (timings->hactive[0] | timings->hactive[1] << 8) + 1;
|
||||
unsigned hblank = (timings->hblank[0] | timings->hblank[1] << 8) + 1;
|
||||
unsigned hsync = (timings->hsync[0] | (timings->hsync[1] & 0x7f) << 8) + 1;
|
||||
|
||||
@@ -241,8 +241,12 @@ static int drm_hdcp_request_srm(struct drm_device *drm_dev,
|
||||
|
||||
ret = request_firmware_direct(&fw, (const char *)fw_name,
|
||||
drm_dev->dev);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
*revoked_ksv_cnt = 0;
|
||||
*revoked_ksv_list = NULL;
|
||||
ret = 0;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (fw->size && fw->data)
|
||||
ret = drm_hdcp_srm_update(fw->data, fw->size, revoked_ksv_list,
|
||||
@@ -287,6 +291,8 @@ int drm_hdcp_check_ksvs_revoked(struct drm_device *drm_dev, u8 *ksvs,
|
||||
|
||||
ret = drm_hdcp_request_srm(drm_dev, &revoked_ksv_list,
|
||||
&revoked_ksv_cnt);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* revoked_ksv_cnt will be zero when above function failed */
|
||||
for (i = 0; i < revoked_ksv_cnt; i++)
|
||||
|
||||
@@ -3141,9 +3141,6 @@ static void hsw_ddi_pre_enable_dp(struct intel_encoder *encoder,
|
||||
intel_dp_set_link_params(intel_dp, crtc_state->port_clock,
|
||||
crtc_state->lane_count, is_mst);
|
||||
|
||||
intel_dp->regs.dp_tp_ctl = DP_TP_CTL(port);
|
||||
intel_dp->regs.dp_tp_status = DP_TP_STATUS(port);
|
||||
|
||||
intel_edp_panel_on(intel_dp);
|
||||
|
||||
intel_ddi_clk_select(encoder, crtc_state);
|
||||
@@ -3848,12 +3845,18 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(pipe_config->uapi.crtc);
|
||||
enum transcoder cpu_transcoder = pipe_config->cpu_transcoder;
|
||||
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
|
||||
u32 temp, flags = 0;
|
||||
|
||||
/* XXX: DSI transcoder paranoia */
|
||||
if (drm_WARN_ON(&dev_priv->drm, transcoder_is_dsi(cpu_transcoder)))
|
||||
return;
|
||||
|
||||
if (INTEL_GEN(dev_priv) >= 12) {
|
||||
intel_dp->regs.dp_tp_ctl = TGL_DP_TP_CTL(cpu_transcoder);
|
||||
intel_dp->regs.dp_tp_status = TGL_DP_TP_STATUS(cpu_transcoder);
|
||||
}
|
||||
|
||||
intel_dsc_get_config(encoder, pipe_config);
|
||||
|
||||
temp = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder));
|
||||
@@ -4173,6 +4176,7 @@ static const struct drm_encoder_funcs intel_ddi_funcs = {
|
||||
static struct intel_connector *
|
||||
intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev);
|
||||
struct intel_connector *connector;
|
||||
enum port port = intel_dig_port->base.port;
|
||||
|
||||
@@ -4183,6 +4187,10 @@ intel_ddi_init_dp_connector(struct intel_digital_port *intel_dig_port)
|
||||
intel_dig_port->dp.output_reg = DDI_BUF_CTL(port);
|
||||
intel_dig_port->dp.prepare_link_retrain =
|
||||
intel_ddi_prepare_link_retrain;
|
||||
if (INTEL_GEN(dev_priv) < 12) {
|
||||
intel_dig_port->dp.regs.dp_tp_ctl = DP_TP_CTL(port);
|
||||
intel_dig_port->dp.regs.dp_tp_status = DP_TP_STATUS(port);
|
||||
}
|
||||
|
||||
if (!intel_dp_init_connector(intel_dig_port, connector)) {
|
||||
kfree(connector);
|
||||
|
||||
@@ -4140,7 +4140,7 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
|
||||
{
|
||||
.name = "AUX D TBT1",
|
||||
.domains = TGL_AUX_D_TBT1_IO_POWER_DOMAINS,
|
||||
.ops = &hsw_power_well_ops,
|
||||
.ops = &icl_tc_phy_aux_power_well_ops,
|
||||
.id = DISP_PW_ID_NONE,
|
||||
{
|
||||
.hsw.regs = &icl_aux_power_well_regs,
|
||||
@@ -4151,7 +4151,7 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
|
||||
{
|
||||
.name = "AUX E TBT2",
|
||||
.domains = TGL_AUX_E_TBT2_IO_POWER_DOMAINS,
|
||||
.ops = &hsw_power_well_ops,
|
||||
.ops = &icl_tc_phy_aux_power_well_ops,
|
||||
.id = DISP_PW_ID_NONE,
|
||||
{
|
||||
.hsw.regs = &icl_aux_power_well_regs,
|
||||
@@ -4162,7 +4162,7 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
|
||||
{
|
||||
.name = "AUX F TBT3",
|
||||
.domains = TGL_AUX_F_TBT3_IO_POWER_DOMAINS,
|
||||
.ops = &hsw_power_well_ops,
|
||||
.ops = &icl_tc_phy_aux_power_well_ops,
|
||||
.id = DISP_PW_ID_NONE,
|
||||
{
|
||||
.hsw.regs = &icl_aux_power_well_regs,
|
||||
@@ -4173,7 +4173,7 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
|
||||
{
|
||||
.name = "AUX G TBT4",
|
||||
.domains = TGL_AUX_G_TBT4_IO_POWER_DOMAINS,
|
||||
.ops = &hsw_power_well_ops,
|
||||
.ops = &icl_tc_phy_aux_power_well_ops,
|
||||
.id = DISP_PW_ID_NONE,
|
||||
{
|
||||
.hsw.regs = &icl_aux_power_well_regs,
|
||||
@@ -4184,7 +4184,7 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
|
||||
{
|
||||
.name = "AUX H TBT5",
|
||||
.domains = TGL_AUX_H_TBT5_IO_POWER_DOMAINS,
|
||||
.ops = &hsw_power_well_ops,
|
||||
.ops = &icl_tc_phy_aux_power_well_ops,
|
||||
.id = DISP_PW_ID_NONE,
|
||||
{
|
||||
.hsw.regs = &icl_aux_power_well_regs,
|
||||
@@ -4195,7 +4195,7 @@ static const struct i915_power_well_desc tgl_power_wells[] = {
|
||||
{
|
||||
.name = "AUX I TBT6",
|
||||
.domains = TGL_AUX_I_TBT6_IO_POWER_DOMAINS,
|
||||
.ops = &hsw_power_well_ops,
|
||||
.ops = &icl_tc_phy_aux_power_well_ops,
|
||||
.id = DISP_PW_ID_NONE,
|
||||
{
|
||||
.hsw.regs = &icl_aux_power_well_regs,
|
||||
|
||||
@@ -2517,9 +2517,6 @@ static void intel_dp_prepare(struct intel_encoder *encoder,
|
||||
intel_crtc_has_type(pipe_config,
|
||||
INTEL_OUTPUT_DP_MST));
|
||||
|
||||
intel_dp->regs.dp_tp_ctl = DP_TP_CTL(port);
|
||||
intel_dp->regs.dp_tp_status = DP_TP_STATUS(port);
|
||||
|
||||
/*
|
||||
* There are four kinds of DP registers:
|
||||
*
|
||||
@@ -7836,6 +7833,8 @@ bool intel_dp_init(struct drm_i915_private *dev_priv,
|
||||
|
||||
intel_dig_port->dp.output_reg = output_reg;
|
||||
intel_dig_port->max_lanes = 4;
|
||||
intel_dig_port->dp.regs.dp_tp_ctl = DP_TP_CTL(port);
|
||||
intel_dig_port->dp.regs.dp_tp_status = DP_TP_STATUS(port);
|
||||
|
||||
intel_encoder->type = INTEL_OUTPUT_DP;
|
||||
intel_encoder->power_domain = intel_port_to_power_domain(port);
|
||||
|
||||
@@ -342,6 +342,7 @@ int intel_dp_aux_init_backlight_funcs(struct intel_connector *intel_connector)
|
||||
*/
|
||||
if (dev_priv->vbt.backlight.type !=
|
||||
INTEL_BACKLIGHT_VESA_EDP_AUX_INTERFACE &&
|
||||
i915_modparams.enable_dpcd_backlight != 1 &&
|
||||
!drm_dp_has_quirk(&intel_dp->desc, intel_dp->edid_quirks,
|
||||
DP_QUIRK_FORCE_DPCD_BACKLIGHT)) {
|
||||
DRM_DEV_INFO(dev->dev,
|
||||
|
||||
@@ -1536,7 +1536,8 @@ bool intel_hdmi_hdcp_check_link(struct intel_digital_port *intel_dig_port)
|
||||
intel_de_write(i915, HDCP_RPRIME(i915, cpu_transcoder, port), ri.reg);
|
||||
|
||||
/* Wait for Ri prime match */
|
||||
if (wait_for(intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)) &
|
||||
if (wait_for((intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)) &
|
||||
(HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC)) ==
|
||||
(HDCP_STATUS_RI_MATCH | HDCP_STATUS_ENC), 1)) {
|
||||
DRM_ERROR("Ri' mismatch detected, link check failed (%x)\n",
|
||||
intel_de_read(i915, HDCP_STATUS(i915, cpu_transcoder, port)));
|
||||
|
||||
@@ -2817,19 +2817,25 @@ static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
|
||||
}
|
||||
}
|
||||
|
||||
static bool gen12_plane_supports_mc_ccs(enum plane_id plane_id)
|
||||
static bool gen12_plane_supports_mc_ccs(struct drm_i915_private *dev_priv,
|
||||
enum plane_id plane_id)
|
||||
{
|
||||
/* Wa_14010477008:tgl[a0..c0] */
|
||||
if (IS_TGL_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_C0))
|
||||
return false;
|
||||
|
||||
return plane_id < PLANE_SPRITE4;
|
||||
}
|
||||
|
||||
static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
|
||||
u32 format, u64 modifier)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(_plane->dev);
|
||||
struct intel_plane *plane = to_intel_plane(_plane);
|
||||
|
||||
switch (modifier) {
|
||||
case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
|
||||
if (!gen12_plane_supports_mc_ccs(plane->id))
|
||||
if (!gen12_plane_supports_mc_ccs(dev_priv, plane->id))
|
||||
return false;
|
||||
/* fall through */
|
||||
case DRM_FORMAT_MOD_LINEAR:
|
||||
@@ -2998,9 +3004,10 @@ static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv,
|
||||
}
|
||||
}
|
||||
|
||||
static const u64 *gen12_get_plane_modifiers(enum plane_id plane_id)
|
||||
static const u64 *gen12_get_plane_modifiers(struct drm_i915_private *dev_priv,
|
||||
enum plane_id plane_id)
|
||||
{
|
||||
if (gen12_plane_supports_mc_ccs(plane_id))
|
||||
if (gen12_plane_supports_mc_ccs(dev_priv, plane_id))
|
||||
return gen12_plane_format_modifiers_mc_ccs;
|
||||
else
|
||||
return gen12_plane_format_modifiers_rc_ccs;
|
||||
@@ -3070,7 +3077,7 @@ skl_universal_plane_create(struct drm_i915_private *dev_priv,
|
||||
|
||||
plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id);
|
||||
if (INTEL_GEN(dev_priv) >= 12) {
|
||||
modifiers = gen12_get_plane_modifiers(plane_id);
|
||||
modifiers = gen12_get_plane_modifiers(dev_priv, plane_id);
|
||||
plane_funcs = &gen12_plane_funcs;
|
||||
} else {
|
||||
if (plane->has_ccs)
|
||||
|
||||
@@ -182,21 +182,35 @@ i915_gem_object_fence_prepare(struct drm_i915_gem_object *obj,
|
||||
int tiling_mode, unsigned int stride)
|
||||
{
|
||||
struct i915_ggtt *ggtt = &to_i915(obj->base.dev)->ggtt;
|
||||
struct i915_vma *vma;
|
||||
struct i915_vma *vma, *vn;
|
||||
LIST_HEAD(unbind);
|
||||
int ret = 0;
|
||||
|
||||
if (tiling_mode == I915_TILING_NONE)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&ggtt->vm.mutex);
|
||||
|
||||
spin_lock(&obj->vma.lock);
|
||||
for_each_ggtt_vma(vma, obj) {
|
||||
GEM_BUG_ON(vma->vm != &ggtt->vm);
|
||||
|
||||
if (i915_vma_fence_prepare(vma, tiling_mode, stride))
|
||||
continue;
|
||||
|
||||
ret = __i915_vma_unbind(vma);
|
||||
if (ret)
|
||||
break;
|
||||
list_move(&vma->vm_link, &unbind);
|
||||
}
|
||||
spin_unlock(&obj->vma.lock);
|
||||
|
||||
list_for_each_entry_safe(vma, vn, &unbind, vm_link) {
|
||||
ret = __i915_vma_unbind(vma);
|
||||
if (ret) {
|
||||
/* Restore the remaining vma on an error */
|
||||
list_splice(&unbind, &ggtt->vm.bound_list);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&ggtt->vm.mutex);
|
||||
|
||||
return ret;
|
||||
@@ -268,6 +282,7 @@ i915_gem_object_set_tiling(struct drm_i915_gem_object *obj,
|
||||
}
|
||||
mutex_unlock(&obj->mm.lock);
|
||||
|
||||
spin_lock(&obj->vma.lock);
|
||||
for_each_ggtt_vma(vma, obj) {
|
||||
vma->fence_size =
|
||||
i915_gem_fence_size(i915, vma->size, tiling, stride);
|
||||
@@ -278,6 +293,7 @@ i915_gem_object_set_tiling(struct drm_i915_gem_object *obj,
|
||||
if (vma->fence)
|
||||
vma->fence->dirty = true;
|
||||
}
|
||||
spin_unlock(&obj->vma.lock);
|
||||
|
||||
obj->tiling_and_stride = tiling | stride;
|
||||
i915_gem_object_unlock(obj);
|
||||
|
||||
@@ -1477,8 +1477,10 @@ static int igt_ppgtt_pin_update(void *arg)
|
||||
unsigned int page_size = BIT(first);
|
||||
|
||||
obj = i915_gem_object_create_internal(dev_priv, page_size);
|
||||
if (IS_ERR(obj))
|
||||
return PTR_ERR(obj);
|
||||
if (IS_ERR(obj)) {
|
||||
err = PTR_ERR(obj);
|
||||
goto out_vm;
|
||||
}
|
||||
|
||||
vma = i915_vma_instance(obj, vm, NULL);
|
||||
if (IS_ERR(vma)) {
|
||||
@@ -1531,8 +1533,10 @@ static int igt_ppgtt_pin_update(void *arg)
|
||||
}
|
||||
|
||||
obj = i915_gem_object_create_internal(dev_priv, PAGE_SIZE);
|
||||
if (IS_ERR(obj))
|
||||
return PTR_ERR(obj);
|
||||
if (IS_ERR(obj)) {
|
||||
err = PTR_ERR(obj);
|
||||
goto out_vm;
|
||||
}
|
||||
|
||||
vma = i915_vma_instance(obj, vm, NULL);
|
||||
if (IS_ERR(vma)) {
|
||||
|
||||
@@ -81,13 +81,14 @@ static void rps_enable_interrupts(struct intel_rps *rps)
|
||||
events = (GEN6_PM_RP_UP_THRESHOLD |
|
||||
GEN6_PM_RP_DOWN_THRESHOLD |
|
||||
GEN6_PM_RP_DOWN_TIMEOUT);
|
||||
|
||||
WRITE_ONCE(rps->pm_events, events);
|
||||
|
||||
spin_lock_irq(>->irq_lock);
|
||||
gen6_gt_pm_enable_irq(gt, rps->pm_events);
|
||||
spin_unlock_irq(>->irq_lock);
|
||||
|
||||
set(gt->uncore, GEN6_PMINTRMSK, rps_pm_mask(rps, rps->cur_freq));
|
||||
intel_uncore_write(gt->uncore,
|
||||
GEN6_PMINTRMSK, rps_pm_mask(rps, rps->last_freq));
|
||||
}
|
||||
|
||||
static void gen6_rps_reset_interrupts(struct intel_rps *rps)
|
||||
@@ -120,7 +121,9 @@ static void rps_disable_interrupts(struct intel_rps *rps)
|
||||
struct intel_gt *gt = rps_to_gt(rps);
|
||||
|
||||
WRITE_ONCE(rps->pm_events, 0);
|
||||
set(gt->uncore, GEN6_PMINTRMSK, rps_pm_sanitize_mask(rps, ~0u));
|
||||
|
||||
intel_uncore_write(gt->uncore,
|
||||
GEN6_PMINTRMSK, rps_pm_sanitize_mask(rps, ~0u));
|
||||
|
||||
spin_lock_irq(>->irq_lock);
|
||||
gen6_gt_pm_disable_irq(gt, GEN6_PM_RPS_EVENTS);
|
||||
|
||||
@@ -521,6 +521,8 @@ int intel_timeline_read_hwsp(struct i915_request *from,
|
||||
|
||||
rcu_read_lock();
|
||||
cl = rcu_dereference(from->hwsp_cacheline);
|
||||
if (i915_request_completed(from)) /* confirm cacheline is valid */
|
||||
goto unlock;
|
||||
if (unlikely(!i915_active_acquire_if_busy(&cl->active)))
|
||||
goto unlock; /* seqno wrapped and completed! */
|
||||
if (unlikely(i915_request_completed(from)))
|
||||
|
||||
@@ -1507,6 +1507,8 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
|
||||
(IS_ICELAKE(p) && IS_REVID(p, since, until))
|
||||
|
||||
#define TGL_REVID_A0 0x0
|
||||
#define TGL_REVID_B0 0x1
|
||||
#define TGL_REVID_C0 0x2
|
||||
|
||||
#define IS_TGL_REVID(p, since, until) \
|
||||
(IS_TIGERLAKE(p) && IS_REVID(p, since, until))
|
||||
|
||||
@@ -3358,7 +3358,8 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
|
||||
{
|
||||
struct intel_uncore *uncore = &dev_priv->uncore;
|
||||
|
||||
u32 de_pipe_masked = GEN8_PIPE_CDCLK_CRC_DONE;
|
||||
u32 de_pipe_masked = gen8_de_pipe_fault_mask(dev_priv) |
|
||||
GEN8_PIPE_CDCLK_CRC_DONE;
|
||||
u32 de_pipe_enables;
|
||||
u32 de_port_masked = GEN8_AUX_CHANNEL_A;
|
||||
u32 de_port_enables;
|
||||
@@ -3369,13 +3370,10 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
|
||||
de_misc_masked |= GEN8_DE_MISC_GSE;
|
||||
|
||||
if (INTEL_GEN(dev_priv) >= 9) {
|
||||
de_pipe_masked |= GEN9_DE_PIPE_IRQ_FAULT_ERRORS;
|
||||
de_port_masked |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C |
|
||||
GEN9_AUX_CHANNEL_D;
|
||||
if (IS_GEN9_LP(dev_priv))
|
||||
de_port_masked |= BXT_DE_PORT_GMBUS;
|
||||
} else {
|
||||
de_pipe_masked |= GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
|
||||
}
|
||||
|
||||
if (INTEL_GEN(dev_priv) >= 11)
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
* Follow the style described here for new macros, and while changing existing
|
||||
* macros. Do **not** mass change existing definitions just to update the style.
|
||||
*
|
||||
* Layout
|
||||
* ~~~~~~
|
||||
* File Layout
|
||||
* ~~~~~~~~~~~
|
||||
*
|
||||
* Keep helper macros near the top. For example, _PIPE() and friends.
|
||||
*
|
||||
|
||||
@@ -158,16 +158,18 @@ vma_create(struct drm_i915_gem_object *obj,
|
||||
|
||||
GEM_BUG_ON(!IS_ALIGNED(vma->size, I915_GTT_PAGE_SIZE));
|
||||
|
||||
spin_lock(&obj->vma.lock);
|
||||
|
||||
if (i915_is_ggtt(vm)) {
|
||||
if (unlikely(overflows_type(vma->size, u32)))
|
||||
goto err_vma;
|
||||
goto err_unlock;
|
||||
|
||||
vma->fence_size = i915_gem_fence_size(vm->i915, vma->size,
|
||||
i915_gem_object_get_tiling(obj),
|
||||
i915_gem_object_get_stride(obj));
|
||||
if (unlikely(vma->fence_size < vma->size || /* overflow */
|
||||
vma->fence_size > vm->total))
|
||||
goto err_vma;
|
||||
goto err_unlock;
|
||||
|
||||
GEM_BUG_ON(!IS_ALIGNED(vma->fence_size, I915_GTT_MIN_ALIGNMENT));
|
||||
|
||||
@@ -179,8 +181,6 @@ vma_create(struct drm_i915_gem_object *obj,
|
||||
__set_bit(I915_VMA_GGTT_BIT, __i915_vma_flags(vma));
|
||||
}
|
||||
|
||||
spin_lock(&obj->vma.lock);
|
||||
|
||||
rb = NULL;
|
||||
p = &obj->vma.tree.rb_node;
|
||||
while (*p) {
|
||||
@@ -225,6 +225,8 @@ vma_create(struct drm_i915_gem_object *obj,
|
||||
|
||||
return vma;
|
||||
|
||||
err_unlock:
|
||||
spin_unlock(&obj->vma.lock);
|
||||
err_vma:
|
||||
i915_vma_free(vma);
|
||||
return ERR_PTR(-E2BIG);
|
||||
|
||||
@@ -843,6 +843,7 @@ static const struct of_device_id ingenic_drm_of_match[] = {
|
||||
{ .compatible = "ingenic,jz4770-lcd", .data = &jz4770_soc_info },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ingenic_drm_of_match);
|
||||
|
||||
static struct platform_driver ingenic_drm_driver = {
|
||||
.driver = {
|
||||
|
||||
@@ -1034,10 +1034,8 @@ static int meson_dw_hdmi_bind(struct device *dev, struct device *master,
|
||||
return PTR_ERR(dw_plat_data->regm);
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(dev, "Failed to get hdmi top irq\n");
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
}
|
||||
|
||||
ret = devm_request_threaded_irq(dev, irq, dw_hdmi_top_irq,
|
||||
dw_hdmi_top_thread_irq, IRQF_SHARED,
|
||||
|
||||
@@ -480,9 +480,10 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev,
|
||||
return ret;
|
||||
|
||||
ret = qxl_release_reserve_list(release, true);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
qxl_release_free(qdev, release);
|
||||
return ret;
|
||||
|
||||
}
|
||||
cmd = (struct qxl_surface_cmd *)qxl_release_map(qdev, release);
|
||||
cmd->type = QXL_SURFACE_CMD_CREATE;
|
||||
cmd->flags = QXL_SURF_FLAG_KEEP_DATA;
|
||||
@@ -499,8 +500,8 @@ int qxl_hw_surface_alloc(struct qxl_device *qdev,
|
||||
/* no need to add a release to the fence for this surface bo,
|
||||
since it is only released when we ask to destroy the surface
|
||||
and it would never signal otherwise */
|
||||
qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
|
||||
qxl_release_fence_buffer_objects(release);
|
||||
qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
|
||||
|
||||
surf->hw_surf_alloc = true;
|
||||
spin_lock(&qdev->surf_id_idr_lock);
|
||||
@@ -542,9 +543,8 @@ int qxl_hw_surface_dealloc(struct qxl_device *qdev,
|
||||
cmd->surface_id = id;
|
||||
qxl_release_unmap(qdev, release, &cmd->release_info);
|
||||
|
||||
qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
|
||||
|
||||
qxl_release_fence_buffer_objects(release);
|
||||
qxl_push_command_ring_release(qdev, release, QXL_CMD_SURFACE, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -510,8 +510,8 @@ static int qxl_primary_apply_cursor(struct drm_plane *plane)
|
||||
cmd->u.set.visible = 1;
|
||||
qxl_release_unmap(qdev, release, &cmd->release_info);
|
||||
|
||||
qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
|
||||
qxl_release_fence_buffer_objects(release);
|
||||
qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -652,8 +652,8 @@ static void qxl_cursor_atomic_update(struct drm_plane *plane,
|
||||
cmd->u.position.y = plane->state->crtc_y + fb->hot_y;
|
||||
|
||||
qxl_release_unmap(qdev, release, &cmd->release_info);
|
||||
qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
|
||||
qxl_release_fence_buffer_objects(release);
|
||||
qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
|
||||
|
||||
if (old_cursor_bo != NULL)
|
||||
qxl_bo_unpin(old_cursor_bo);
|
||||
@@ -700,8 +700,8 @@ static void qxl_cursor_atomic_disable(struct drm_plane *plane,
|
||||
cmd->type = QXL_CURSOR_HIDE;
|
||||
qxl_release_unmap(qdev, release, &cmd->release_info);
|
||||
|
||||
qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
|
||||
qxl_release_fence_buffer_objects(release);
|
||||
qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
|
||||
}
|
||||
|
||||
static void qxl_update_dumb_head(struct qxl_device *qdev,
|
||||
|
||||
@@ -209,9 +209,10 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev,
|
||||
goto out_release_backoff;
|
||||
|
||||
rects = drawable_set_clipping(qdev, num_clips, clips_bo);
|
||||
if (!rects)
|
||||
if (!rects) {
|
||||
ret = -EINVAL;
|
||||
goto out_release_backoff;
|
||||
|
||||
}
|
||||
drawable = (struct qxl_drawable *)qxl_release_map(qdev, release);
|
||||
|
||||
drawable->clip.type = SPICE_CLIP_TYPE_RECTS;
|
||||
@@ -242,8 +243,8 @@ void qxl_draw_dirty_fb(struct qxl_device *qdev,
|
||||
}
|
||||
qxl_bo_kunmap(clips_bo);
|
||||
|
||||
qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
|
||||
qxl_release_fence_buffer_objects(release);
|
||||
qxl_push_command_ring_release(qdev, release, QXL_CMD_DRAW, false);
|
||||
|
||||
out_release_backoff:
|
||||
if (ret)
|
||||
|
||||
@@ -212,7 +212,8 @@ qxl_image_init_helper(struct qxl_device *qdev,
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("unsupported image bit depth\n");
|
||||
return -EINVAL; /* TODO: cleanup */
|
||||
qxl_bo_kunmap_atomic_page(qdev, image_bo, ptr);
|
||||
return -EINVAL;
|
||||
}
|
||||
image->u.bitmap.flags = QXL_BITMAP_TOP_DOWN;
|
||||
image->u.bitmap.x = width;
|
||||
|
||||
@@ -261,11 +261,8 @@ static int qxl_process_single_command(struct qxl_device *qdev,
|
||||
apply_surf_reloc(qdev, &reloc_info[i]);
|
||||
}
|
||||
|
||||
qxl_release_fence_buffer_objects(release);
|
||||
ret = qxl_push_command_ring_release(qdev, release, cmd->type, true);
|
||||
if (ret)
|
||||
qxl_release_backoff_reserve_list(release);
|
||||
else
|
||||
qxl_release_fence_buffer_objects(release);
|
||||
|
||||
out_free_bos:
|
||||
out_free_release:
|
||||
|
||||
@@ -676,7 +676,7 @@ drm_sched_get_cleanup_job(struct drm_gpu_scheduler *sched)
|
||||
*/
|
||||
if ((sched->timeout != MAX_SCHEDULE_TIMEOUT &&
|
||||
!cancel_delayed_work(&sched->work_tdr)) ||
|
||||
__kthread_should_park(sched->thread))
|
||||
kthread_should_park())
|
||||
return NULL;
|
||||
|
||||
spin_lock(&sched->job_list_lock);
|
||||
|
||||
@@ -717,7 +717,7 @@ static void sun6i_dsi_encoder_enable(struct drm_encoder *encoder)
|
||||
struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
|
||||
struct sun6i_dsi *dsi = encoder_to_sun6i_dsi(encoder);
|
||||
struct mipi_dsi_device *device = dsi->device;
|
||||
union phy_configure_opts opts = { 0 };
|
||||
union phy_configure_opts opts = { };
|
||||
struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
|
||||
u16 delay;
|
||||
int err;
|
||||
|
||||
@@ -379,9 +379,17 @@ static struct drm_crtc_state *tidss_crtc_duplicate_state(struct drm_crtc *crtc)
|
||||
return &state->base;
|
||||
}
|
||||
|
||||
static void tidss_crtc_destroy(struct drm_crtc *crtc)
|
||||
{
|
||||
struct tidss_crtc *tcrtc = to_tidss_crtc(crtc);
|
||||
|
||||
drm_crtc_cleanup(crtc);
|
||||
kfree(tcrtc);
|
||||
}
|
||||
|
||||
static const struct drm_crtc_funcs tidss_crtc_funcs = {
|
||||
.reset = tidss_crtc_reset,
|
||||
.destroy = drm_crtc_cleanup,
|
||||
.destroy = tidss_crtc_destroy,
|
||||
.set_config = drm_atomic_helper_set_config,
|
||||
.page_flip = drm_atomic_helper_page_flip,
|
||||
.atomic_duplicate_state = tidss_crtc_duplicate_state,
|
||||
@@ -400,7 +408,7 @@ struct tidss_crtc *tidss_crtc_create(struct tidss_device *tidss,
|
||||
bool has_ctm = tidss->feat->vp_feat.color.has_ctm;
|
||||
int ret;
|
||||
|
||||
tcrtc = devm_kzalloc(tidss->dev, sizeof(*tcrtc), GFP_KERNEL);
|
||||
tcrtc = kzalloc(sizeof(*tcrtc), GFP_KERNEL);
|
||||
if (!tcrtc)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@@ -411,8 +419,10 @@ struct tidss_crtc *tidss_crtc_create(struct tidss_device *tidss,
|
||||
|
||||
ret = drm_crtc_init_with_planes(&tidss->ddev, crtc, primary,
|
||||
NULL, &tidss_crtc_funcs, NULL);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
kfree(tcrtc);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
drm_crtc_helper_add(crtc, &tidss_crtc_helper_funcs);
|
||||
|
||||
|
||||
@@ -55,12 +55,18 @@ static int tidss_encoder_atomic_check(struct drm_encoder *encoder,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tidss_encoder_destroy(struct drm_encoder *encoder)
|
||||
{
|
||||
drm_encoder_cleanup(encoder);
|
||||
kfree(encoder);
|
||||
}
|
||||
|
||||
static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
|
||||
.atomic_check = tidss_encoder_atomic_check,
|
||||
};
|
||||
|
||||
static const struct drm_encoder_funcs encoder_funcs = {
|
||||
.destroy = drm_encoder_cleanup,
|
||||
.destroy = tidss_encoder_destroy,
|
||||
};
|
||||
|
||||
struct drm_encoder *tidss_encoder_create(struct tidss_device *tidss,
|
||||
@@ -69,7 +75,7 @@ struct drm_encoder *tidss_encoder_create(struct tidss_device *tidss,
|
||||
struct drm_encoder *enc;
|
||||
int ret;
|
||||
|
||||
enc = devm_kzalloc(tidss->dev, sizeof(*enc), GFP_KERNEL);
|
||||
enc = kzalloc(sizeof(*enc), GFP_KERNEL);
|
||||
if (!enc)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@@ -77,8 +83,10 @@ struct drm_encoder *tidss_encoder_create(struct tidss_device *tidss,
|
||||
|
||||
ret = drm_encoder_init(&tidss->ddev, enc, &encoder_funcs,
|
||||
encoder_type, NULL);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
kfree(enc);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
drm_encoder_helper_add(enc, &encoder_helper_funcs);
|
||||
|
||||
|
||||
@@ -141,6 +141,14 @@ static void tidss_plane_atomic_disable(struct drm_plane *plane,
|
||||
dispc_plane_enable(tidss->dispc, tplane->hw_plane_id, false);
|
||||
}
|
||||
|
||||
static void drm_plane_destroy(struct drm_plane *plane)
|
||||
{
|
||||
struct tidss_plane *tplane = to_tidss_plane(plane);
|
||||
|
||||
drm_plane_cleanup(plane);
|
||||
kfree(tplane);
|
||||
}
|
||||
|
||||
static const struct drm_plane_helper_funcs tidss_plane_helper_funcs = {
|
||||
.atomic_check = tidss_plane_atomic_check,
|
||||
.atomic_update = tidss_plane_atomic_update,
|
||||
@@ -151,7 +159,7 @@ static const struct drm_plane_funcs tidss_plane_funcs = {
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
.reset = drm_atomic_helper_plane_reset,
|
||||
.destroy = drm_plane_cleanup,
|
||||
.destroy = drm_plane_destroy,
|
||||
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
|
||||
};
|
||||
@@ -175,7 +183,7 @@ struct tidss_plane *tidss_plane_create(struct tidss_device *tidss,
|
||||
BIT(DRM_MODE_BLEND_COVERAGE));
|
||||
int ret;
|
||||
|
||||
tplane = devm_kzalloc(tidss->dev, sizeof(*tplane), GFP_KERNEL);
|
||||
tplane = kzalloc(sizeof(*tplane), GFP_KERNEL);
|
||||
if (!tplane)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@@ -190,7 +198,7 @@ struct tidss_plane *tidss_plane_create(struct tidss_device *tidss,
|
||||
formats, num_formats,
|
||||
NULL, type, NULL);
|
||||
if (ret < 0)
|
||||
return ERR_PTR(ret);
|
||||
goto err;
|
||||
|
||||
drm_plane_helper_add(&tplane->plane, &tidss_plane_helper_funcs);
|
||||
|
||||
@@ -203,15 +211,19 @@ struct tidss_plane *tidss_plane_create(struct tidss_device *tidss,
|
||||
default_encoding,
|
||||
default_range);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
goto err;
|
||||
|
||||
ret = drm_plane_create_alpha_property(&tplane->plane);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
goto err;
|
||||
|
||||
ret = drm_plane_create_blend_mode_property(&tplane->plane, blend_modes);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
goto err;
|
||||
|
||||
return tplane;
|
||||
|
||||
err:
|
||||
kfree(tplane);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
@@ -221,6 +221,7 @@ struct virtio_gpu_fpriv {
|
||||
/* virtio_ioctl.c */
|
||||
#define DRM_VIRTIO_NUM_IOCTLS 10
|
||||
extern struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS];
|
||||
void virtio_gpu_create_context(struct drm_device *dev, struct drm_file *file);
|
||||
|
||||
/* virtio_kms.c */
|
||||
int virtio_gpu_init(struct drm_device *dev);
|
||||
|
||||
@@ -39,6 +39,9 @@ int virtio_gpu_gem_create(struct drm_file *file,
|
||||
int ret;
|
||||
u32 handle;
|
||||
|
||||
if (vgdev->has_virgl_3d)
|
||||
virtio_gpu_create_context(dev, file);
|
||||
|
||||
ret = virtio_gpu_object_create(vgdev, params, &obj, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -27,14 +27,14 @@
|
||||
|
||||
#include <linux/file.h>
|
||||
#include <linux/sync_file.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <drm/drm_file.h>
|
||||
#include <drm/virtgpu_drm.h>
|
||||
|
||||
#include "virtgpu_drv.h"
|
||||
|
||||
static void virtio_gpu_create_context(struct drm_device *dev,
|
||||
struct drm_file *file)
|
||||
void virtio_gpu_create_context(struct drm_device *dev, struct drm_file *file)
|
||||
{
|
||||
struct virtio_gpu_device *vgdev = dev->dev_private;
|
||||
struct virtio_gpu_fpriv *vfpriv = file->driver_priv;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <linux/virtio.h>
|
||||
#include <linux/virtio_config.h>
|
||||
#include <linux/virtio_ring.h>
|
||||
|
||||
#include <drm/drm_file.h>
|
||||
|
||||
@@ -52,14 +53,6 @@ static void virtio_gpu_config_changed_work_func(struct work_struct *work)
|
||||
events_clear, &events_clear);
|
||||
}
|
||||
|
||||
static void virtio_gpu_context_destroy(struct virtio_gpu_device *vgdev,
|
||||
uint32_t ctx_id)
|
||||
{
|
||||
virtio_gpu_cmd_context_destroy(vgdev, ctx_id);
|
||||
virtio_gpu_notify(vgdev);
|
||||
ida_free(&vgdev->ctx_id_ida, ctx_id - 1);
|
||||
}
|
||||
|
||||
static void virtio_gpu_init_vq(struct virtio_gpu_queue *vgvq,
|
||||
void (*work_func)(struct work_struct *work))
|
||||
{
|
||||
@@ -274,14 +267,17 @@ int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file)
|
||||
void virtio_gpu_driver_postclose(struct drm_device *dev, struct drm_file *file)
|
||||
{
|
||||
struct virtio_gpu_device *vgdev = dev->dev_private;
|
||||
struct virtio_gpu_fpriv *vfpriv;
|
||||
struct virtio_gpu_fpriv *vfpriv = file->driver_priv;
|
||||
|
||||
if (!vgdev->has_virgl_3d)
|
||||
return;
|
||||
|
||||
vfpriv = file->driver_priv;
|
||||
if (vfpriv->context_created) {
|
||||
virtio_gpu_cmd_context_destroy(vgdev, vfpriv->ctx_id);
|
||||
virtio_gpu_notify(vgdev);
|
||||
}
|
||||
|
||||
virtio_gpu_context_destroy(vgdev, vfpriv->ctx_id);
|
||||
ida_free(&vgdev->ctx_id_ida, vfpriv->ctx_id - 1);
|
||||
mutex_destroy(&vfpriv->context_lock);
|
||||
kfree(vfpriv);
|
||||
file->driver_priv = NULL;
|
||||
|
||||
Reference in New Issue
Block a user