Skip to content

Commit

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

Pull drm fixes from Dave Airlie:
 "Intel, amd and mxsfb fixes.

  These are the drm fixes I've collected for rc2. Mostly i915 GVT only
  fixes, along with a single EDID fix, some mxsfb fixes and a few minor
  amd fixes"

* tag 'drm-fixes-for-4.11-rc2' of git://people.freedesktop.org/~airlied/linux: (38 commits)
  drm: mxsfb: Implement drm_panel handling
  drm: mxsfb_crtc: Fix the framebuffer misplacement
  drm: mxsfb: Fix crash when provided invalid DT bindings
  drm: mxsfb: fix pixel clock polarity
  drm: mxsfb: use bus_format to determine LCD bus width
  drm/amdgpu: bump driver version for some new features
  drm/amdgpu: validate paramaters in the gem ioctl
  drm/amd/amdgpu: fix console deadlock if late init failed
  drm/i915/gvt: change some gvt_err to gvt_dbg_cmd
  drm/i915/gvt: protect RO and Rsvd bits of virtual vgpu configuration space
  drm/i915/gvt: handle workload lifecycle properly
  drm/edid: Add EDID_QUIRK_FORCE_8BPC quirk for Rotel RSX-1058
  drm/i915/gvt: fix an error for F_RO flag
  drm/i915/gvt: use pfn_valid for better checking
  drm/i915/gvt: set SFUSE_STRAP properly for vitual monitor detection
  drm/i915/gvt: fix an error for one register
  drm/i915/gvt: add more registers into handlers list
  drm/i915/gvt: have more registers with F_CMD_ACCESS flags set
  drm/i915/gvt: add some new MMIOs to cmd_access white list
  drm/i915/gvt: fix pcode mailbox write emulation of BDW
  ...
  • Loading branch information
Linus Torvalds committed Mar 10, 2017
2 parents baeedc7 + 3f81e13 commit 7c7fba9
Show file tree
Hide file tree
Showing 22 changed files with 768 additions and 264 deletions.
5 changes: 4 additions & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -2094,8 +2094,11 @@ int amdgpu_device_resume(struct drm_device *dev, bool resume, bool fbcon)
}

r = amdgpu_late_init(adev);
if (r)
if (r) {
if (fbcon)
console_unlock();
return r;
}

/* pin cursors */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@
* - 3.7.0 - Add support for VCE clock list packet
* - 3.8.0 - Add support raster config init in the kernel
* - 3.9.0 - Add support for memory query info about VRAM and GTT.
* - 3.10.0 - Add support for new fences ioctl, new gem ioctl flags
*/
#define KMS_DRIVER_MAJOR 3
#define KMS_DRIVER_MINOR 9
#define KMS_DRIVER_MINOR 10
#define KMS_DRIVER_PATCHLEVEL 0

