amd, etnaviv, mali_dp, syncobj and panel fixes
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJbrW4cAAoJEAx081l5xIa+A1EP/j7KbLBhzxOQ0zxtOH4dRJNn Gq1d0sddYKrk9Os7lj4EUr4xm6BebqfYM5Fz93sE2021A8Q8G9F+gOSVysWGGKVV HRvjDmAXf5JRpapwe509xoMJ5eSzXSbFtgN5BoNBiIwUctqwMTsR9WvChF+OuQLX pIOEopa2bkJVDIVxobsYK6oeiZcUM3lrAx7Gl8zLd8w+OyhTjjFCiuwnpysxKBZd +9Pn1FNzVfumx0l25HMqTcDYt5d9dJIkT/e268ZNRNpihDrvwQfh62L63sNTU2ji Yp6ZbWmZl8Ws7mk4y6FlLNpHf7O4O2WvqVaAmzgGeHWnFMiSsMSeaYUCVQsYD4EH 2gw3LjJN4FCfYr8yPsvV5ufRgmNosLSEwUZSyZ/70s8isv4giJoo64GKPf/EWGCw MMVJ4HxX1GpZqfyf0zz/guz1mWmsOhVeeTbAla+gIzjJcVhZyq4BBQsq9voUMWK7 ocaMeRJXloZDvxTiTXIpRc1ALRJ1pyQBX20vUrbm+HqrUyt/dW40STt7gbcVIvOp EFEG5b7kS9KuNErW3k0q4psA0KyUNt6XEcrsZEvrJP6ZYFQMGhBcN+ZNNqQPo5BK k5TOm1UGjtG9rVYQsHMMQCAJ6MNedDE0k+1AoD5PH8qNCkjHEDdaA6rydq6FdCEu cJJCrm0zpZl8/xh3UwPU =DT6k -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2018-09-28' of git://anongit.freedesktop.org/drm/drm Dave writes: "drm fixes for 4.19-rc6 Looks like a pretty normal week for graphics, core: syncobj fix, panel link regression revert amd: suspend/resume fixes, EDID emulation fix mali-dp: NV12 writeback and vblank reset fixes etnaviv: DMA setup fix" * tag 'drm-fixes-2018-09-28' of git://anongit.freedesktop.org/drm/drm: drm/amd/display: Fix Edid emulation for linux drm/amd/display: Fix Vega10 lightup on S3 resume drm/amdgpu: Fix vce work queue was not cancelled when suspend Revert "drm/panel: Add device_link from panel device to DRM device" drm/syncobj: Don't leak fences when WAIT_FOR_SUBMIT is set drm/malidp: Fix writeback in NV12 drm: mali-dp: Call drm_crtc_vblank_reset on device init drm/etnaviv: add DMA configuration for etnaviv platform device
This commit is contained in:
Коммит
f151f57bfd
|
@ -258,6 +258,8 @@ int amdgpu_vce_suspend(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
cancel_delayed_work_sync(&adev->vce.idle_work);
|
||||||
|
|
||||||
if (adev->vce.vcpu_bo == NULL)
|
if (adev->vce.vcpu_bo == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -268,7 +270,6 @@ int amdgpu_vce_suspend(struct amdgpu_device *adev)
|
||||||
if (i == AMDGPU_MAX_VCE_HANDLES)
|
if (i == AMDGPU_MAX_VCE_HANDLES)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cancel_delayed_work_sync(&adev->vce.idle_work);
|
|
||||||
/* TODO: suspending running encoding sessions isn't supported */
|
/* TODO: suspending running encoding sessions isn't supported */
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,11 +153,11 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev)
|
||||||
unsigned size;
|
unsigned size;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
||||||
|
cancel_delayed_work_sync(&adev->vcn.idle_work);
|
||||||
|
|
||||||
if (adev->vcn.vcpu_bo == NULL)
|
if (adev->vcn.vcpu_bo == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cancel_delayed_work_sync(&adev->vcn.idle_work);
|
|
||||||
|
|
||||||
size = amdgpu_bo_size(adev->vcn.vcpu_bo);
|
size = amdgpu_bo_size(adev->vcn.vcpu_bo);
|
||||||
ptr = adev->vcn.cpu_addr;
|
ptr = adev->vcn.cpu_addr;
|
||||||
|
|
||||||
|
|
|
@ -641,6 +641,87 @@ amdgpu_dm_find_first_crtc_matching_connector(struct drm_atomic_state *state,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void emulated_link_detect(struct dc_link *link)
|
||||||
|
{
|
||||||
|
struct dc_sink_init_data sink_init_data = { 0 };
|
||||||
|
struct display_sink_capability sink_caps = { 0 };
|
||||||
|
enum dc_edid_status edid_status;
|
||||||
|
struct dc_context *dc_ctx = link->ctx;
|
||||||
|
struct dc_sink *sink = NULL;
|
||||||
|
struct dc_sink *prev_sink = NULL;
|
||||||
|
|
||||||
|
link->type = dc_connection_none;
|
||||||
|
prev_sink = link->local_sink;
|
||||||
|
|
||||||
|
if (prev_sink != NULL)
|
||||||
|
dc_sink_retain(prev_sink);
|
||||||
|
|
||||||
|
switch (link->connector_signal) {
|
||||||
|
case SIGNAL_TYPE_HDMI_TYPE_A: {
|
||||||
|
sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
|
||||||
|
sink_caps.signal = SIGNAL_TYPE_HDMI_TYPE_A;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SIGNAL_TYPE_DVI_SINGLE_LINK: {
|
||||||
|
sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
|
||||||
|
sink_caps.signal = SIGNAL_TYPE_DVI_SINGLE_LINK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SIGNAL_TYPE_DVI_DUAL_LINK: {
|
||||||
|
sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
|
||||||
|
sink_caps.signal = SIGNAL_TYPE_DVI_DUAL_LINK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SIGNAL_TYPE_LVDS: {
|
||||||
|
sink_caps.transaction_type = DDC_TRANSACTION_TYPE_I2C;
|
||||||
|
sink_caps.signal = SIGNAL_TYPE_LVDS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SIGNAL_TYPE_EDP: {
|
||||||
|
sink_caps.transaction_type =
|
||||||
|
DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
|
||||||
|
sink_caps.signal = SIGNAL_TYPE_EDP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case SIGNAL_TYPE_DISPLAY_PORT: {
|
||||||
|
sink_caps.transaction_type =
|
||||||
|
DDC_TRANSACTION_TYPE_I2C_OVER_AUX;
|
||||||
|
sink_caps.signal = SIGNAL_TYPE_VIRTUAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
DC_ERROR("Invalid connector type! signal:%d\n",
|
||||||
|
link->connector_signal);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sink_init_data.link = link;
|
||||||
|
sink_init_data.sink_signal = sink_caps.signal;
|
||||||
|
|
||||||
|
sink = dc_sink_create(&sink_init_data);
|
||||||
|
if (!sink) {
|
||||||
|
DC_ERROR("Failed to create sink!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
link->local_sink = sink;
|
||||||
|
|
||||||
|
edid_status = dm_helpers_read_local_edid(
|
||||||
|
link->ctx,
|
||||||
|
link,
|
||||||
|
sink);
|
||||||
|
|
||||||
|
if (edid_status != EDID_OK)
|
||||||
|
DC_ERROR("Failed to read EDID");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static int dm_resume(void *handle)
|
static int dm_resume(void *handle)
|
||||||
{
|
{
|
||||||
struct amdgpu_device *adev = handle;
|
struct amdgpu_device *adev = handle;
|
||||||
|
@ -654,6 +735,7 @@ static int dm_resume(void *handle)
|
||||||
struct drm_plane *plane;
|
struct drm_plane *plane;
|
||||||
struct drm_plane_state *new_plane_state;
|
struct drm_plane_state *new_plane_state;
|
||||||
struct dm_plane_state *dm_new_plane_state;
|
struct dm_plane_state *dm_new_plane_state;
|
||||||
|
enum dc_connection_type new_connection_type = dc_connection_none;
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -684,7 +766,13 @@ static int dm_resume(void *handle)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mutex_lock(&aconnector->hpd_lock);
|
mutex_lock(&aconnector->hpd_lock);
|
||||||
dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD);
|
if (!dc_link_detect_sink(aconnector->dc_link, &new_connection_type))
|
||||||
|
DRM_ERROR("KMS: Failed to detect connector\n");
|
||||||
|
|
||||||
|
if (aconnector->base.force && new_connection_type == dc_connection_none)
|
||||||
|
emulated_link_detect(aconnector->dc_link);
|
||||||
|
else
|
||||||
|
dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD);
|
||||||
|
|
||||||
if (aconnector->fake_enable && aconnector->dc_link->local_sink)
|
if (aconnector->fake_enable && aconnector->dc_link->local_sink)
|
||||||
aconnector->fake_enable = false;
|
aconnector->fake_enable = false;
|
||||||
|
@ -922,6 +1010,7 @@ static void handle_hpd_irq(void *param)
|
||||||
struct amdgpu_dm_connector *aconnector = (struct amdgpu_dm_connector *)param;
|
struct amdgpu_dm_connector *aconnector = (struct amdgpu_dm_connector *)param;
|
||||||
struct drm_connector *connector = &aconnector->base;
|
struct drm_connector *connector = &aconnector->base;
|
||||||
struct drm_device *dev = connector->dev;
|
struct drm_device *dev = connector->dev;
|
||||||
|
enum dc_connection_type new_connection_type = dc_connection_none;
|
||||||
|
|
||||||
/* In case of failure or MST no need to update connector status or notify the OS
|
/* In case of failure or MST no need to update connector status or notify the OS
|
||||||
* since (for MST case) MST does this in it's own context.
|
* since (for MST case) MST does this in it's own context.
|
||||||
|
@ -931,7 +1020,21 @@ static void handle_hpd_irq(void *param)
|
||||||
if (aconnector->fake_enable)
|
if (aconnector->fake_enable)
|
||||||
aconnector->fake_enable = false;
|
aconnector->fake_enable = false;
|
||||||
|
|
||||||
if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD)) {
|
if (!dc_link_detect_sink(aconnector->dc_link, &new_connection_type))
|
||||||
|
DRM_ERROR("KMS: Failed to detect connector\n");
|
||||||
|
|
||||||
|
if (aconnector->base.force && new_connection_type == dc_connection_none) {
|
||||||
|
emulated_link_detect(aconnector->dc_link);
|
||||||
|
|
||||||
|
|
||||||
|
drm_modeset_lock_all(dev);
|
||||||
|
dm_restore_drm_connector_state(dev, connector);
|
||||||
|
drm_modeset_unlock_all(dev);
|
||||||
|
|
||||||
|
if (aconnector->base.force == DRM_FORCE_UNSPECIFIED)
|
||||||
|
drm_kms_helper_hotplug_event(dev);
|
||||||
|
|
||||||
|
} else if (dc_link_detect(aconnector->dc_link, DETECT_REASON_HPD)) {
|
||||||
amdgpu_dm_update_connector_after_detect(aconnector);
|
amdgpu_dm_update_connector_after_detect(aconnector);
|
||||||
|
|
||||||
|
|
||||||
|
@ -1031,6 +1134,7 @@ static void handle_hpd_rx_irq(void *param)
|
||||||
struct drm_device *dev = connector->dev;
|
struct drm_device *dev = connector->dev;
|
||||||
struct dc_link *dc_link = aconnector->dc_link;
|
struct dc_link *dc_link = aconnector->dc_link;
|
||||||
bool is_mst_root_connector = aconnector->mst_mgr.mst_state;
|
bool is_mst_root_connector = aconnector->mst_mgr.mst_state;
|
||||||
|
enum dc_connection_type new_connection_type = dc_connection_none;
|
||||||
|
|
||||||
/* TODO:Temporary add mutex to protect hpd interrupt not have a gpio
|
/* TODO:Temporary add mutex to protect hpd interrupt not have a gpio
|
||||||
* conflict, after implement i2c helper, this mutex should be
|
* conflict, after implement i2c helper, this mutex should be
|
||||||
|
@ -1042,7 +1146,24 @@ static void handle_hpd_rx_irq(void *param)
|
||||||
if (dc_link_handle_hpd_rx_irq(dc_link, NULL, NULL) &&
|
if (dc_link_handle_hpd_rx_irq(dc_link, NULL, NULL) &&
|
||||||
!is_mst_root_connector) {
|
!is_mst_root_connector) {
|
||||||
/* Downstream Port status changed. */
|
/* Downstream Port status changed. */
|
||||||
if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) {
|
if (!dc_link_detect_sink(dc_link, &new_connection_type))
|
||||||
|
DRM_ERROR("KMS: Failed to detect connector\n");
|
||||||
|
|
||||||
|
if (aconnector->base.force && new_connection_type == dc_connection_none) {
|
||||||
|
emulated_link_detect(dc_link);
|
||||||
|
|
||||||
|
if (aconnector->fake_enable)
|
||||||
|
aconnector->fake_enable = false;
|
||||||
|
|
||||||
|
amdgpu_dm_update_connector_after_detect(aconnector);
|
||||||
|
|
||||||
|
|
||||||
|
drm_modeset_lock_all(dev);
|
||||||
|
dm_restore_drm_connector_state(dev, connector);
|
||||||
|
drm_modeset_unlock_all(dev);
|
||||||
|
|
||||||
|
drm_kms_helper_hotplug_event(dev);
|
||||||
|
} else if (dc_link_detect(dc_link, DETECT_REASON_HPDRX)) {
|
||||||
|
|
||||||
if (aconnector->fake_enable)
|
if (aconnector->fake_enable)
|
||||||
aconnector->fake_enable = false;
|
aconnector->fake_enable = false;
|
||||||
|
@ -1433,6 +1554,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
|
||||||
struct amdgpu_mode_info *mode_info = &adev->mode_info;
|
struct amdgpu_mode_info *mode_info = &adev->mode_info;
|
||||||
uint32_t link_cnt;
|
uint32_t link_cnt;
|
||||||
int32_t total_overlay_planes, total_primary_planes;
|
int32_t total_overlay_planes, total_primary_planes;
|
||||||
|
enum dc_connection_type new_connection_type = dc_connection_none;
|
||||||
|
|
||||||
link_cnt = dm->dc->caps.max_links;
|
link_cnt = dm->dc->caps.max_links;
|
||||||
if (amdgpu_dm_mode_config_init(dm->adev)) {
|
if (amdgpu_dm_mode_config_init(dm->adev)) {
|
||||||
|
@ -1499,7 +1621,14 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev)
|
||||||
|
|
||||||
link = dc_get_link_at_index(dm->dc, i);
|
link = dc_get_link_at_index(dm->dc, i);
|
||||||
|
|
||||||
if (dc_link_detect(link, DETECT_REASON_BOOT)) {
|
if (!dc_link_detect_sink(link, &new_connection_type))
|
||||||
|
DRM_ERROR("KMS: Failed to detect connector\n");
|
||||||
|
|
||||||
|
if (aconnector->base.force && new_connection_type == dc_connection_none) {
|
||||||
|
emulated_link_detect(link);
|
||||||
|
amdgpu_dm_update_connector_after_detect(aconnector);
|
||||||
|
|
||||||
|
} else if (dc_link_detect(link, DETECT_REASON_BOOT)) {
|
||||||
amdgpu_dm_update_connector_after_detect(aconnector);
|
amdgpu_dm_update_connector_after_detect(aconnector);
|
||||||
register_backlight_device(dm, link);
|
register_backlight_device(dm, link);
|
||||||
}
|
}
|
||||||
|
@ -2494,7 +2623,7 @@ create_stream_for_sink(struct amdgpu_dm_connector *aconnector,
|
||||||
if (dm_state && dm_state->freesync_capable)
|
if (dm_state && dm_state->freesync_capable)
|
||||||
stream->ignore_msa_timing_param = true;
|
stream->ignore_msa_timing_param = true;
|
||||||
finish:
|
finish:
|
||||||
if (sink && sink->sink_signal == SIGNAL_TYPE_VIRTUAL)
|
if (sink && sink->sink_signal == SIGNAL_TYPE_VIRTUAL && aconnector->base.force != DRM_FORCE_ON)
|
||||||
dc_sink_release(sink);
|
dc_sink_release(sink);
|
||||||
|
|
||||||
return stream;
|
return stream;
|
||||||
|
|
|
@ -195,7 +195,7 @@ static bool program_hpd_filter(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool detect_sink(struct dc_link *link, enum dc_connection_type *type)
|
bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type)
|
||||||
{
|
{
|
||||||
uint32_t is_hpd_high = 0;
|
uint32_t is_hpd_high = 0;
|
||||||
struct gpio *hpd_pin;
|
struct gpio *hpd_pin;
|
||||||
|
@ -604,7 +604,7 @@ bool dc_link_detect(struct dc_link *link, enum dc_detect_reason reason)
|
||||||
if (link->connector_signal == SIGNAL_TYPE_VIRTUAL)
|
if (link->connector_signal == SIGNAL_TYPE_VIRTUAL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (false == detect_sink(link, &new_connection_type)) {
|
if (false == dc_link_detect_sink(link, &new_connection_type)) {
|
||||||
BREAK_TO_DEBUGGER();
|
BREAK_TO_DEBUGGER();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,6 +215,7 @@ void dc_link_enable_hpd_filter(struct dc_link *link, bool enable);
|
||||||
|
|
||||||
bool dc_link_is_dp_sink_present(struct dc_link *link);
|
bool dc_link_is_dp_sink_present(struct dc_link *link);
|
||||||
|
|
||||||
|
bool dc_link_detect_sink(struct dc_link *link, enum dc_connection_type *type);
|
||||||
/*
|
/*
|
||||||
* DPCD access interfaces
|
* DPCD access interfaces
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2560,7 +2560,7 @@ static void pplib_apply_display_requirements(
|
||||||
dc->prev_display_config = *pp_display_cfg;
|
dc->prev_display_config = *pp_display_cfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dce110_set_bandwidth(
|
static void dce110_set_bandwidth(
|
||||||
struct dc *dc,
|
struct dc *dc,
|
||||||
struct dc_state *context,
|
struct dc_state *context,
|
||||||
bool decrease_allowed)
|
bool decrease_allowed)
|
||||||
|
|
|
@ -68,11 +68,6 @@ void dce110_fill_display_configs(
|
||||||
const struct dc_state *context,
|
const struct dc_state *context,
|
||||||
struct dm_pp_display_configuration *pp_display_cfg);
|
struct dm_pp_display_configuration *pp_display_cfg);
|
||||||
|
|
||||||
void dce110_set_bandwidth(
|
|
||||||
struct dc *dc,
|
|
||||||
struct dc_state *context,
|
|
||||||
bool decrease_allowed);
|
|
||||||
|
|
||||||
uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context);
|
uint32_t dce110_get_min_vblank_time_us(const struct dc_state *context);
|
||||||
|
|
||||||
void dp_receiver_power_ctrl(struct dc_link *link, bool on);
|
void dp_receiver_power_ctrl(struct dc_link *link, bool on);
|
||||||
|
|
|
@ -244,17 +244,6 @@ static void dce120_update_dchub(
|
||||||
dh_data->dchub_info_valid = false;
|
dh_data->dchub_info_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dce120_set_bandwidth(
|
|
||||||
struct dc *dc,
|
|
||||||
struct dc_state *context,
|
|
||||||
bool decrease_allowed)
|
|
||||||
{
|
|
||||||
if (context->stream_count <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dce110_set_bandwidth(dc, context, decrease_allowed);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dce120_hw_sequencer_construct(struct dc *dc)
|
void dce120_hw_sequencer_construct(struct dc *dc)
|
||||||
{
|
{
|
||||||
/* All registers used by dce11.2 match those in dce11 in offset and
|
/* All registers used by dce11.2 match those in dce11 in offset and
|
||||||
|
@ -263,6 +252,5 @@ void dce120_hw_sequencer_construct(struct dc *dc)
|
||||||
dce110_hw_sequencer_construct(dc);
|
dce110_hw_sequencer_construct(dc);
|
||||||
dc->hwss.enable_display_power_gating = dce120_enable_display_power_gating;
|
dc->hwss.enable_display_power_gating = dce120_enable_display_power_gating;
|
||||||
dc->hwss.update_dchub = dce120_update_dchub;
|
dc->hwss.update_dchub = dce120_update_dchub;
|
||||||
dc->hwss.set_bandwidth = dce120_set_bandwidth;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -754,6 +754,7 @@ static int malidp_bind(struct device *dev)
|
||||||
drm->irq_enabled = true;
|
drm->irq_enabled = true;
|
||||||
|
|
||||||
ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
|
ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
|
||||||
|
drm_crtc_vblank_reset(&malidp->crtc);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
DRM_ERROR("failed to initialise vblank\n");
|
DRM_ERROR("failed to initialise vblank\n");
|
||||||
goto vblank_fail;
|
goto vblank_fail;
|
||||||
|
|
|
@ -384,7 +384,8 @@ static long malidp500_se_calc_mclk(struct malidp_hw_device *hwdev,
|
||||||
|
|
||||||
static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev,
|
static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev,
|
||||||
dma_addr_t *addrs, s32 *pitches,
|
dma_addr_t *addrs, s32 *pitches,
|
||||||
int num_planes, u16 w, u16 h, u32 fmt_id)
|
int num_planes, u16 w, u16 h, u32 fmt_id,
|
||||||
|
const s16 *rgb2yuv_coeffs)
|
||||||
{
|
{
|
||||||
u32 base = MALIDP500_SE_MEMWRITE_BASE;
|
u32 base = MALIDP500_SE_MEMWRITE_BASE;
|
||||||
u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK);
|
u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK);
|
||||||
|
@ -416,6 +417,16 @@ static int malidp500_enable_memwrite(struct malidp_hw_device *hwdev,
|
||||||
|
|
||||||
malidp_hw_write(hwdev, MALIDP_DE_H_ACTIVE(w) | MALIDP_DE_V_ACTIVE(h),
|
malidp_hw_write(hwdev, MALIDP_DE_H_ACTIVE(w) | MALIDP_DE_V_ACTIVE(h),
|
||||||
MALIDP500_SE_MEMWRITE_OUT_SIZE);
|
MALIDP500_SE_MEMWRITE_OUT_SIZE);
|
||||||
|
|
||||||
|
if (rgb2yuv_coeffs) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) {
|
||||||
|
malidp_hw_write(hwdev, rgb2yuv_coeffs[i],
|
||||||
|
MALIDP500_SE_RGB_YUV_COEFFS + i * 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
malidp_hw_setbits(hwdev, MALIDP_SE_MEMWRITE_EN, MALIDP500_SE_CONTROL);
|
malidp_hw_setbits(hwdev, MALIDP_SE_MEMWRITE_EN, MALIDP500_SE_CONTROL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -658,7 +669,8 @@ static long malidp550_se_calc_mclk(struct malidp_hw_device *hwdev,
|
||||||
|
|
||||||
static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev,
|
static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev,
|
||||||
dma_addr_t *addrs, s32 *pitches,
|
dma_addr_t *addrs, s32 *pitches,
|
||||||
int num_planes, u16 w, u16 h, u32 fmt_id)
|
int num_planes, u16 w, u16 h, u32 fmt_id,
|
||||||
|
const s16 *rgb2yuv_coeffs)
|
||||||
{
|
{
|
||||||
u32 base = MALIDP550_SE_MEMWRITE_BASE;
|
u32 base = MALIDP550_SE_MEMWRITE_BASE;
|
||||||
u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK);
|
u32 de_base = malidp_get_block_base(hwdev, MALIDP_DE_BLOCK);
|
||||||
|
@ -689,6 +701,15 @@ static int malidp550_enable_memwrite(struct malidp_hw_device *hwdev,
|
||||||
malidp_hw_setbits(hwdev, MALIDP550_SE_MEMWRITE_ONESHOT | MALIDP_SE_MEMWRITE_EN,
|
malidp_hw_setbits(hwdev, MALIDP550_SE_MEMWRITE_ONESHOT | MALIDP_SE_MEMWRITE_EN,
|
||||||
MALIDP550_SE_CONTROL);
|
MALIDP550_SE_CONTROL);
|
||||||
|
|
||||||
|
if (rgb2yuv_coeffs) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MALIDP_COLORADJ_NUM_COEFFS; i++) {
|
||||||
|
malidp_hw_write(hwdev, rgb2yuv_coeffs[i],
|
||||||
|
MALIDP550_SE_RGB_YUV_COEFFS + i * 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -191,7 +191,8 @@ struct malidp_hw {
|
||||||
* @param fmt_id - internal format ID of output buffer
|
* @param fmt_id - internal format ID of output buffer
|
||||||
*/
|
*/
|
||||||
int (*enable_memwrite)(struct malidp_hw_device *hwdev, dma_addr_t *addrs,
|
int (*enable_memwrite)(struct malidp_hw_device *hwdev, dma_addr_t *addrs,
|
||||||
s32 *pitches, int num_planes, u16 w, u16 h, u32 fmt_id);
|
s32 *pitches, int num_planes, u16 w, u16 h, u32 fmt_id,
|
||||||
|
const s16 *rgb2yuv_coeffs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disable the writing to memory of the next frame's content.
|
* Disable the writing to memory of the next frame's content.
|
||||||
|
|
|
@ -26,6 +26,8 @@ struct malidp_mw_connector_state {
|
||||||
s32 pitches[2];
|
s32 pitches[2];
|
||||||
u8 format;
|
u8 format;
|
||||||
u8 n_planes;
|
u8 n_planes;
|
||||||
|
bool rgb2yuv_initialized;
|
||||||
|
const s16 *rgb2yuv_coeffs;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int malidp_mw_connector_get_modes(struct drm_connector *connector)
|
static int malidp_mw_connector_get_modes(struct drm_connector *connector)
|
||||||
|
@ -84,7 +86,7 @@ static void malidp_mw_connector_destroy(struct drm_connector *connector)
|
||||||
static struct drm_connector_state *
|
static struct drm_connector_state *
|
||||||
malidp_mw_connector_duplicate_state(struct drm_connector *connector)
|
malidp_mw_connector_duplicate_state(struct drm_connector *connector)
|
||||||
{
|
{
|
||||||
struct malidp_mw_connector_state *mw_state;
|
struct malidp_mw_connector_state *mw_state, *mw_current_state;
|
||||||
|
|
||||||
if (WARN_ON(!connector->state))
|
if (WARN_ON(!connector->state))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -93,7 +95,10 @@ malidp_mw_connector_duplicate_state(struct drm_connector *connector)
|
||||||
if (!mw_state)
|
if (!mw_state)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* No need to preserve any of our driver-local data */
|
mw_current_state = to_mw_state(connector->state);
|
||||||
|
mw_state->rgb2yuv_coeffs = mw_current_state->rgb2yuv_coeffs;
|
||||||
|
mw_state->rgb2yuv_initialized = mw_current_state->rgb2yuv_initialized;
|
||||||
|
|
||||||
__drm_atomic_helper_connector_duplicate_state(connector, &mw_state->base);
|
__drm_atomic_helper_connector_duplicate_state(connector, &mw_state->base);
|
||||||
|
|
||||||
return &mw_state->base;
|
return &mw_state->base;
|
||||||
|
@ -108,6 +113,13 @@ static const struct drm_connector_funcs malidp_mw_connector_funcs = {
|
||||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const s16 rgb2yuv_coeffs_bt709_limited[MALIDP_COLORADJ_NUM_COEFFS] = {
|
||||||
|
47, 157, 16,
|
||||||
|
-26, -87, 112,
|
||||||
|
112, -102, -10,
|
||||||
|
16, 128, 128
|
||||||
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
|
malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
|
||||||
struct drm_crtc_state *crtc_state,
|
struct drm_crtc_state *crtc_state,
|
||||||
|
@ -157,6 +169,9 @@ malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
|
||||||
}
|
}
|
||||||
mw_state->n_planes = n_planes;
|
mw_state->n_planes = n_planes;
|
||||||
|
|
||||||
|
if (fb->format->is_yuv)
|
||||||
|
mw_state->rgb2yuv_coeffs = rgb2yuv_coeffs_bt709_limited;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,10 +254,12 @@ void malidp_mw_atomic_commit(struct drm_device *drm,
|
||||||
|
|
||||||
drm_writeback_queue_job(mw_conn, conn_state->writeback_job);
|
drm_writeback_queue_job(mw_conn, conn_state->writeback_job);
|
||||||
conn_state->writeback_job = NULL;
|
conn_state->writeback_job = NULL;
|
||||||
|
|
||||||
hwdev->hw->enable_memwrite(hwdev, mw_state->addrs,
|
hwdev->hw->enable_memwrite(hwdev, mw_state->addrs,
|
||||||
mw_state->pitches, mw_state->n_planes,
|
mw_state->pitches, mw_state->n_planes,
|
||||||
fb->width, fb->height, mw_state->format);
|
fb->width, fb->height, mw_state->format,
|
||||||
|
!mw_state->rgb2yuv_initialized ?
|
||||||
|
mw_state->rgb2yuv_coeffs : NULL);
|
||||||
|
mw_state->rgb2yuv_initialized = !!mw_state->rgb2yuv_coeffs;
|
||||||
} else {
|
} else {
|
||||||
DRM_DEV_DEBUG_DRIVER(drm->dev, "Disable memwrite\n");
|
DRM_DEV_DEBUG_DRIVER(drm->dev, "Disable memwrite\n");
|
||||||
hwdev->hw->disable_memwrite(hwdev);
|
hwdev->hw->disable_memwrite(hwdev);
|
||||||
|
|
|
@ -205,6 +205,7 @@
|
||||||
#define MALIDP500_SE_BASE 0x00c00
|
#define MALIDP500_SE_BASE 0x00c00
|
||||||
#define MALIDP500_SE_CONTROL 0x00c0c
|
#define MALIDP500_SE_CONTROL 0x00c0c
|
||||||
#define MALIDP500_SE_MEMWRITE_OUT_SIZE 0x00c2c
|
#define MALIDP500_SE_MEMWRITE_OUT_SIZE 0x00c2c
|
||||||
|
#define MALIDP500_SE_RGB_YUV_COEFFS 0x00C74
|
||||||
#define MALIDP500_SE_MEMWRITE_BASE 0x00e00
|
#define MALIDP500_SE_MEMWRITE_BASE 0x00e00
|
||||||
#define MALIDP500_DC_IRQ_BASE 0x00f00
|
#define MALIDP500_DC_IRQ_BASE 0x00f00
|
||||||
#define MALIDP500_CONFIG_VALID 0x00f00
|
#define MALIDP500_CONFIG_VALID 0x00f00
|
||||||
|
@ -238,6 +239,7 @@
|
||||||
#define MALIDP550_SE_CONTROL 0x08010
|
#define MALIDP550_SE_CONTROL 0x08010
|
||||||
#define MALIDP550_SE_MEMWRITE_ONESHOT (1 << 7)
|
#define MALIDP550_SE_MEMWRITE_ONESHOT (1 << 7)
|
||||||
#define MALIDP550_SE_MEMWRITE_OUT_SIZE 0x08030
|
#define MALIDP550_SE_MEMWRITE_OUT_SIZE 0x08030
|
||||||
|
#define MALIDP550_SE_RGB_YUV_COEFFS 0x08078
|
||||||
#define MALIDP550_SE_MEMWRITE_BASE 0x08100
|
#define MALIDP550_SE_MEMWRITE_BASE 0x08100
|
||||||
#define MALIDP550_DC_BASE 0x0c000
|
#define MALIDP550_DC_BASE 0x0c000
|
||||||
#define MALIDP550_DC_CONTROL 0x0c010
|
#define MALIDP550_DC_CONTROL 0x0c010
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
#include <drm/drm_device.h>
|
|
||||||
#include <drm/drm_crtc.h>
|
#include <drm/drm_crtc.h>
|
||||||
#include <drm/drm_panel.h>
|
#include <drm/drm_panel.h>
|
||||||
|
|
||||||
|
@ -105,13 +104,6 @@ int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector)
|
||||||
if (panel->connector)
|
if (panel->connector)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
panel->link = device_link_add(connector->dev->dev, panel->dev, 0);
|
|
||||||
if (!panel->link) {
|
|
||||||
dev_err(panel->dev, "failed to link panel to %s\n",
|
|
||||||
dev_name(connector->dev->dev));
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
panel->connector = connector;
|
panel->connector = connector;
|
||||||
panel->drm = connector->dev;
|
panel->drm = connector->dev;
|
||||||
|
|
||||||
|
@ -133,8 +125,6 @@ EXPORT_SYMBOL(drm_panel_attach);
|
||||||
*/
|
*/
|
||||||
int drm_panel_detach(struct drm_panel *panel)
|
int drm_panel_detach(struct drm_panel *panel)
|
||||||
{
|
{
|
||||||
device_link_del(panel->link);
|
|
||||||
|
|
||||||
panel->connector = NULL;
|
panel->connector = NULL;
|
||||||
panel->drm = NULL;
|
panel->drm = NULL;
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,8 @@ static int drm_syncobj_fence_get_or_add_callback(struct drm_syncobj *syncobj,
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
WARN_ON(*fence);
|
||||||
|
|
||||||
*fence = drm_syncobj_fence_get(syncobj);
|
*fence = drm_syncobj_fence_get(syncobj);
|
||||||
if (*fence)
|
if (*fence)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -743,6 +745,9 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs,
|
||||||
|
|
||||||
if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
|
if (flags & DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) {
|
||||||
for (i = 0; i < count; ++i) {
|
for (i = 0; i < count; ++i) {
|
||||||
|
if (entries[i].fence)
|
||||||
|
continue;
|
||||||
|
|
||||||
drm_syncobj_fence_get_or_add_callback(syncobjs[i],
|
drm_syncobj_fence_get_or_add_callback(syncobjs[i],
|
||||||
&entries[i].fence,
|
&entries[i].fence,
|
||||||
&entries[i].syncobj_cb,
|
&entries[i].syncobj_cb,
|
||||||
|
|
|
@ -592,8 +592,6 @@ static int etnaviv_pdev_probe(struct platform_device *pdev)
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct component_match *match = NULL;
|
struct component_match *match = NULL;
|
||||||
|
|
||||||
dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
|
|
||||||
|
|
||||||
if (!dev->platform_data) {
|
if (!dev->platform_data) {
|
||||||
struct device_node *core_node;
|
struct device_node *core_node;
|
||||||
|
|
||||||
|
@ -655,13 +653,30 @@ static int __init etnaviv_init(void)
|
||||||
for_each_compatible_node(np, NULL, "vivante,gc") {
|
for_each_compatible_node(np, NULL, "vivante,gc") {
|
||||||
if (!of_device_is_available(np))
|
if (!of_device_is_available(np))
|
||||||
continue;
|
continue;
|
||||||
pdev = platform_device_register_simple("etnaviv", -1,
|
|
||||||
NULL, 0);
|
pdev = platform_device_alloc("etnaviv", -1);
|
||||||
if (IS_ERR(pdev)) {
|
if (!pdev) {
|
||||||
ret = PTR_ERR(pdev);
|
ret = -ENOMEM;
|
||||||
of_node_put(np);
|
of_node_put(np);
|
||||||
goto unregister_platform_driver;
|
goto unregister_platform_driver;
|
||||||
}
|
}
|
||||||
|
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(40);
|
||||||
|
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Apply the same DMA configuration to the virtual etnaviv
|
||||||
|
* device as the GPU we found. This assumes that all Vivante
|
||||||
|
* GPUs in the system share the same DMA constraints.
|
||||||
|
*/
|
||||||
|
of_dma_configure(&pdev->dev, np, true);
|
||||||
|
|
||||||
|
ret = platform_device_add(pdev);
|
||||||
|
if (ret) {
|
||||||
|
platform_device_put(pdev);
|
||||||
|
of_node_put(np);
|
||||||
|
goto unregister_platform_driver;
|
||||||
|
}
|
||||||
|
|
||||||
etnaviv_drm = pdev;
|
etnaviv_drm = pdev;
|
||||||
of_node_put(np);
|
of_node_put(np);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -89,7 +89,6 @@ struct drm_panel {
|
||||||
struct drm_device *drm;
|
struct drm_device *drm;
|
||||||
struct drm_connector *connector;
|
struct drm_connector *connector;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct device_link *link;
|
|
||||||
|
|
||||||
const struct drm_panel_funcs *funcs;
|
const struct drm_panel_funcs *funcs;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче