Skip to content

Commit

Permalink
Merge tag 'drm-fixes-for-v4.17-rc2' of git://people.freedesktop.org/~…
Browse files Browse the repository at this point in the history
…airlied/linux

Pull drm fixes from Dave Airlie:
 "Exynos, i915, vc4, amdgpu fixes.

  i915:
   - an oops fix
   - two race fixes
   - some gvt fixes

  amdgpu:
   - dark screen fix
   - clk/voltage fix
   - vega12 smu fix

  vc4:
   - memory leak fix

  exynos just drops some code"

* tag 'drm-fixes-for-v4.17-rc2' of git://people.freedesktop.org/~airlied/linux: (23 commits)
  drm/amd/powerplay: header file interface to SMU update
  drm/amd/pp: Fix bug voltage can't be OD separately on VI
  drm/amd/display: Don't program bypass on linear regamma LUT
  drm/i915: Fix LSPCON TMDS output buffer enabling from low-power state
  drm/i915/audio: Fix audio detection issue on GLK
  drm/i915: Call i915_perf_fini() on init_hw error unwind
  drm/i915/bios: filter out invalid DDC pins from VBT child devices
  drm/i915/pmu: Inspect runtime PM state more carefully while estimating RC6
  drm/i915: Do no use kfree() to free a kmem_cache_alloc() return value
  drm/exynos: exynos_drm_fb -> drm_framebuffer
  drm/exynos: Move dma_addr out of exynos_drm_fb
  drm/exynos: Move GEM BOs to drm_framebuffer
  drm: Fix HDCP downstream dev count read
  drm/vc4: Fix memory leak during BO teardown
  drm/i915/execlists: Clear user-active flag on preemption completion
  drm/i915/gvt: Add drm_format_mod update
  drm/i915/gvt: Disable primary/sprite/cursor plane at virtual display initialization
  drm/i915/gvt: Delete redundant error message in fb_decode.c
  drm/i915/gvt: Cancel dma map when resetting ggtt entries
  drm/i915/gvt: Missed to cancel dma map for ggtt entries
  ...
  • Loading branch information
Linus Torvalds committed Apr 23, 2018
2 parents 5ec83b2 + 221bda4 commit 867ab4b
Show file tree
Hide file tree
Showing 22 changed files with 194 additions and 136 deletions.
7 changes: 0 additions & 7 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,6 @@ int amdgpu_dm_set_regamma_lut(struct dm_crtc_state *crtc)
lut = (struct drm_color_lut *)blob->data;
lut_size = blob->length / sizeof(struct drm_color_lut);

if (__is_lut_linear(lut, lut_size)) {
/* Set to bypass if lut is set to linear */
stream->out_transfer_func->type = TF_TYPE_BYPASS;
stream->out_transfer_func->tf = TRANSFER_FUNCTION_LINEAR;
return 0;
}

gamma = dc_create_gamma();
if (!gamma)
return -ENOMEM;
Expand Down
16 changes: 10 additions & 6 deletions drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -4743,23 +4743,27 @@ static void smu7_check_dpm_table_updated(struct pp_hwmgr *hwmgr)

for (i=0; i < dep_table->count; i++) {
if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {
data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC;
break;
data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_MCLK;
return;
}
}
if (i == dep_table->count)
if (i == dep_table->count && data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_VDDC) {
data->need_update_smu7_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC;
data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
}

dep_table = table_info->vdd_dep_on_sclk;
odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dependency_on_sclk);
for (i=0; i < dep_table->count; i++) {
if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {
data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC;
break;
data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_SCLK;
return;
}
}
if (i == dep_table->count)
if (i == dep_table->count && data->need_update_smu7_dpm_table & DPMTABLE_OD_UPDATE_VDDC) {
data->need_update_smu7_dpm_table &= ~DPMTABLE_OD_UPDATE_VDDC;
data->need_update_smu7_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
}
}

static int smu7_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
Expand Down
4 changes: 3 additions & 1 deletion drivers/gpu/drm/amd/powerplay/inc/vega12/smu9_driver_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -412,8 +412,10 @@ typedef struct {
QuadraticInt_t ReservedEquation2;
QuadraticInt_t ReservedEquation3;

uint16_t MinVoltageUlvGfx;
uint16_t MinVoltageUlvSoc;

uint32_t Reserved[15];
uint32_t Reserved[14];



Expand Down
39 changes: 32 additions & 7 deletions drivers/gpu/drm/drm_dp_dual_mode_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,19 +350,44 @@ int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type,
{
uint8_t tmds_oen = enable ? 0 : DP_DUAL_MODE_TMDS_DISABLE;
ssize_t ret;
int retry;

if (type < DRM_DP_DUAL_MODE_TYPE2_DVI)
return 0;

ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
&tmds_oen, sizeof(tmds_oen));
if (ret) {
DRM_DEBUG_KMS("Failed to %s TMDS output buffers\n",
enable ? "enable" : "disable");
return ret;
/*
* LSPCON adapters in low-power state may ignore the first write, so
* read back and verify the written value a few times.
*/
for (retry = 0; retry < 3; retry++) {
uint8_t tmp;

ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
&tmds_oen, sizeof(tmds_oen));
if (ret) {
DRM_DEBUG_KMS("Failed to %s TMDS output buffers (%d attempts)\n",
enable ? "enable" : "disable",
retry + 1);
return ret;
}

ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_TMDS_OEN,
&tmp, sizeof(tmp));
if (ret) {
DRM_DEBUG_KMS("I2C read failed during TMDS output buffer %s (%d attempts)\n",
enable ? "enabling" : "disabling",
retry + 1);
return ret;
}

if (tmp == tmds_oen)
return 0;
}

