提交 c8440a70 编写于 作者: D Dave Airlie

Merge branch 'drm-fixes-4.18' of git://people.freedesktop.org/~agd5f/linux into drm-fixes

- Fix an HDMI 2.0 4k@60 regression
- Hotplug fixes for PX/HG laptops
- Fixes for vbios changes in vega12
- Fix a race in the user fence code
- Fix a couple of misc typos
Signed-off-by: NDave Airlie <airlied@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180705155206.2752-1-alexander.deucher@amd.com
...@@ -190,6 +190,7 @@ struct amdgpu_job; ...@@ -190,6 +190,7 @@ struct amdgpu_job;
struct amdgpu_irq_src; struct amdgpu_irq_src;
struct amdgpu_fpriv; struct amdgpu_fpriv;
struct amdgpu_bo_va_mapping; struct amdgpu_bo_va_mapping;
struct amdgpu_atif;
enum amdgpu_cp_irq { enum amdgpu_cp_irq {
AMDGPU_CP_IRQ_GFX_EOP = 0, AMDGPU_CP_IRQ_GFX_EOP = 0,
...@@ -1269,43 +1270,6 @@ struct amdgpu_vram_scratch { ...@@ -1269,43 +1270,6 @@ struct amdgpu_vram_scratch {
/* /*
* ACPI * ACPI
*/ */
struct amdgpu_atif_notification_cfg {
bool enabled;
int command_code;
};
struct amdgpu_atif_notifications {
bool display_switch;
bool expansion_mode_change;
bool thermal_state;
bool forced_power_state;
bool system_power_state;
bool display_conf_change;
bool px_gfx_switch;
bool brightness_change;
bool dgpu_display_event;
};
struct amdgpu_atif_functions {
bool system_params;
bool sbios_requests;
bool select_active_disp;
bool lid_state;
bool get_tv_standard;
bool set_tv_standard;
bool get_panel_expansion_mode;
bool set_panel_expansion_mode;
bool temperature_change;
bool graphics_device_types;
};
struct amdgpu_atif {
struct amdgpu_atif_notifications notifications;
struct amdgpu_atif_functions functions;
struct amdgpu_atif_notification_cfg notification_cfg;
struct amdgpu_encoder *encoder_for_bl;
};
struct amdgpu_atcs_functions { struct amdgpu_atcs_functions {
bool get_ext_state; bool get_ext_state;
bool pcie_perf_req; bool pcie_perf_req;
...@@ -1466,7 +1430,7 @@ struct amdgpu_device { ...@@ -1466,7 +1430,7 @@ struct amdgpu_device {
#if defined(CONFIG_DEBUG_FS) #if defined(CONFIG_DEBUG_FS)
struct dentry *debugfs_regs[AMDGPU_DEBUGFS_MAX_COMPONENTS]; struct dentry *debugfs_regs[AMDGPU_DEBUGFS_MAX_COMPONENTS];
#endif #endif
struct amdgpu_atif atif; struct amdgpu_atif *atif;
struct amdgpu_atcs atcs; struct amdgpu_atcs atcs;
struct mutex srbm_mutex; struct mutex srbm_mutex;
/* GRBM index mutex. Protects concurrent access to GRBM index */ /* GRBM index mutex. Protects concurrent access to GRBM index */
...@@ -1894,6 +1858,12 @@ static inline bool amdgpu_atpx_dgpu_req_power_for_displays(void) { return false; ...@@ -1894,6 +1858,12 @@ static inline bool amdgpu_atpx_dgpu_req_power_for_displays(void) { return false;
static inline bool amdgpu_has_atpx(void) { return false; } static inline bool amdgpu_has_atpx(void) { return false; }
#endif #endif
#if defined(CONFIG_VGA_SWITCHEROO) && defined(CONFIG_ACPI)
void *amdgpu_atpx_get_dhandle(void);
#else
static inline void *amdgpu_atpx_get_dhandle(void) { return NULL; }
#endif
/* /*
* KMS * KMS
*/ */
......
...@@ -34,6 +34,45 @@ ...@@ -34,6 +34,45 @@
#include "amd_acpi.h" #include "amd_acpi.h"
#include "atom.h" #include "atom.h"
struct amdgpu_atif_notification_cfg {
bool enabled;
int command_code;
};
struct amdgpu_atif_notifications {
bool display_switch;
bool expansion_mode_change;
bool thermal_state;
bool forced_power_state;
bool system_power_state;
bool display_conf_change;
bool px_gfx_switch;
bool brightness_change;
bool dgpu_display_event;
};
struct amdgpu_atif_functions {
bool system_params;
bool sbios_requests;
bool select_active_disp;
bool lid_state;
bool get_tv_standard;
bool set_tv_standard;
bool get_panel_expansion_mode;
bool set_panel_expansion_mode;
bool temperature_change;
bool graphics_device_types;
};
struct amdgpu_atif {
acpi_handle handle;
struct amdgpu_atif_notifications notifications;
struct amdgpu_atif_functions functions;
struct amdgpu_atif_notification_cfg notification_cfg;
struct amdgpu_encoder *encoder_for_bl;
};
/* Call the ATIF method /* Call the ATIF method
*/ */
/** /**
...@@ -46,8 +85,9 @@ ...@@ -46,8 +85,9 @@
* Executes the requested ATIF function (all asics). * Executes the requested ATIF function (all asics).
* Returns a pointer to the acpi output buffer. * Returns a pointer to the acpi output buffer.
*/ */
static union acpi_object *amdgpu_atif_call(acpi_handle handle, int function, static union acpi_object *amdgpu_atif_call(struct amdgpu_atif *atif,
struct acpi_buffer *params) int function,
struct acpi_buffer *params)
{ {
acpi_status status; acpi_status status;
union acpi_object atif_arg_elements[2]; union acpi_object atif_arg_elements[2];
...@@ -70,7 +110,8 @@ static union acpi_object *amdgpu_atif_call(acpi_handle handle, int function, ...@@ -70,7 +110,8 @@ static union acpi_object *amdgpu_atif_call(acpi_handle handle, int function,
atif_arg_elements[1].integer.value = 0; atif_arg_elements[1].integer.value = 0;
} }
status = acpi_evaluate_object(handle, "ATIF", &atif_arg, &buffer); status = acpi_evaluate_object(atif->handle, NULL, &atif_arg,
&buffer);
/* Fail only if calling the method fails and ATIF is supported */ /* Fail only if calling the method fails and ATIF is supported */
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
...@@ -141,15 +182,14 @@ static void amdgpu_atif_parse_functions(struct amdgpu_atif_functions *f, u32 mas ...@@ -141,15 +182,14 @@ static void amdgpu_atif_parse_functions(struct amdgpu_atif_functions *f, u32 mas
* (all asics). * (all asics).
* returns 0 on success, error on failure. * returns 0 on success, error on failure.
*/ */
static int amdgpu_atif_verify_interface(acpi_handle handle, static int amdgpu_atif_verify_interface(struct amdgpu_atif *atif)
struct amdgpu_atif *atif)
{ {
union acpi_object *info; union acpi_object *info;
struct atif_verify_interface output; struct atif_verify_interface output;
size_t size; size_t size;
int err = 0; int err = 0;
info = amdgpu_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); info = amdgpu_atif_call(atif, ATIF_FUNCTION_VERIFY_INTERFACE, NULL);
if (!info) if (!info)
return -EIO; return -EIO;
...@@ -176,6 +216,35 @@ static int amdgpu_atif_verify_interface(acpi_handle handle, ...@@ -176,6 +216,35 @@ static int amdgpu_atif_verify_interface(acpi_handle handle,
return err; return err;
} }
static acpi_handle amdgpu_atif_probe_handle(acpi_handle dhandle)
{
acpi_handle handle = NULL;
char acpi_method_name[255] = { 0 };
struct acpi_buffer buffer = { sizeof(acpi_method_name), acpi_method_name };
acpi_status status;
/* For PX/HG systems, ATIF and ATPX are in the iGPU's namespace, on dGPU only
* systems, ATIF is in the dGPU's namespace.
*/
status = acpi_get_handle(dhandle, "ATIF", &handle);
if (ACPI_SUCCESS(status))
goto out;
if (amdgpu_has_atpx()) {
status = acpi_get_handle(amdgpu_atpx_get_dhandle(), "ATIF",
&handle);
if (ACPI_SUCCESS(status))
goto out;
}
DRM_DEBUG_DRIVER("No ATIF handle found\n");
return NULL;
out:
acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
DRM_DEBUG_DRIVER("Found ATIF handle %s\n", acpi_method_name);
return handle;
}
/** /**
* amdgpu_atif_get_notification_params - determine notify configuration * amdgpu_atif_get_notification_params - determine notify configuration
* *
...@@ -188,15 +257,16 @@ static int amdgpu_atif_verify_interface(acpi_handle handle, ...@@ -188,15 +257,16 @@ static int amdgpu_atif_verify_interface(acpi_handle handle,
* where n is specified in the result if a notifier is used. * where n is specified in the result if a notifier is used.
* Returns 0 on success, error on failure. * Returns 0 on success, error on failure.
*/ */
static int amdgpu_atif_get_notification_params(acpi_handle handle, static int amdgpu_atif_get_notification_params(struct amdgpu_atif *atif)
struct amdgpu_atif_notification_cfg *n)
{ {
union acpi_object *info; union acpi_object *info;
struct amdgpu_atif_notification_cfg *n = &atif->notification_cfg;
struct atif_system_params params; struct atif_system_params params;
size_t size; size_t size;
int err = 0; int err = 0;
info = amdgpu_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS, NULL); info = amdgpu_atif_call(atif, ATIF_FUNCTION_GET_SYSTEM_PARAMETERS,
NULL);
if (!info) { if (!info) {
err = -EIO; err = -EIO;
goto out; goto out;
...@@ -250,14 +320,15 @@ static int amdgpu_atif_get_notification_params(acpi_handle handle, ...@@ -250,14 +320,15 @@ static int amdgpu_atif_get_notification_params(acpi_handle handle,
* (all asics). * (all asics).
* Returns 0 on success, error on failure. * Returns 0 on success, error on failure.
*/ */
static int amdgpu_atif_get_sbios_requests(acpi_handle handle, static int amdgpu_atif_get_sbios_requests(struct amdgpu_atif *atif,
struct atif_sbios_requests *req) struct atif_sbios_requests *req)
{ {
union acpi_object *info; union acpi_object *info;
size_t size; size_t size;
int count = 0; int count = 0;
info = amdgpu_atif_call(handle, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS, NULL); info = amdgpu_atif_call(atif, ATIF_FUNCTION_GET_SYSTEM_BIOS_REQUESTS,
NULL);
if (!info) if (!info)
return -EIO; return -EIO;
...@@ -290,11 +361,10 @@ static int amdgpu_atif_get_sbios_requests(acpi_handle handle, ...@@ -290,11 +361,10 @@ static int amdgpu_atif_get_sbios_requests(acpi_handle handle,
* Returns NOTIFY code * Returns NOTIFY code
*/ */
static int amdgpu_atif_handler(struct amdgpu_device *adev, static int amdgpu_atif_handler(struct amdgpu_device *adev,
struct acpi_bus_event *event) struct acpi_bus_event *event)
{ {
struct amdgpu_atif *atif = &adev->atif; struct amdgpu_atif *atif = adev->atif;
struct atif_sbios_requests req; struct atif_sbios_requests req;
acpi_handle handle;
int count; int count;
DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n", DRM_DEBUG_DRIVER("event, device_class = %s, type = %#x\n",
...@@ -303,14 +373,14 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev, ...@@ -303,14 +373,14 @@ static int amdgpu_atif_handler(struct amdgpu_device *adev,
if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0) if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
return NOTIFY_DONE; return NOTIFY_DONE;
if (!atif->notification_cfg.enabled || if (!atif ||
!atif->notification_cfg.enabled ||
event->type != atif->notification_cfg.command_code) event->type != atif->notification_cfg.command_code)
/* Not our event */ /* Not our event */
return NOTIFY_DONE; return NOTIFY_DONE;
/* Check pending SBIOS requests */ /* Check pending SBIOS requests */
handle = ACPI_HANDLE(&adev->pdev->dev); count = amdgpu_atif_get_sbios_requests(atif, &req);
count = amdgpu_atif_get_sbios_requests(handle, &req);
if (count <= 0) if (count <= 0)
return NOTIFY_DONE; return NOTIFY_DONE;
...@@ -641,8 +711,8 @@ static int amdgpu_acpi_event(struct notifier_block *nb, ...@@ -641,8 +711,8 @@ static int amdgpu_acpi_event(struct notifier_block *nb,
*/ */
int amdgpu_acpi_init(struct amdgpu_device *adev) int amdgpu_acpi_init(struct amdgpu_device *adev)
{ {
acpi_handle handle; acpi_handle handle, atif_handle;
struct amdgpu_atif *atif = &adev->atif; struct amdgpu_atif *atif;
struct amdgpu_atcs *atcs = &adev->atcs; struct amdgpu_atcs *atcs = &adev->atcs;
int ret; int ret;
...@@ -658,12 +728,26 @@ int amdgpu_acpi_init(struct amdgpu_device *adev) ...@@ -658,12 +728,26 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret); DRM_DEBUG_DRIVER("Call to ATCS verify_interface failed: %d\n", ret);
} }
/* Probe for ATIF, and initialize it if found */
atif_handle = amdgpu_atif_probe_handle(handle);
if (!atif_handle)
goto out;
atif = kzalloc(sizeof(*atif), GFP_KERNEL);
if (!atif) {
DRM_WARN("Not enough memory to initialize ATIF\n");
goto out;
}
atif->handle = atif_handle;
/* Call the ATIF method */ /* Call the ATIF method */
ret = amdgpu_atif_verify_interface(handle, atif); ret = amdgpu_atif_verify_interface(atif);
if (ret) { if (ret) {
DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret); DRM_DEBUG_DRIVER("Call to ATIF verify_interface failed: %d\n", ret);
kfree(atif);
goto out; goto out;
} }
adev->atif = atif;
if (atif->notifications.brightness_change) { if (atif->notifications.brightness_change) {
struct drm_encoder *tmp; struct drm_encoder *tmp;
...@@ -693,8 +777,7 @@ int amdgpu_acpi_init(struct amdgpu_device *adev) ...@@ -693,8 +777,7 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
} }
if (atif->functions.system_params) { if (atif->functions.system_params) {
ret = amdgpu_atif_get_notification_params(handle, ret = amdgpu_atif_get_notification_params(atif);
&atif->notification_cfg);
if (ret) { if (ret) {
DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n", DRM_DEBUG_DRIVER("Call to GET_SYSTEM_PARAMS failed: %d\n",
ret); ret);
...@@ -720,4 +803,6 @@ int amdgpu_acpi_init(struct amdgpu_device *adev) ...@@ -720,4 +803,6 @@ int amdgpu_acpi_init(struct amdgpu_device *adev)
void amdgpu_acpi_fini(struct amdgpu_device *adev) void amdgpu_acpi_fini(struct amdgpu_device *adev)
{ {
unregister_acpi_notifier(&adev->acpi_nb); unregister_acpi_notifier(&adev->acpi_nb);
if (adev->atif)
kfree(adev->atif);
} }
...@@ -90,6 +90,12 @@ bool amdgpu_atpx_dgpu_req_power_for_displays(void) { ...@@ -90,6 +90,12 @@ bool amdgpu_atpx_dgpu_req_power_for_displays(void) {
return amdgpu_atpx_priv.atpx.dgpu_req_power_for_displays; return amdgpu_atpx_priv.atpx.dgpu_req_power_for_displays;
} }
#if defined(CONFIG_ACPI)
void *amdgpu_atpx_get_dhandle(void) {
return amdgpu_atpx_priv.dhandle;
}
#endif
/** /**
* amdgpu_atpx_call - call an ATPX method * amdgpu_atpx_call - call an ATPX method
* *
......
...@@ -231,6 +231,12 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ...@@ -231,6 +231,12 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
if (ib->flags & AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE) if (ib->flags & AMDGPU_IB_FLAG_TC_WB_NOT_INVALIDATE)
fence_flags |= AMDGPU_FENCE_FLAG_TC_WB_ONLY; fence_flags |= AMDGPU_FENCE_FLAG_TC_WB_ONLY;
/* wrap the last IB with fence */
if (job && job->uf_addr) {
amdgpu_ring_emit_fence(ring, job->uf_addr, job->uf_sequence,
fence_flags | AMDGPU_FENCE_FLAG_64BIT);
}
r = amdgpu_fence_emit(ring, f, fence_flags); r = amdgpu_fence_emit(ring, f, fence_flags);
if (r) { if (r) {
dev_err(adev->dev, "failed to emit fence (%d)\n", r); dev_err(adev->dev, "failed to emit fence (%d)\n", r);
...@@ -243,12 +249,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs, ...@@ -243,12 +249,6 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
if (ring->funcs->insert_end) if (ring->funcs->insert_end)
ring->funcs->insert_end(ring); ring->funcs->insert_end(ring);
/* wrap the last IB with fence */
if (job && job->uf_addr) {
amdgpu_ring_emit_fence(ring, job->uf_addr, job->uf_sequence,
fence_flags | AMDGPU_FENCE_FLAG_64BIT);
}
if (patch_offset != ~0 && ring->funcs->patch_cond_exec) if (patch_offset != ~0 && ring->funcs->patch_cond_exec)
amdgpu_ring_patch_cond_exec(ring, patch_offset); amdgpu_ring_patch_cond_exec(ring, patch_offset);
......
...@@ -1882,7 +1882,7 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev) ...@@ -1882,7 +1882,7 @@ void amdgpu_pm_compute_clocks(struct amdgpu_device *adev)
if (!amdgpu_device_has_dc_support(adev)) { if (!amdgpu_device_has_dc_support(adev)) {
mutex_lock(&adev->pm.mutex); mutex_lock(&adev->pm.mutex);
amdgpu_dpm_get_active_displays(adev); amdgpu_dpm_get_active_displays(adev);
adev->pm.pm_display_cfg.num_display = adev->pm.dpm.new_active_crtcs; adev->pm.pm_display_cfg.num_display = adev->pm.dpm.new_active_crtc_count;
adev->pm.pm_display_cfg.vrefresh = amdgpu_dpm_get_vrefresh(adev); adev->pm.pm_display_cfg.vrefresh = amdgpu_dpm_get_vrefresh(adev);
adev->pm.pm_display_cfg.min_vblank_time = amdgpu_dpm_get_vblank_time(adev); adev->pm.pm_display_cfg.min_vblank_time = amdgpu_dpm_get_vblank_time(adev);
/* we have issues with mclk switching with refresh rates over 120 hz on the non-DC code. */ /* we have issues with mclk switching with refresh rates over 120 hz on the non-DC code. */
......
...@@ -900,7 +900,7 @@ static const struct amdgpu_ring_funcs vce_v3_0_ring_phys_funcs = { ...@@ -900,7 +900,7 @@ static const struct amdgpu_ring_funcs vce_v3_0_ring_phys_funcs = {
.emit_frame_size = .emit_frame_size =
4 + /* vce_v3_0_emit_pipeline_sync */ 4 + /* vce_v3_0_emit_pipeline_sync */
6, /* amdgpu_vce_ring_emit_fence x1 no user fence */ 6, /* amdgpu_vce_ring_emit_fence x1 no user fence */
.emit_ib_size = 5, /* vce_v3_0_ring_emit_ib */ .emit_ib_size = 4, /* amdgpu_vce_ring_emit_ib */
.emit_ib = amdgpu_vce_ring_emit_ib, .emit_ib = amdgpu_vce_ring_emit_ib,
.emit_fence = amdgpu_vce_ring_emit_fence, .emit_fence = amdgpu_vce_ring_emit_fence,
.test_ring = amdgpu_vce_ring_test_ring, .test_ring = amdgpu_vce_ring_test_ring,
...@@ -924,7 +924,7 @@ static const struct amdgpu_ring_funcs vce_v3_0_ring_vm_funcs = { ...@@ -924,7 +924,7 @@ static const struct amdgpu_ring_funcs vce_v3_0_ring_vm_funcs = {
6 + /* vce_v3_0_emit_vm_flush */ 6 + /* vce_v3_0_emit_vm_flush */
4 + /* vce_v3_0_emit_pipeline_sync */ 4 + /* vce_v3_0_emit_pipeline_sync */
6 + 6, /* amdgpu_vce_ring_emit_fence x2 vm fence */ 6 + 6, /* amdgpu_vce_ring_emit_fence x2 vm fence */
.emit_ib_size = 4, /* amdgpu_vce_ring_emit_ib */ .emit_ib_size = 5, /* vce_v3_0_ring_emit_ib */
.emit_ib = vce_v3_0_ring_emit_ib, .emit_ib = vce_v3_0_ring_emit_ib,
.emit_vm_flush = vce_v3_0_emit_vm_flush, .emit_vm_flush = vce_v3_0_emit_vm_flush,
.emit_pipeline_sync = vce_v3_0_emit_pipeline_sync, .emit_pipeline_sync = vce_v3_0_emit_pipeline_sync,
......
...@@ -2175,6 +2175,46 @@ get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing) ...@@ -2175,6 +2175,46 @@ get_output_color_space(const struct dc_crtc_timing *dc_crtc_timing)
return color_space; return color_space;
} }
static void reduce_mode_colour_depth(struct dc_crtc_timing *timing_out)
{
if (timing_out->display_color_depth <= COLOR_DEPTH_888)
return;
timing_out->display_color_depth--;
}
static void adjust_colour_depth_from_display_info(struct dc_crtc_timing *timing_out,
const struct drm_display_info *info)
{
int normalized_clk;
if (timing_out->display_color_depth <= COLOR_DEPTH_888)
return;
do {
normalized_clk = timing_out->pix_clk_khz;
/* YCbCr 4:2:0 requires additional adjustment of 1/2 */
if (timing_out->pixel_encoding == PIXEL_ENCODING_YCBCR420)
normalized_clk /= 2;
/* Adjusting pix clock following on HDMI spec based on colour depth */
switch (timing_out->display_color_depth) {
case COLOR_DEPTH_101010:
normalized_clk = (normalized_clk * 30) / 24;
break;
case COLOR_DEPTH_121212:
normalized_clk = (normalized_clk * 36) / 24;
break;
case COLOR_DEPTH_161616:
normalized_clk = (normalized_clk * 48) / 24;
break;
default:
return;
}
if (normalized_clk <= info->max_tmds_clock)
return;
reduce_mode_colour_depth(timing_out);
} while (timing_out->display_color_depth > COLOR_DEPTH_888);
}
/*****************************************************************************/ /*****************************************************************************/
static void static void
...@@ -2183,6 +2223,7 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream, ...@@ -2183,6 +2223,7 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream,
const struct drm_connector *connector) const struct drm_connector *connector)
{ {
struct dc_crtc_timing *timing_out = &stream->timing; struct dc_crtc_timing *timing_out = &stream->timing;
const struct drm_display_info *info = &connector->display_info;
memset(timing_out, 0, sizeof(struct dc_crtc_timing)); memset(timing_out, 0, sizeof(struct dc_crtc_timing));
...@@ -2191,8 +2232,10 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream, ...@@ -2191,8 +2232,10 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream,
timing_out->v_border_top = 0; timing_out->v_border_top = 0;
timing_out->v_border_bottom = 0; timing_out->v_border_bottom = 0;
/* TODO: un-hardcode */ /* TODO: un-hardcode */
if (drm_mode_is_420_only(info, mode_in)
if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB444) && stream->sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A)
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR420;
else if ((connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB444)
&& stream->sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A) && stream->sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A)
timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR444; timing_out->pixel_encoding = PIXEL_ENCODING_YCBCR444;
else else
...@@ -2228,6 +2271,8 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream, ...@@ -2228,6 +2271,8 @@ fill_stream_properties_from_drm_display_mode(struct dc_stream_state *stream,
stream->out_transfer_func->type = TF_TYPE_PREDEFINED; stream->out_transfer_func->type = TF_TYPE_PREDEFINED;
stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB; stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB;
if (stream->sink->sink_signal == SIGNAL_TYPE_HDMI_TYPE_A)
adjust_colour_depth_from_display_info(timing_out, info);
} }
static void fill_audio_info(struct audio_info *audio_info, static void fill_audio_info(struct audio_info *audio_info,
......
...@@ -1433,7 +1433,10 @@ struct atom_smc_dpm_info_v4_1 ...@@ -1433,7 +1433,10 @@ struct atom_smc_dpm_info_v4_1
uint8_t acggfxclkspreadpercent; uint8_t acggfxclkspreadpercent;
uint16_t acggfxclkspreadfreq; uint16_t acggfxclkspreadfreq;
uint32_t boardreserved[10]; uint8_t Vr2_I2C_address;
uint8_t padding_vr2[3];
uint32_t boardreserved[9];
}; };
/* /*
......
...@@ -512,14 +512,82 @@ int pp_atomfwctrl_get_clk_information_by_clkid(struct pp_hwmgr *hwmgr, BIOS_CLKI ...@@ -512,14 +512,82 @@ int pp_atomfwctrl_get_clk_information_by_clkid(struct pp_hwmgr *hwmgr, BIOS_CLKI
return 0; return 0;
} }
static void pp_atomfwctrl_copy_vbios_bootup_values_3_2(struct pp_hwmgr *hwmgr,
struct pp_atomfwctrl_bios_boot_up_values *boot_values,
struct atom_firmware_info_v3_2 *fw_info)
{
uint32_t frequency = 0;
boot_values->ulRevision = fw_info->firmware_revision;
boot_values->ulGfxClk = fw_info->bootup_sclk_in10khz;
boot_values->ulUClk = fw_info->bootup_mclk_in10khz;
boot_values->usVddc = fw_info->bootup_vddc_mv;
boot_values->usVddci = fw_info->bootup_vddci_mv;
boot_values->usMvddc = fw_info->bootup_mvddc_mv;
boot_values->usVddGfx = fw_info->bootup_vddgfx_mv;
boot_values->ucCoolingID = fw_info->coolingsolution_id;
boot_values->ulSocClk = 0;
boot_values->ulDCEFClk = 0;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_SOCCLK_ID, &frequency))
boot_values->ulSocClk = frequency;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCEFCLK_ID, &frequency))
boot_values->ulDCEFClk = frequency;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_ECLK_ID, &frequency))
boot_values->ulEClk = frequency;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_VCLK_ID, &frequency))
boot_values->ulVClk = frequency;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU11_SYSPLL0_DCLK_ID, &frequency))
boot_values->ulDClk = frequency;
}
static void pp_atomfwctrl_copy_vbios_bootup_values_3_1(struct pp_hwmgr *hwmgr,
struct pp_atomfwctrl_bios_boot_up_values *boot_values,
struct atom_firmware_info_v3_1 *fw_info)
{
uint32_t frequency = 0;
boot_values->ulRevision = fw_info->firmware_revision;
boot_values->ulGfxClk = fw_info->bootup_sclk_in10khz;
boot_values->ulUClk = fw_info->bootup_mclk_in10khz;
boot_values->usVddc = fw_info->bootup_vddc_mv;
boot_values->usVddci = fw_info->bootup_vddci_mv;
boot_values->usMvddc = fw_info->bootup_mvddc_mv;
boot_values->usVddGfx = fw_info->bootup_vddgfx_mv;
boot_values->ucCoolingID = fw_info->coolingsolution_id;
boot_values->ulSocClk = 0;
boot_values->ulDCEFClk = 0;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_SOCCLK_ID, &frequency))
boot_values->ulSocClk = frequency;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCEFCLK_ID, &frequency))
boot_values->ulDCEFClk = frequency;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_ECLK_ID, &frequency))
boot_values->ulEClk = frequency;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_VCLK_ID, &frequency))
boot_values->ulVClk = frequency;
if (!pp_atomfwctrl_get_clk_information_by_clkid(hwmgr, SMU9_SYSPLL0_DCLK_ID, &frequency))
boot_values->ulDClk = frequency;
}
int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr, int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr,
struct pp_atomfwctrl_bios_boot_up_values *boot_values) struct pp_atomfwctrl_bios_boot_up_values *boot_values)
{ {
struct atom_firmware_info_v3_1 *info = NULL; struct atom_firmware_info_v3_2 *fwinfo_3_2;
struct atom_firmware_info_v3_1 *fwinfo_3_1;
struct atom_common_table_header *info = NULL;
uint16_t ix; uint16_t ix;
ix = GetIndexIntoMasterDataTable(firmwareinfo); ix = GetIndexIntoMasterDataTable(firmwareinfo);
info = (struct atom_firmware_info_v3_1 *) info = (struct atom_common_table_header *)
smu_atom_get_data_table(hwmgr->adev, smu_atom_get_data_table(hwmgr->adev,
ix, NULL, NULL, NULL); ix, NULL, NULL, NULL);
...@@ -528,16 +596,18 @@ int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr, ...@@ -528,16 +596,18 @@ int pp_atomfwctrl_get_vbios_bootup_values(struct pp_hwmgr *hwmgr,
return -EINVAL; return -EINVAL;
} }
boot_values->ulRevision = info->firmware_revision; if ((info->format_revision == 3) && (info->content_revision == 2)) {
boot_values->ulGfxClk = info->bootup_sclk_in10khz; fwinfo_3_2 = (struct atom_firmware_info_v3_2 *)info;
boot_values->ulUClk = info->bootup_mclk_in10khz; pp_atomfwctrl_copy_vbios_bootup_values_3_2(hwmgr,
boot_values->usVddc = info->bootup_vddc_mv; boot_values, fwinfo_3_2);
boot_values->usVddci = info->bootup_vddci_mv; } else if ((info->format_revision == 3) && (info->content_revision == 1)) {
boot_values->usMvddc = info->bootup_mvddc_mv; fwinfo_3_1 = (struct atom_firmware_info_v3_1 *)info;
boot_values->usVddGfx = info->bootup_vddgfx_mv; pp_atomfwctrl_copy_vbios_bootup_values_3_1(hwmgr,
boot_values->ucCoolingID = info->coolingsolution_id; boot_values, fwinfo_3_1);
boot_values->ulSocClk = 0; } else {
boot_values->ulDCEFClk = 0; pr_info("Fw info table revision does not match!");
return -EINVAL;
}
return 0; return 0;
} }
...@@ -629,5 +699,7 @@ int pp_atomfwctrl_get_smc_dpm_information(struct pp_hwmgr *hwmgr, ...@@ -629,5 +699,7 @@ int pp_atomfwctrl_get_smc_dpm_information(struct pp_hwmgr *hwmgr,
param->acggfxclkspreadpercent = info->acggfxclkspreadpercent; param->acggfxclkspreadpercent = info->acggfxclkspreadpercent;
param->acggfxclkspreadfreq = info->acggfxclkspreadfreq; param->acggfxclkspreadfreq = info->acggfxclkspreadfreq;
param->Vr2_I2C_address = info->Vr2_I2C_address;
return 0; return 0;
} }
...@@ -136,6 +136,9 @@ struct pp_atomfwctrl_bios_boot_up_values { ...@@ -136,6 +136,9 @@ struct pp_atomfwctrl_bios_boot_up_values {
uint32_t ulUClk; uint32_t ulUClk;
uint32_t ulSocClk; uint32_t ulSocClk;
uint32_t ulDCEFClk; uint32_t ulDCEFClk;
uint32_t ulEClk;
uint32_t ulVClk;
uint32_t ulDClk;
uint16_t usVddc; uint16_t usVddc;
uint16_t usVddci; uint16_t usVddci;
uint16_t usMvddc; uint16_t usMvddc;
...@@ -207,6 +210,8 @@ struct pp_atomfwctrl_smc_dpm_parameters ...@@ -207,6 +210,8 @@ struct pp_atomfwctrl_smc_dpm_parameters
uint8_t acggfxclkspreadenabled; uint8_t acggfxclkspreadenabled;
uint8_t acggfxclkspreadpercent; uint8_t acggfxclkspreadpercent;
uint16_t acggfxclkspreadfreq; uint16_t acggfxclkspreadfreq;
uint8_t Vr2_I2C_address;
}; };
int pp_atomfwctrl_get_gpu_pll_dividers_vega10(struct pp_hwmgr *hwmgr, int pp_atomfwctrl_get_gpu_pll_dividers_vega10(struct pp_hwmgr *hwmgr,
......
...@@ -81,6 +81,7 @@ static void vega12_set_default_registry_data(struct pp_hwmgr *hwmgr) ...@@ -81,6 +81,7 @@ static void vega12_set_default_registry_data(struct pp_hwmgr *hwmgr)
data->registry_data.disallowed_features = 0x0; data->registry_data.disallowed_features = 0x0;
data->registry_data.od_state_in_dc_support = 0; data->registry_data.od_state_in_dc_support = 0;
data->registry_data.thermal_support = 1;
data->registry_data.skip_baco_hardware = 0; data->registry_data.skip_baco_hardware = 0;
data->registry_data.log_avfs_param = 0; data->registry_data.log_avfs_param = 0;
...@@ -803,6 +804,9 @@ static int vega12_init_smc_table(struct pp_hwmgr *hwmgr) ...@@ -803,6 +804,9 @@ static int vega12_init_smc_table(struct pp_hwmgr *hwmgr)
data->vbios_boot_state.soc_clock = boot_up_values.ulSocClk; data->vbios_boot_state.soc_clock = boot_up_values.ulSocClk;
data->vbios_boot_state.dcef_clock = boot_up_values.ulDCEFClk; data->vbios_boot_state.dcef_clock = boot_up_values.ulDCEFClk;
data->vbios_boot_state.uc_cooling_id = boot_up_values.ucCoolingID; data->vbios_boot_state.uc_cooling_id = boot_up_values.ucCoolingID;
data->vbios_boot_state.eclock = boot_up_values.ulEClk;
data->vbios_boot_state.dclock = boot_up_values.ulDClk;
data->vbios_boot_state.vclock = boot_up_values.ulVClk;
smum_send_msg_to_smc_with_parameter(hwmgr, smum_send_msg_to_smc_with_parameter(hwmgr,
PPSMC_MSG_SetMinDeepSleepDcefclk, PPSMC_MSG_SetMinDeepSleepDcefclk,
(uint32_t)(data->vbios_boot_state.dcef_clock / 100)); (uint32_t)(data->vbios_boot_state.dcef_clock / 100));
......
...@@ -167,6 +167,9 @@ struct vega12_vbios_boot_state { ...@@ -167,6 +167,9 @@ struct vega12_vbios_boot_state {
uint32_t mem_clock; uint32_t mem_clock;
uint32_t soc_clock; uint32_t soc_clock;
uint32_t dcef_clock; uint32_t dcef_clock;
uint32_t eclock;
uint32_t dclock;
uint32_t vclock;
}; };
#define DPMTABLE_OD_UPDATE_SCLK 0x00000001 #define DPMTABLE_OD_UPDATE_SCLK 0x00000001
......
...@@ -230,6 +230,8 @@ static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable ...@@ -230,6 +230,8 @@ static int append_vbios_pptable(struct pp_hwmgr *hwmgr, PPTable_t *ppsmc_pptable
ppsmc_pptable->AcgThresholdFreqLow = 0xFFFF; ppsmc_pptable->AcgThresholdFreqLow = 0xFFFF;
} }
ppsmc_pptable->Vr2_I2C_address = smc_dpm_table.Vr2_I2C_address;
return 0; return 0;
} }
......
...@@ -499,7 +499,10 @@ typedef struct { ...@@ -499,7 +499,10 @@ typedef struct {
uint8_t AcgGfxclkSpreadPercent; uint8_t AcgGfxclkSpreadPercent;
uint16_t AcgGfxclkSpreadFreq; uint16_t AcgGfxclkSpreadFreq;
uint32_t BoardReserved[10]; uint8_t Vr2_I2C_address;
uint8_t padding_vr2[3];
uint32_t BoardReserved[9];
uint32_t MmHubPadding[7]; uint32_t MmHubPadding[7];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册