int amdgpu_vram_limit = 0;
Expand Down
21 changes: 21 additions & 0 deletions drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,27 @@ int amdgpu_gem_create_ioctl(struct drm_device *dev, void *data,
bool kernel = false;
int r;

/* reject invalid gem flags */
if (args->in.domain_flags & ~(AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
AMDGPU_GEM_CREATE_NO_CPU_ACCESS |
AMDGPU_GEM_CREATE_CPU_GTT_USWC |
AMDGPU_GEM_CREATE_VRAM_CLEARED|
AMDGPU_GEM_CREATE_SHADOW |
AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS)) {
r = -EINVAL;
goto error_unlock;
}
/* reject invalid gem domains */
if (args->in.domains & ~(AMDGPU_GEM_DOMAIN_CPU |
AMDGPU_GEM_DOMAIN_GTT |
AMDGPU_GEM_DOMAIN_VRAM |
AMDGPU_GEM_DOMAIN_GDS |
AMDGPU_GEM_DOMAIN_GWS |
AMDGPU_GEM_DOMAIN_OA)) {
r = -EINVAL;
goto error_unlock;
}

/* create a gem object to contain this object in */
if (args->in.domains & (AMDGPU_GEM_DOMAIN_GDS |
AMDGPU_GEM_DOMAIN_GWS | AMDGPU_GEM_DOMAIN_OA)) {
Expand Down
3 changes: 3 additions & 0 deletions drivers/gpu/drm/drm_edid.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ static const struct edid_quirk {

/* Panel in Samsung NP700G7A-S01PL notebook reports 6bpc */
{ "SEC", 0xd033, EDID_QUIRK_FORCE_8BPC },

/* Rotel RSX-1058 forwards sink's EDID but only does HDMI 1.1*/
{ "ETR", 13896, EDID_QUIRK_FORCE_8BPC },
};

/*
Expand Down
57 changes: 54 additions & 3 deletions drivers/gpu/drm/i915/gvt/cfg_space.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,54 @@ enum {
INTEL_GVT_PCI_BAR_MAX,
};

/* bitmap for writable bits (RW or RW1C bits, but cannot co-exist in one
* byte) byte by byte in standard pci configuration space. (not the full
* 256 bytes.)
*/
static const u8 pci_cfg_space_rw_bmp[PCI_INTERRUPT_LINE + 4] = {
[PCI_COMMAND] = 0xff, 0x07,
[PCI_STATUS] = 0x00, 0xf9, /* the only one RW1C byte */
[PCI_CACHE_LINE_SIZE] = 0xff,
[PCI_BASE_ADDRESS_0 ... PCI_CARDBUS_CIS - 1] = 0xff,
[PCI_ROM_ADDRESS] = 0x01, 0xf8, 0xff, 0xff,
[PCI_INTERRUPT_LINE] = 0xff,
};

/**
* vgpu_pci_cfg_mem_write - write virtual cfg space memory
*
* Use this function to write virtual cfg space memory.
* For standard cfg space, only RW bits can be changed,
* and we emulates the RW1C behavior of PCI_STATUS register.
*/
static void vgpu_pci_cfg_mem_write(struct intel_vgpu *vgpu, unsigned int off,
u8 *src, unsigned int bytes)
{
u8 *cfg_base = vgpu_cfg_space(vgpu);
u8 mask, new, old;
int i = 0;

for (; i < bytes && (off + i < sizeof(pci_cfg_space_rw_bmp)); i++) {
mask = pci_cfg_space_rw_bmp[off + i];
old = cfg_base[off + i];
new = src[i] & mask;

/**
* The PCI_STATUS high byte has RW1C bits, here
* emulates clear by writing 1 for these bits.
* Writing a 0b to RW1C bits has no effect.
*/
if (off + i == PCI_STATUS + 1)
new = (~new & old) & mask;

cfg_base[off + i] = (old & ~mask) | new;
}

/* For other configuration space directly copy as it is. */
if (i < bytes)
memcpy(cfg_base + off + i, src + i, bytes - i);
}

/**
* intel_vgpu_emulate_cfg_read - emulate vGPU configuration space read
*
Expand Down Expand Up @@ -123,7 +171,7 @@ static int emulate_pci_command_write(struct intel_vgpu *vgpu,
u8 changed = old ^ new;
int ret;

memcpy(vgpu_cfg_space(vgpu) + offset, p_data, bytes);
vgpu_pci_cfg_mem_write(vgpu, offset, p_data, bytes);
if (!(changed & PCI_COMMAND_MEMORY))
return 0;

Expand Down Expand Up @@ -237,6 +285,9 @@ int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset,
{
int ret;

if (vgpu->failsafe)
return 0;

if (WARN_ON(bytes > 4))
return -EINVAL;

Expand Down Expand Up @@ -274,10 +325,10 @@ int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset,
if (ret)
return ret;

memcpy(vgpu_cfg_space(vgpu) + offset, p_data, bytes);
vgpu_pci_cfg_mem_write(vgpu, offset, p_data, bytes);
break;
default:
memcpy(vgpu_cfg_space(vgpu) + offset, p_data, bytes);
vgpu_pci_cfg_mem_write(vgpu, offset, p_data, bytes);
break;
}
return 0;
Expand Down
10 changes: 5 additions & 5 deletions drivers/gpu/drm/i915/gvt/cmd_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ static inline void print_opcode(u32 cmd, int ring_id)
if (d_info == NULL)
return;

gvt_err("opcode=0x%x %s sub_ops:",
gvt_dbg_cmd("opcode=0x%x %s sub_ops:",
cmd >> (32 - d_info->op_len), d_info->name);

for (i = 0; i < d_info->nr_sub_op; i++)
Expand All @@ -693,23 +693,23 @@ static void parser_exec_state_dump(struct parser_exec_state *s)
int cnt = 0;
int i;

gvt_err(" vgpu%d RING%d: ring_start(%08lx) ring_end(%08lx)"
gvt_dbg_cmd(" vgpu%d RING%d: ring_start(%08lx) ring_end(%08lx)"
" ring_head(%08lx) ring_tail(%08lx)\n", s->vgpu->id,
s->ring_id, s->ring_start, s->ring_start + s->ring_size,
s->ring_head, s->ring_tail);

gvt_err(" %s %s ip_gma(%08lx) ",
gvt_dbg_cmd(" %s %s ip_gma(%08lx) ",
s->buf_type == RING_BUFFER_INSTRUCTION ?
"RING_BUFFER" : "BATCH_BUFFER",
s->buf_addr_type == GTT_BUFFER ?
"GTT" : "PPGTT", s->ip_gma);

if (s->ip_va == NULL) {
gvt_err(" ip_va(NULL)");
gvt_dbg_cmd(" ip_va(NULL)");
return;
}

gvt_err(" ip_va=%p: %08x %08x %08x %08x\n",
gvt_dbg_cmd(" ip_va=%p: %08x %08x %08x %08x\n",
s->ip_va, cmd_val(s, 0), cmd_val(s, 1),
cmd_val(s, 2), cmd_val(s, 3));

Expand Down
139 changes: 94 additions & 45 deletions drivers/gpu/drm/i915/gvt/display.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,44 +83,80 @@ static int pipe_is_enabled(struct intel_vgpu *vgpu, int pipe)
return 0;
}

static unsigned char virtual_dp_monitor_edid[GVT_EDID_NUM][EDID_SIZE] = {
{
/* EDID with 1024x768 as its resolution */
/*Header*/
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
/* Vendor & Product Identification */
0x22, 0xf0, 0x54, 0x29, 0x00, 0x00, 0x00, 0x00, 0x04, 0x17,
/* Version & Revision */
0x01, 0x04,
/* Basic Display Parameters & Features */
0xa5, 0x34, 0x20, 0x78, 0x23,
/* Color Characteristics */
0xfc, 0x81, 0xa4, 0x55, 0x4d, 0x9d, 0x25, 0x12, 0x50, 0x54,
/* Established Timings: maximum resolution is 1024x768 */
0x21, 0x08, 0x00,
/* Standard Timings. All invalid */
0x00, 0xc0, 0x00, 0xc0, 0x00, 0x40, 0x00, 0x80, 0x00, 0x00,
0x00, 0x40, 0x00, 0x00, 0x00, 0x01,
/* 18 Byte Data Blocks 1: invalid */
0x00, 0x00, 0x80, 0xa0, 0x70, 0xb0,
0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x1a,
/* 18 Byte Data Blocks 2: invalid */
0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x3c, 0x18, 0x50, 0x11, 0x00, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/* 18 Byte Data Blocks 3: invalid */
0x00, 0x00, 0x00, 0xfc, 0x00, 0x48,
0x50, 0x20, 0x5a, 0x52, 0x32, 0x34, 0x34, 0x30, 0x77, 0x0a, 0x20, 0x20,
/* 18 Byte Data Blocks 4: invalid */
0x00, 0x00, 0x00, 0xff, 0x00, 0x43, 0x4e, 0x34, 0x33, 0x30, 0x34, 0x30,
0x44, 0x58, 0x51, 0x0a, 0x20, 0x20,
/* Extension Block Count */
0x00,
/* Checksum */
0xef,
},
{
/* EDID with 1920x1200 as its resolution */
static unsigned char virtual_dp_monitor_edid[] = {
/*Header*/
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
/* Vendor & Product Identification */
0x22, 0xf0, 0x54, 0x29, 0x00, 0x00, 0x00, 0x00, 0x04, 0x17,
/* Version & Revision */
0x01, 0x04,
/* Basic Display Parameters & Features */
0xa5, 0x34, 0x20, 0x78, 0x23,
/* Color Characteristics */
0xfc, 0x81, 0xa4, 0x55, 0x4d, 0x9d, 0x25, 0x12, 0x50, 0x54,
/* Established Timings: maximum resolution is 1024x768 */
0x21, 0x08, 0x00,
/*
* Standard Timings.
* below new resolutions can be supported:
* 1920x1080, 1280x720, 1280x960, 1280x1024,
* 1440x900, 1600x1200, 1680x1050
*/
0xd1, 0xc0, 0x81, 0xc0, 0x81, 0x40, 0x81, 0x80, 0x95, 0x00,
0xa9, 0x40, 0xb3, 0x00, 0x01, 0x01,
/* 18 Byte Data Blocks 1: max resolution is 1920x1200 */
0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0,
0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x1a,
/* 18 Byte Data Blocks 2: invalid */
0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x3c, 0x18, 0x50, 0x11, 0x00, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/* 18 Byte Data Blocks 3: invalid */
0x00, 0x00, 0x00, 0xfc, 0x00, 0x48,
0x50, 0x20, 0x5a, 0x52, 0x32, 0x34, 0x34, 0x30, 0x77, 0x0a, 0x20, 0x20,
/* 18 Byte Data Blocks 4: invalid */
0x00, 0x00, 0x00, 0xff, 0x00, 0x43, 0x4e, 0x34, 0x33, 0x30, 0x34, 0x30,
0x44, 0x58, 0x51, 0x0a, 0x20, 0x20,
/* Extension Block Count */
0x00,
/* Checksum */
0x45,
/*Header*/
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
/* Vendor & Product Identification */
0x22, 0xf0, 0x54, 0x29, 0x00, 0x00, 0x00, 0x00, 0x04, 0x17,
/* Version & Revision */
0x01, 0x04,
/* Basic Display Parameters & Features */
0xa5, 0x34, 0x20, 0x78, 0x23,
/* Color Characteristics */
0xfc, 0x81, 0xa4, 0x55, 0x4d, 0x9d, 0x25, 0x12, 0x50, 0x54,
/* Established Timings: maximum resolution is 1024x768 */
0x21, 0x08, 0x00,
/*
* Standard Timings.
* below new resolutions can be supported:
* 1920x1080, 1280x720, 1280x960, 1280x1024,
* 1440x900, 1600x1200, 1680x1050
*/
0xd1, 0xc0, 0x81, 0xc0, 0x81, 0x40, 0x81, 0x80, 0x95, 0x00,
0xa9, 0x40, 0xb3, 0x00, 0x01, 0x01,
/* 18 Byte Data Blocks 1: max resolution is 1920x1200 */
0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0,
0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x06, 0x44, 0x21, 0x00, 0x00, 0x1a,
/* 18 Byte Data Blocks 2: invalid */
0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x3c, 0x18, 0x50, 0x11, 0x00, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
/* 18 Byte Data Blocks 3: invalid */
0x00, 0x00, 0x00, 0xfc, 0x00, 0x48,
0x50, 0x20, 0x5a, 0x52, 0x32, 0x34, 0x34, 0x30, 0x77, 0x0a, 0x20, 0x20,
/* 18 Byte Data Blocks 4: invalid */
0x00, 0x00, 0x00, 0xff, 0x00, 0x43, 0x4e, 0x34, 0x33, 0x30, 0x34, 0x30,
0x44, 0x58, 0x51, 0x0a, 0x20, 0x20,
/* Extension Block Count */
0x00,
/* Checksum */
0x45,
},
};

#define DPCD_HEADER_SIZE 0xb
Expand All @@ -140,14 +176,20 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
vgpu_vreg(vgpu, SDEISR) &= ~(SDE_PORTA_HOTPLUG_SPT |
SDE_PORTE_HOTPLUG_SPT);

if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B))
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_B)) {
vgpu_vreg(vgpu, SDEISR) |= SDE_PORTB_HOTPLUG_CPT;
vgpu_vreg(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIB_DETECTED;
}

if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C))
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_C)) {
vgpu_vreg(vgpu, SDEISR) |= SDE_PORTC_HOTPLUG_CPT;
vgpu_vreg(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIC_DETECTED;
}

if (intel_vgpu_has_monitor_on_port(vgpu, PORT_D))
if (intel_vgpu_has_monitor_on_port(vgpu, PORT_D)) {
vgpu_vreg(vgpu, SDEISR) |= SDE_PORTD_HOTPLUG_CPT;
vgpu_vreg(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDID_DETECTED;
}

if (IS_SKYLAKE(dev_priv) &&
intel_vgpu_has_monitor_on_port(vgpu, PORT_E)) {
Expand All @@ -160,6 +202,8 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
GEN8_PORT_DP_A_HOTPLUG;
else
vgpu_vreg(vgpu, SDEISR) |= SDE_PORTA_HOTPLUG_SPT;

vgpu_vreg(vgpu, DDI_BUF_CTL(PORT_A)) |= DDI_INIT_DISPLAY_DETECTED;
}
}

Expand All @@ -175,10 +219,13 @@ static void clean_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num)
}