return 0;
DRM_DEBUG_KMS("I2C write value mismatch during TMDS output buffer %s\n",
enable ? "enabling" : "disabling");

return -EIO;
}
EXPORT_SYMBOL(drm_dp_dual_mode_set_tmds_output);

Expand Down
73 changes: 14 additions & 59 deletions drivers/gpu/drm/exynos/exynos_drm_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <drm/drm_fb_helper.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <uapi/drm/exynos_drm.h>

#include "exynos_drm_drv.h"
Expand All @@ -26,20 +27,6 @@
#include "exynos_drm_iommu.h"
#include "exynos_drm_crtc.h"

#define to_exynos_fb(x) container_of(x, struct exynos_drm_fb, fb)

/*
* exynos specific framebuffer structure.
*
* @fb: drm framebuffer obejct.
* @exynos_gem: array of exynos specific gem object containing a gem object.
*/
struct exynos_drm_fb {
struct drm_framebuffer fb;
struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER];
dma_addr_t dma_addr[MAX_FB_BUFFER];
};

static int check_fb_gem_memory_type(struct drm_device *drm_dev,
struct exynos_drm_gem *exynos_gem)
{
Expand All @@ -66,40 +53,9 @@ static int check_fb_gem_memory_type(struct drm_device *drm_dev,
return 0;
}

static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
{
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
unsigned int i;

drm_framebuffer_cleanup(fb);

for (i = 0; i < ARRAY_SIZE(exynos_fb->exynos_gem); i++) {
struct drm_gem_object *obj;

if (exynos_fb->exynos_gem[i] == NULL)
continue;

obj = &exynos_fb->exynos_gem[i]->base;
drm_gem_object_unreference_unlocked(obj);
}

kfree(exynos_fb);
exynos_fb = NULL;
}

static int exynos_drm_fb_create_handle(struct drm_framebuffer *fb,
struct drm_file *file_priv,
unsigned int *handle)
{
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);

return drm_gem_handle_create(file_priv,
&exynos_fb->exynos_gem[0]->base, handle);
}

static const struct drm_framebuffer_funcs exynos_drm_fb_funcs = {
.destroy = exynos_drm_fb_destroy,
.create_handle = exynos_drm_fb_create_handle,
.destroy = drm_gem_fb_destroy,
.create_handle = drm_gem_fb_create_handle,
};

struct drm_framebuffer *
Expand All @@ -108,36 +64,34 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
struct exynos_drm_gem **exynos_gem,
int count)
{
struct exynos_drm_fb *exynos_fb;
struct drm_framebuffer *fb;
int i;
int ret;

exynos_fb = kzalloc(sizeof(*exynos_fb), GFP_KERNEL);
if (!exynos_fb)
fb = kzalloc(sizeof(*fb), GFP_KERNEL);
if (!fb)
return ERR_PTR(-ENOMEM);

for (i = 0; i < count; i++) {
ret = check_fb_gem_memory_type(dev, exynos_gem[i]);
if (ret < 0)
goto err;

exynos_fb->exynos_gem[i] = exynos_gem[i];
exynos_fb->dma_addr[i] = exynos_gem[i]->dma_addr
+ mode_cmd->offsets[i];
fb->obj[i] = &exynos_gem[i]->base;
}

drm_helper_mode_fill_fb_struct(dev, &exynos_fb->fb, mode_cmd);
drm_helper_mode_fill_fb_struct(dev, fb, mode_cmd);

ret = drm_framebuffer_init(dev, &exynos_fb->fb, &exynos_drm_fb_funcs);
ret = drm_framebuffer_init(dev, fb, &exynos_drm_fb_funcs);
if (ret < 0) {
DRM_ERROR("failed to initialize framebuffer\n");
goto err;
}

return &exynos_fb->fb;
return fb;

err:
kfree(exynos_fb);
kfree(fb);
return ERR_PTR(ret);
}

Expand Down Expand Up @@ -191,12 +145,13 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,

dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index)
{
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
struct exynos_drm_gem *exynos_gem;

if (WARN_ON_ONCE(index >= MAX_FB_BUFFER))
return 0;

return exynos_fb->dma_addr[index];
exynos_gem = to_exynos_gem(fb->obj[index]);
return exynos_gem->dma_addr + fb->offsets[index];
}

static struct drm_mode_config_helper_funcs exynos_drm_mode_config_helpers = {
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/gvt/cmd_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1080,6 +1080,7 @@ static int cmd_handler_mi_user_interrupt(struct parser_exec_state *s)
{
set_bit(cmd_interrupt_events[s->ring_id].mi_user_interrupt,
s->workload->pending_events);
patch_value(s, cmd_ptr(s, 0), MI_NOOP);
return 0;
}

Expand Down
10 changes: 10 additions & 0 deletions drivers/gpu/drm/i915/gvt/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ static u8 dpcd_fix_data[DPCD_HEADER_SIZE] = {
static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
{
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;
int pipe;

vgpu_vreg_t(vgpu, SDEISR) &= ~(SDE_PORTB_HOTPLUG_CPT |
SDE_PORTC_HOTPLUG_CPT |
SDE_PORTD_HOTPLUG_CPT);
Expand Down Expand Up @@ -267,6 +269,14 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
if (IS_BROADWELL(dev_priv))
vgpu_vreg_t(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK;

/* Disable Primary/Sprite/Cursor plane */
for_each_pipe(dev_priv, pipe) {
vgpu_vreg_t(vgpu, DSPCNTR(pipe)) &= ~DISPLAY_PLANE_ENABLE;
vgpu_vreg_t(vgpu, SPRCTL(pipe)) &= ~SPRITE_ENABLE;
vgpu_vreg_t(vgpu, CURCNTR(pipe)) &= ~CURSOR_MODE;
vgpu_vreg_t(vgpu, CURCNTR(pipe)) |= CURSOR_MODE_DISABLE;
}

vgpu_vreg_t(vgpu, PIPECONF(PIPE_A)) |= PIPECONF_ENABLE;
}

Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/gvt/dmabuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ static void update_fb_info(struct vfio_device_gfx_plane_info *gvt_dmabuf,
struct intel_vgpu_fb_info *fb_info)
{
gvt_dmabuf->drm_format = fb_info->drm_format;
gvt_dmabuf->drm_format_mod = fb_info->drm_format_mod;
gvt_dmabuf->width = fb_info->width;
gvt_dmabuf->height = fb_info->height;
gvt_dmabuf->stride = fb_info->stride;
Expand Down
27 changes: 9 additions & 18 deletions drivers/gpu/drm/i915/gvt/fb_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,16 +245,13 @@ int intel_vgpu_decode_primary_plane(struct intel_vgpu *vgpu,
plane->hw_format = fmt;

plane->base = vgpu_vreg_t(vgpu, DSPSURF(pipe)) & I915_GTT_PAGE_MASK;
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
gvt_vgpu_err("invalid gma address: %lx\n",
(unsigned long)plane->base);
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
return -EINVAL;
}

plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
gvt_vgpu_err("invalid gma address: %lx\n",
(unsigned long)plane->base);
gvt_vgpu_err("Translate primary plane gma 0x%x to gpa fail\n",
plane->base);
return -EINVAL;
}

Expand Down Expand Up @@ -371,16 +368,13 @@ int intel_vgpu_decode_cursor_plane(struct intel_vgpu *vgpu,
alpha_plane, alpha_force);

plane->base = vgpu_vreg_t(vgpu, CURBASE(pipe)) & I915_GTT_PAGE_MASK;
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
gvt_vgpu_err("invalid gma address: %lx\n",
(unsigned long)plane->base);
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
return -EINVAL;
}

plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
gvt_vgpu_err("invalid gma address: %lx\n",
(unsigned long)plane->base);
gvt_vgpu_err("Translate cursor plane gma 0x%x to gpa fail\n",
plane->base);
return -EINVAL;
}

Expand Down Expand Up @@ -476,16 +470,13 @@ int intel_vgpu_decode_sprite_plane(struct intel_vgpu *vgpu,
plane->drm_format = drm_format;

plane->base = vgpu_vreg_t(vgpu, SPRSURF(pipe)) & I915_GTT_PAGE_MASK;
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0)) {
gvt_vgpu_err("invalid gma address: %lx\n",
(unsigned long)plane->base);
if (!intel_gvt_ggtt_validate_range(vgpu, plane->base, 0))
return -EINVAL;
}

plane->base_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm, plane->base);
if (plane->base_gpa == INTEL_GVT_INVALID_ADDR) {
gvt_vgpu_err("invalid gma address: %lx\n",
(unsigned long)plane->base);
gvt_vgpu_err("Translate sprite plane gma 0x%x to gpa fail\n",
plane->base);
return -EINVAL;
}

Expand Down
Loading

0 comments on commit 867ab4b

Please sign in to comment.