static int setup_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num,
int type)
int type, unsigned int resolution)
{
struct intel_vgpu_port *port = intel_vgpu_port(vgpu, port_num);

if (WARN_ON(resolution >= GVT_EDID_NUM))
return -EINVAL;

port->edid = kzalloc(sizeof(*(port->edid)), GFP_KERNEL);
if (!port->edid)
return -ENOMEM;
Expand All @@ -189,7 +236,7 @@ static int setup_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num,
return -ENOMEM;
}

memcpy(port->edid->edid_block, virtual_dp_monitor_edid,
memcpy(port->edid->edid_block, virtual_dp_monitor_edid[resolution],
EDID_SIZE);
port->edid->data_valid = true;

Expand Down Expand Up @@ -322,16 +369,18 @@ void intel_vgpu_clean_display(struct intel_vgpu *vgpu)
* Zero on success, negative error code if failed.
*
*/
int intel_vgpu_init_display(struct intel_vgpu *vgpu)
int intel_vgpu_init_display(struct intel_vgpu *vgpu, u64 resolution)
{
struct drm_i915_private *dev_priv = vgpu->gvt->dev_priv;

intel_vgpu_init_i2c_edid(vgpu);

if (IS_SKYLAKE(dev_priv))
return setup_virtual_dp_monitor(vgpu, PORT_D, GVT_DP_D);
return setup_virtual_dp_monitor(vgpu, PORT_D, GVT_DP_D,
resolution);
else
return setup_virtual_dp_monitor(vgpu, PORT_B, GVT_DP_B);
return setup_virtual_dp_monitor(vgpu, PORT_B, GVT_DP_B,
resolution);
}

/**
Expand Down
Loading

0 comments on commit 7c7fba9

Please sign in to comment.