diff -Nrup linux-4.4.143/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c linux-4.4.189/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c --- linux-4.4.143/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c 2019-08-11 03:20:49.000000000 -0700 @@ -504,7 +504,7 @@ static int kgd_hqd_sdma_destroy(struct k while (true) { temp = RREG32(sdma_base_addr + mmSDMA0_RLC0_CONTEXT_STATUS); - if (temp & SDMA0_STATUS_REG__RB_CMD_IDLE__SHIFT) + if (temp & SDMA0_RLC0_CONTEXT_STATUS__IDLE_MASK) break; if (timeout == 0) return -ETIME; diff -Nrup linux-4.4.143/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c linux-4.4.189/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c --- linux-4.4.143/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c 2019-08-11 03:20:49.000000000 -0700 @@ -492,6 +492,10 @@ void amdgpu_bo_force_delete(struct amdgp int amdgpu_bo_init(struct amdgpu_device *adev) { + /* reserve PAT memory space to WC for VRAM */ + arch_io_reserve_memtype_wc(adev->mc.aper_base, + adev->mc.aper_size); + /* Add an MTRR for the VRAM */ adev->mc.vram_mtrr = arch_phys_wc_add(adev->mc.aper_base, adev->mc.aper_size); @@ -507,6 +511,7 @@ void amdgpu_bo_fini(struct amdgpu_device { amdgpu_ttm_fini(adev); arch_phys_wc_del(adev->mc.vram_mtrr); + arch_io_free_memtype_wc(adev->mc.aper_base, adev->mc.aper_size); } int amdgpu_bo_fbdev_mmap(struct amdgpu_bo *bo, diff -Nrup linux-4.4.143/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c linux-4.4.189/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c --- linux-4.4.143/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c 2019-08-11 03:20:49.000000000 -0700 @@ -496,9 +496,13 @@ static int amdgpu_ttm_tt_pin_userptr(str int r; int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY); + unsigned int flags = 0; enum dma_data_direction direction = write ? DMA_BIDIRECTIONAL : DMA_TO_DEVICE; + if (write) + flags |= FOLL_WRITE; + if (current->mm != gtt->usermm) return -EPERM; @@ -519,7 +523,7 @@ static int amdgpu_ttm_tt_pin_userptr(str struct page **pages = ttm->pages + pinned; r = get_user_pages(current, current->mm, userptr, num_pages, - write, 0, pages, NULL); + flags, pages, NULL); if (r < 0) goto release_pages; diff -Nrup linux-4.4.143/drivers/gpu/drm/amd/amdkfd/kfd_process.c linux-4.4.189/drivers/gpu/drm/amd/amdkfd/kfd_process.c --- linux-4.4.143/drivers/gpu/drm/amd/amdkfd/kfd_process.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/amd/amdkfd/kfd_process.c 2019-08-11 03:20:49.000000000 -0700 @@ -125,6 +125,8 @@ struct kfd_process *kfd_get_process(cons return ERR_PTR(-EINVAL); process = find_process(thread); + if (!process) + return ERR_PTR(-EINVAL); return process; } diff -Nrup linux-4.4.143/drivers/gpu/drm/armada/armada_hw.h linux-4.4.189/drivers/gpu/drm/armada/armada_hw.h --- linux-4.4.143/drivers/gpu/drm/armada/armada_hw.h 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/armada/armada_hw.h 2019-08-11 03:20:49.000000000 -0700 @@ -160,6 +160,7 @@ enum { CFG_ALPHAM_GRA = 0x1 << 16, CFG_ALPHAM_CFG = 0x2 << 16, CFG_ALPHA_MASK = 0xff << 8, +#define CFG_ALPHA(x) ((x) << 8) CFG_PIXCMD_MASK = 0xff, }; diff -Nrup linux-4.4.143/drivers/gpu/drm/armada/armada_overlay.c linux-4.4.189/drivers/gpu/drm/armada/armada_overlay.c --- linux-4.4.143/drivers/gpu/drm/armada/armada_overlay.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/armada/armada_overlay.c 2019-08-11 03:20:49.000000000 -0700 @@ -27,6 +27,7 @@ struct armada_ovl_plane_properties { uint16_t contrast; uint16_t saturation; uint32_t colorkey_mode; + uint32_t colorkey_enable; }; struct armada_ovl_plane { @@ -62,11 +63,13 @@ armada_ovl_update_attr(struct armada_ovl writel_relaxed(0x00002000, dcrtc->base + LCD_SPU_CBSH_HUE); spin_lock_irq(&dcrtc->irq_lock); - armada_updatel(prop->colorkey_mode | CFG_ALPHAM_GRA, - CFG_CKMODE_MASK | CFG_ALPHAM_MASK | CFG_ALPHA_MASK, - dcrtc->base + LCD_SPU_DMA_CTRL1); - - armada_updatel(ADV_GRACOLORKEY, 0, dcrtc->base + LCD_SPU_ADV_REG); + armada_updatel(prop->colorkey_mode, + CFG_CKMODE_MASK | CFG_ALPHAM_MASK | CFG_ALPHA_MASK, + dcrtc->base + LCD_SPU_DMA_CTRL1); + if (dcrtc->variant->has_spu_adv_reg) + armada_updatel(prop->colorkey_enable, + ADV_GRACOLORKEY | ADV_VIDCOLORKEY, + dcrtc->base + LCD_SPU_ADV_REG); spin_unlock_irq(&dcrtc->irq_lock); } @@ -339,8 +342,17 @@ static int armada_ovl_plane_set_property dplane->prop.colorkey_vb |= K2B(val); update_attr = true; } else if (property == priv->colorkey_mode_prop) { - dplane->prop.colorkey_mode &= ~CFG_CKMODE_MASK; - dplane->prop.colorkey_mode |= CFG_CKMODE(val); + if (val == CKMODE_DISABLE) { + dplane->prop.colorkey_mode = + CFG_CKMODE(CKMODE_DISABLE) | + CFG_ALPHAM_CFG | CFG_ALPHA(255); + dplane->prop.colorkey_enable = 0; + } else { + dplane->prop.colorkey_mode = + CFG_CKMODE(val) | + CFG_ALPHAM_GRA | CFG_ALPHA(0); + dplane->prop.colorkey_enable = ADV_GRACOLORKEY; + } update_attr = true; } else if (property == priv->brightness_prop) { dplane->prop.brightness = val - 256; @@ -469,7 +481,9 @@ int armada_overlay_plane_create(struct d dplane->prop.colorkey_yr = 0xfefefe00; dplane->prop.colorkey_ug = 0x01010100; dplane->prop.colorkey_vb = 0x01010100; - dplane->prop.colorkey_mode = CFG_CKMODE(CKMODE_RGB); + dplane->prop.colorkey_mode = CFG_CKMODE(CKMODE_RGB) | + CFG_ALPHAM_GRA | CFG_ALPHA(0); + dplane->prop.colorkey_enable = ADV_GRACOLORKEY; dplane->prop.brightness = 0; dplane->prop.contrast = 0x4000; dplane->prop.saturation = 0x4000; diff -Nrup linux-4.4.143/drivers/gpu/drm/ast/ast_drv.c linux-4.4.189/drivers/gpu/drm/ast/ast_drv.c --- linux-4.4.143/drivers/gpu/drm/ast/ast_drv.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/ast/ast_drv.c 2019-08-11 03:20:49.000000000 -0700 @@ -60,8 +60,29 @@ static const struct pci_device_id pciidl MODULE_DEVICE_TABLE(pci, pciidlist); +static void ast_kick_out_firmware_fb(struct pci_dev *pdev) +{ + struct apertures_struct *ap; + bool primary = false; + + ap = alloc_apertures(1); + if (!ap) + return; + + ap->ranges[0].base = pci_resource_start(pdev, 0); + ap->ranges[0].size = pci_resource_len(pdev, 0); + +#ifdef CONFIG_X86 + primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; +#endif + remove_conflicting_framebuffers(ap, "astdrmfb", primary); + kfree(ap); +} + static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { + ast_kick_out_firmware_fb(pdev); + return drm_get_pci_dev(pdev, ent, &driver); } diff -Nrup linux-4.4.143/drivers/gpu/drm/ast/ast_main.c linux-4.4.189/drivers/gpu/drm/ast/ast_main.c --- linux-4.4.143/drivers/gpu/drm/ast/ast_main.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/ast/ast_main.c 2019-08-11 03:20:49.000000000 -0700 @@ -557,7 +557,8 @@ int ast_driver_unload(struct drm_device drm_mode_config_cleanup(dev); ast_mm_fini(ast); - pci_iounmap(dev->pdev, ast->ioregs); + if (ast->ioregs != ast->regs + AST_IO_MM_OFFSET) + pci_iounmap(dev->pdev, ast->ioregs); pci_iounmap(dev->pdev, ast->regs); kfree(ast); return 0; diff -Nrup linux-4.4.143/drivers/gpu/drm/ast/ast_mode.c linux-4.4.189/drivers/gpu/drm/ast/ast_mode.c --- linux-4.4.143/drivers/gpu/drm/ast/ast_mode.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/ast/ast_mode.c 2019-08-11 03:20:49.000000000 -0700 @@ -552,6 +552,7 @@ static int ast_crtc_do_set_base(struct d } ast_bo_unreserve(bo); + ast_set_offset_reg(crtc); ast_set_start_address_crt1(crtc, (u32)gpu_addr); return 0; @@ -967,9 +968,21 @@ static int get_clock(void *i2c_priv) { struct ast_i2c_chan *i2c = i2c_priv; struct ast_private *ast = i2c->dev->dev_private; - uint32_t val; + uint32_t val, val2, count, pass; + + count = 0; + pass = 0; + val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; + do { + val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; + if (val == val2) { + pass++; + } else { + pass = 0; + val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; + } + } while ((pass < 5) && (count++ < 0x10000)); - val = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4; return val & 1 ? 1 : 0; } @@ -977,9 +990,21 @@ static int get_data(void *i2c_priv) { struct ast_i2c_chan *i2c = i2c_priv; struct ast_private *ast = i2c->dev->dev_private; - uint32_t val; + uint32_t val, val2, count, pass; + + count = 0; + pass = 0; + val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; + do { + val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; + if (val == val2) { + pass++; + } else { + pass = 0; + val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; + } + } while ((pass < 5) && (count++ < 0x10000)); - val = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5; return val & 1 ? 1 : 0; } @@ -992,7 +1017,7 @@ static void set_clock(void *i2c_priv, in for (i = 0; i < 0x10000; i++) { ujcrb7 = ((clock & 0x01) ? 0 : 1); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xfe, ujcrb7); + ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7); jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01); if (ujcrb7 == jtemp) break; @@ -1008,7 +1033,7 @@ static void set_data(void *i2c_priv, int for (i = 0; i < 0x10000; i++) { ujcrb7 = ((data & 0x01) ? 0 : 1) << 2; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xfb, ujcrb7); + ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7); jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04); if (ujcrb7 == jtemp) break; @@ -1249,7 +1274,7 @@ static int ast_cursor_move(struct drm_cr ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, ((y >> 8) & 0x07)); /* dummy write to fire HWC */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xCB, 0xFF, 0x00); + ast_show_cursor(crtc); return 0; } diff -Nrup linux-4.4.143/drivers/gpu/drm/ast/ast_ttm.c linux-4.4.189/drivers/gpu/drm/ast/ast_ttm.c --- linux-4.4.143/drivers/gpu/drm/ast/ast_ttm.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/ast/ast_ttm.c 2019-08-11 03:20:49.000000000 -0700 @@ -275,6 +275,8 @@ int ast_mm_init(struct ast_private *ast) return ret; } + arch_io_reserve_memtype_wc(pci_resource_start(dev->pdev, 0), + pci_resource_len(dev->pdev, 0)); ast->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0), pci_resource_len(dev->pdev, 0)); @@ -283,11 +285,15 @@ int ast_mm_init(struct ast_private *ast) void ast_mm_fini(struct ast_private *ast) { + struct drm_device *dev = ast->dev; + ttm_bo_device_release(&ast->ttm.bdev); ast_ttm_global_release(ast); arch_phys_wc_del(ast->fb_mtrr); + arch_io_free_memtype_wc(pci_resource_start(dev->pdev, 0), + pci_resource_len(dev->pdev, 0)); } void ast_ttm_placement(struct ast_bo *bo, int domain) diff -Nrup linux-4.4.143/drivers/gpu/drm/cirrus/cirrus_ttm.c linux-4.4.189/drivers/gpu/drm/cirrus/cirrus_ttm.c --- linux-4.4.143/drivers/gpu/drm/cirrus/cirrus_ttm.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/cirrus/cirrus_ttm.c 2019-08-11 03:20:49.000000000 -0700 @@ -275,6 +275,9 @@ int cirrus_mm_init(struct cirrus_device return ret; } + arch_io_reserve_memtype_wc(pci_resource_start(dev->pdev, 0), + pci_resource_len(dev->pdev, 0)); + cirrus->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0), pci_resource_len(dev->pdev, 0)); @@ -284,6 +287,8 @@ int cirrus_mm_init(struct cirrus_device void cirrus_mm_fini(struct cirrus_device *cirrus) { + struct drm_device *dev = cirrus->dev; + if (!cirrus->mm_inited) return; @@ -293,6 +298,8 @@ void cirrus_mm_fini(struct cirrus_device arch_phys_wc_del(cirrus->fb_mtrr); cirrus->fb_mtrr = 0; + arch_io_free_memtype_wc(pci_resource_start(dev->pdev, 0), + pci_resource_len(dev->pdev, 0)); } void cirrus_ttm_placement(struct cirrus_bo *bo, int domain) diff -Nrup linux-4.4.143/drivers/gpu/drm/drm_atomic.c linux-4.4.189/drivers/gpu/drm/drm_atomic.c --- linux-4.4.143/drivers/gpu/drm/drm_atomic.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/drm_atomic.c 2019-08-11 03:20:49.000000000 -0700 @@ -960,7 +960,9 @@ drm_atomic_set_crtc_for_plane(struct drm { struct drm_plane *plane = plane_state->plane; struct drm_crtc_state *crtc_state; - + /* Nothing to do for same crtc*/ + if (plane_state->crtc == crtc) + return 0; if (plane_state->crtc) { crtc_state = drm_atomic_get_crtc_state(plane_state->state, plane_state->crtc); diff -Nrup linux-4.4.143/drivers/gpu/drm/drm_bufs.c linux-4.4.189/drivers/gpu/drm/drm_bufs.c --- linux-4.4.143/drivers/gpu/drm/drm_bufs.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/drm_bufs.c 2019-08-11 03:20:49.000000000 -0700 @@ -36,6 +36,8 @@ #include #include "drm_legacy.h" +#include + static struct drm_map_list *drm_find_matching_map(struct drm_device *dev, struct drm_local_map *map) { @@ -1332,6 +1334,7 @@ int drm_legacy_freebufs(struct drm_devic idx, dma->buf_count - 1); return -EINVAL; } + idx = array_index_nospec(idx, dma->buf_count); buf = dma->buflist[idx]; if (buf->file_priv != file_priv) { DRM_ERROR("Process %d freeing buffer not owned\n", diff -Nrup linux-4.4.143/drivers/gpu/drm/drm_dp_mst_topology.c linux-4.4.189/drivers/gpu/drm/drm_dp_mst_topology.c --- linux-4.4.143/drivers/gpu/drm/drm_dp_mst_topology.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/drm_dp_mst_topology.c 2019-08-11 03:20:49.000000000 -0700 @@ -1225,6 +1225,9 @@ static struct drm_dp_mst_branch *drm_dp_ mutex_lock(&mgr->lock); mstb = mgr->mst_primary; + if (!mstb) + goto out; + for (i = 0; i < lct - 1; i++) { int shift = (i % 2) ? 0 : 4; int port_num = (rad[i / 2] >> shift) & 0xf; @@ -3016,6 +3019,7 @@ static int drm_dp_mst_i2c_xfer(struct i2 msg.u.i2c_read.transactions[i].i2c_dev_id = msgs[i].addr; msg.u.i2c_read.transactions[i].num_bytes = msgs[i].len; msg.u.i2c_read.transactions[i].bytes = msgs[i].buf; + msg.u.i2c_read.transactions[i].no_stop_bit = !(msgs[i].flags & I2C_M_STOP); } msg.u.i2c_read.read_i2c_device_id = msgs[num - 1].addr; msg.u.i2c_read.num_bytes_read = msgs[num - 1].len; diff -Nrup linux-4.4.143/drivers/gpu/drm/drm_fb_helper.c linux-4.4.189/drivers/gpu/drm/drm_fb_helper.c --- linux-4.4.143/drivers/gpu/drm/drm_fb_helper.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/drm_fb_helper.c 2019-08-11 03:20:49.000000000 -0700 @@ -1109,9 +1109,14 @@ int drm_fb_helper_check_var(struct fb_va struct drm_framebuffer *fb = fb_helper->fb; int depth; - if (var->pixclock != 0 || in_dbg_master()) + if (in_dbg_master()) return -EINVAL; + if (var->pixclock != 0) { + DRM_DEBUG("fbdev emulation doesn't support changing the pixel clock, value of pixclock is ignored\n"); + var->pixclock = 0; + } + /* Need to resize the fb object !!! */ if (var->bits_per_pixel > fb->bits_per_pixel || var->xres > fb->width || var->yres > fb->height || diff -Nrup linux-4.4.143/drivers/gpu/drm/drm_ioctl.c linux-4.4.189/drivers/gpu/drm/drm_ioctl.c --- linux-4.4.143/drivers/gpu/drm/drm_ioctl.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/drm_ioctl.c 2019-08-11 03:20:49.000000000 -0700 @@ -36,6 +36,7 @@ #include #include +#include static int drm_version(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -702,13 +703,17 @@ long drm_ioctl(struct file *filp, if (is_driver_ioctl) { /* driver ioctl */ - if (nr - DRM_COMMAND_BASE >= dev->driver->num_ioctls) + unsigned int index = nr - DRM_COMMAND_BASE; + + if (index >= dev->driver->num_ioctls) goto err_i1; - ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; + index = array_index_nospec(index, dev->driver->num_ioctls); + ioctl = &dev->driver->ioctls[index]; } else { /* core ioctl */ if (nr >= DRM_CORE_IOCTL_COUNT) goto err_i1; + nr = array_index_nospec(nr, DRM_CORE_IOCTL_COUNT); ioctl = &drm_ioctls[nr]; } @@ -810,6 +815,7 @@ bool drm_ioctl_flags(unsigned int nr, un if (nr >= DRM_CORE_IOCTL_COUNT) return false; + nr = array_index_nospec(nr, DRM_CORE_IOCTL_COUNT); *flags = drm_ioctls[nr].flags; return true; diff -Nrup linux-4.4.143/drivers/gpu/drm/drm_modes.c linux-4.4.189/drivers/gpu/drm/drm_modes.c --- linux-4.4.143/drivers/gpu/drm/drm_modes.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/drm_modes.c 2019-08-11 03:20:49.000000000 -0700 @@ -722,7 +722,7 @@ int drm_mode_hsync(const struct drm_disp if (mode->hsync) return mode->hsync; - if (mode->htotal < 0) + if (mode->htotal <= 0) return 0; calc_val = (mode->clock * 1000) / mode->htotal; /* hsync in Hz */ diff -Nrup linux-4.4.143/drivers/gpu/drm/exynos/exynos5433_drm_decon.c linux-4.4.189/drivers/gpu/drm/exynos/exynos5433_drm_decon.c --- linux-4.4.143/drivers/gpu/drm/exynos/exynos5433_drm_decon.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/exynos/exynos5433_drm_decon.c 2019-08-11 03:20:49.000000000 -0700 @@ -190,7 +190,7 @@ static void decon_win_set_pixfmt(struct unsigned long val; val = readl(ctx->addr + DECON_WINCONx(win)); - val &= ~WINCONx_BPPMODE_MASK; + val &= WINCONx_ENWIN_F; switch (fb->pixel_format) { case DRM_FORMAT_XRGB1555: @@ -278,8 +278,8 @@ static void decon_update_plane(struct ex COORDINATE_Y(plane->crtc_y + plane->crtc_h - 1); writel(val, ctx->addr + DECON_VIDOSDxB(win)); - val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) | - VIDOSD_Wx_ALPHA_B_F(0x0); + val = VIDOSD_Wx_ALPHA_R_F(0xff) | VIDOSD_Wx_ALPHA_G_F(0xff) | + VIDOSD_Wx_ALPHA_B_F(0xff); writel(val, ctx->addr + DECON_VIDOSDxC(win)); val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) | diff -Nrup linux-4.4.143/drivers/gpu/drm/exynos/exynos_drm_g2d.c linux-4.4.189/drivers/gpu/drm/exynos/exynos_drm_g2d.c --- linux-4.4.143/drivers/gpu/drm/exynos/exynos_drm_g2d.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/exynos/exynos_drm_g2d.c 2019-08-11 03:20:49.000000000 -0700 @@ -471,7 +471,8 @@ static dma_addr_t *g2d_userptr_get_dma_a goto err_free; } - ret = get_vaddr_frames(start, npages, true, true, g2d_userptr->vec); + ret = get_vaddr_frames(start, npages, FOLL_FORCE | FOLL_WRITE, + g2d_userptr->vec); if (ret != npages) { DRM_ERROR("failed to get user pages from userptr.\n"); if (ret < 0) diff -Nrup linux-4.4.143/drivers/gpu/drm/exynos/exynos_drm_gsc.c linux-4.4.189/drivers/gpu/drm/exynos/exynos_drm_gsc.c --- linux-4.4.143/drivers/gpu/drm/exynos/exynos_drm_gsc.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/exynos/exynos_drm_gsc.c 2019-08-11 03:20:49.000000000 -0700 @@ -526,21 +526,25 @@ static int gsc_src_set_fmt(struct device GSC_IN_CHROMA_ORDER_CRCB); break; case DRM_FORMAT_NV21: + cfg |= (GSC_IN_CHROMA_ORDER_CRCB | GSC_IN_YUV420_2P); + break; case DRM_FORMAT_NV61: - cfg |= (GSC_IN_CHROMA_ORDER_CRCB | - GSC_IN_YUV420_2P); + cfg |= (GSC_IN_CHROMA_ORDER_CRCB | GSC_IN_YUV422_2P); break; case DRM_FORMAT_YUV422: cfg |= GSC_IN_YUV422_3P; break; case DRM_FORMAT_YUV420: + cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV420_3P); + break; case DRM_FORMAT_YVU420: - cfg |= GSC_IN_YUV420_3P; + cfg |= (GSC_IN_CHROMA_ORDER_CRCB | GSC_IN_YUV420_3P); break; case DRM_FORMAT_NV12: + cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV420_2P); + break; case DRM_FORMAT_NV16: - cfg |= (GSC_IN_CHROMA_ORDER_CBCR | - GSC_IN_YUV420_2P); + cfg |= (GSC_IN_CHROMA_ORDER_CBCR | GSC_IN_YUV422_2P); break; default: dev_err(ippdrv->dev, "invalid target yuv order 0x%x.\n", fmt); @@ -800,18 +804,25 @@ static int gsc_dst_set_fmt(struct device GSC_OUT_CHROMA_ORDER_CRCB); break; case DRM_FORMAT_NV21: - case DRM_FORMAT_NV61: cfg |= (GSC_OUT_CHROMA_ORDER_CRCB | GSC_OUT_YUV420_2P); break; + case DRM_FORMAT_NV61: + cfg |= (GSC_OUT_CHROMA_ORDER_CRCB | GSC_OUT_YUV422_2P); + break; case DRM_FORMAT_YUV422: + cfg |= GSC_OUT_YUV422_3P; + break; case DRM_FORMAT_YUV420: + cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV420_3P); + break; case DRM_FORMAT_YVU420: - cfg |= GSC_OUT_YUV420_3P; + cfg |= (GSC_OUT_CHROMA_ORDER_CRCB | GSC_OUT_YUV420_3P); break; case DRM_FORMAT_NV12: + cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV420_2P); + break; case DRM_FORMAT_NV16: - cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | - GSC_OUT_YUV420_2P); + cfg |= (GSC_OUT_CHROMA_ORDER_CBCR | GSC_OUT_YUV422_2P); break; default: dev_err(ippdrv->dev, "invalid target yuv order 0x%x.\n", fmt); diff -Nrup linux-4.4.143/drivers/gpu/drm/exynos/regs-gsc.h linux-4.4.189/drivers/gpu/drm/exynos/regs-gsc.h --- linux-4.4.143/drivers/gpu/drm/exynos/regs-gsc.h 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/exynos/regs-gsc.h 2019-08-11 03:20:49.000000000 -0700 @@ -138,6 +138,7 @@ #define GSC_OUT_YUV420_3P (3 << 4) #define GSC_OUT_YUV422_1P (4 << 4) #define GSC_OUT_YUV422_2P (5 << 4) +#define GSC_OUT_YUV422_3P (6 << 4) #define GSC_OUT_YUV444 (7 << 4) #define GSC_OUT_TILE_TYPE_MASK (1 << 2) #define GSC_OUT_TILE_C_16x8 (0 << 2) diff -Nrup linux-4.4.143/drivers/gpu/drm/gma500/cdv_intel_lvds.c linux-4.4.189/drivers/gpu/drm/gma500/cdv_intel_lvds.c --- linux-4.4.143/drivers/gpu/drm/gma500/cdv_intel_lvds.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/gma500/cdv_intel_lvds.c 2019-08-11 03:20:49.000000000 -0700 @@ -620,6 +620,9 @@ void cdv_intel_lvds_init(struct drm_devi int pipe; u8 pin; + if (!dev_priv->lvds_enabled_in_vbt) + return; + pin = GMBUS_PORT_PANEL; if (!lvds_is_present_in_vbt(dev, &pin)) { DRM_DEBUG_KMS("LVDS is not present in VBT\n"); diff -Nrup linux-4.4.143/drivers/gpu/drm/gma500/intel_bios.c linux-4.4.189/drivers/gpu/drm/gma500/intel_bios.c --- linux-4.4.143/drivers/gpu/drm/gma500/intel_bios.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/gma500/intel_bios.c 2019-08-11 03:20:49.000000000 -0700 @@ -436,6 +436,9 @@ parse_driver_features(struct drm_psb_pri if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP) dev_priv->edp.support = 1; + dev_priv->lvds_enabled_in_vbt = driver->lvds_config != 0; + DRM_DEBUG_KMS("LVDS VBT config bits: 0x%x\n", driver->lvds_config); + /* This bit means to use 96Mhz for DPLL_A or not */ if (driver->primary_lfp_id) dev_priv->dplla_96mhz = true; diff -Nrup linux-4.4.143/drivers/gpu/drm/gma500/mdfld_intel_display.c linux-4.4.189/drivers/gpu/drm/gma500/mdfld_intel_display.c --- linux-4.4.143/drivers/gpu/drm/gma500/mdfld_intel_display.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/gma500/mdfld_intel_display.c 2019-08-11 03:20:49.000000000 -0700 @@ -99,7 +99,7 @@ void mdfldWaitForPipeEnable(struct drm_d /* Wait for for the pipe enable to take effect. */ for (count = 0; count < COUNT_MAX; count++) { temp = REG_READ(map->conf); - if ((temp & PIPEACONF_PIPE_STATE) == 1) + if (temp & PIPEACONF_PIPE_STATE) break; } } diff -Nrup linux-4.4.143/drivers/gpu/drm/gma500/psb_drv.h linux-4.4.189/drivers/gpu/drm/gma500/psb_drv.h --- linux-4.4.143/drivers/gpu/drm/gma500/psb_drv.h 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/gma500/psb_drv.h 2019-08-11 03:20:49.000000000 -0700 @@ -536,6 +536,7 @@ struct drm_psb_private { int lvds_ssc_freq; bool is_lvds_on; bool is_mipi_on; + bool lvds_enabled_in_vbt; u32 mipi_ctrl_display; unsigned int core_freq; diff -Nrup linux-4.4.143/drivers/gpu/drm/gma500/psb_intel_drv.h linux-4.4.189/drivers/gpu/drm/gma500/psb_intel_drv.h --- linux-4.4.143/drivers/gpu/drm/gma500/psb_intel_drv.h 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/gma500/psb_intel_drv.h 2019-08-11 03:20:49.000000000 -0700 @@ -252,7 +252,7 @@ extern int intelfb_remove(struct drm_dev extern bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode); -extern int psb_intel_lvds_mode_valid(struct drm_connector *connector, +extern enum drm_mode_status psb_intel_lvds_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode); extern int psb_intel_lvds_set_property(struct drm_connector *connector, struct drm_property *property, diff -Nrup linux-4.4.143/drivers/gpu/drm/gma500/psb_intel_lvds.c linux-4.4.189/drivers/gpu/drm/gma500/psb_intel_lvds.c --- linux-4.4.143/drivers/gpu/drm/gma500/psb_intel_lvds.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/gma500/psb_intel_lvds.c 2019-08-11 03:20:49.000000000 -0700 @@ -343,7 +343,7 @@ static void psb_intel_lvds_restore(struc } } -int psb_intel_lvds_mode_valid(struct drm_connector *connector, +enum drm_mode_status psb_intel_lvds_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct drm_psb_private *dev_priv = connector->dev->dev_private; diff -Nrup linux-4.4.143/drivers/gpu/drm/i2c/adv7511.c linux-4.4.189/drivers/gpu/drm/i2c/adv7511.c --- linux-4.4.143/drivers/gpu/drm/i2c/adv7511.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/i2c/adv7511.c 2019-08-11 03:20:49.000000000 -0700 @@ -450,6 +450,18 @@ static void adv7511_hpd_work(struct work else status = connector_status_disconnected; + /* + * The bridge resets its registers on unplug. So when we get a plug + * event and we're already supposed to be powered, cycle the bridge to + * restore its state. + */ + if (status == connector_status_connected && + adv7511->connector.status == connector_status_disconnected && + adv7511->powered) { + regcache_mark_dirty(adv7511->regmap); + adv7511_power_on(adv7511); + } + if (adv7511->connector.status != status) { adv7511->connector.status = status; drm_kms_helper_hotplug_event(adv7511->connector.dev); @@ -769,11 +781,11 @@ static void adv7511_encoder_mode_set(str vsync_polarity = 1; } - if (mode->vrefresh <= 24000) + if (drm_mode_vrefresh(mode) <= 24) low_refresh_rate = ADV7511_LOW_REFRESH_RATE_24HZ; - else if (mode->vrefresh <= 25000) + else if (drm_mode_vrefresh(mode) <= 25) low_refresh_rate = ADV7511_LOW_REFRESH_RATE_25HZ; - else if (mode->vrefresh <= 30000) + else if (drm_mode_vrefresh(mode) <= 30) low_refresh_rate = ADV7511_LOW_REFRESH_RATE_30HZ; else low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE; diff -Nrup linux-4.4.143/drivers/gpu/drm/i915/i915_gem_userptr.c linux-4.4.189/drivers/gpu/drm/i915/i915_gem_userptr.c --- linux-4.4.143/drivers/gpu/drm/i915/i915_gem_userptr.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/i915/i915_gem_userptr.c 2019-08-11 03:20:49.000000000 -0700 @@ -581,13 +581,17 @@ __i915_gem_userptr_get_pages_worker(stru pvec = drm_malloc_ab(npages, sizeof(struct page *)); if (pvec != NULL) { struct mm_struct *mm = obj->userptr.mm->mm; + unsigned int flags = 0; + + if (!obj->userptr.read_only) + flags |= FOLL_WRITE; down_read(&mm->mmap_sem); while (pinned < npages) { ret = get_user_pages(work->task, mm, obj->userptr.ptr + pinned * PAGE_SIZE, npages - pinned, - !obj->userptr.read_only, 0, + flags, pvec + pinned, NULL); if (ret < 0) break; @@ -842,6 +846,9 @@ i915_gem_userptr_ioctl(struct drm_device I915_USERPTR_UNSYNCHRONIZED)) return -EINVAL; + if (!args->user_size) + return -EINVAL; + if (offset_in_page(args->user_ptr | args->user_size)) return -EINVAL; diff -Nrup linux-4.4.143/drivers/gpu/drm/i915/intel_audio.c linux-4.4.189/drivers/gpu/drm/i915/intel_audio.c --- linux-4.4.143/drivers/gpu/drm/i915/intel_audio.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/i915/intel_audio.c 2019-08-11 03:20:49.000000000 -0700 @@ -76,6 +76,9 @@ static const struct { /* HDMI N/CTS table */ #define TMDS_297M 297000 #define TMDS_296M 296703 +#define TMDS_594M 594000 +#define TMDS_593M 593407 + static const struct { int sample_rate; int clock; @@ -96,6 +99,20 @@ static const struct { { 176400, TMDS_297M, 18816, 247500 }, { 192000, TMDS_296M, 23296, 281250 }, { 192000, TMDS_297M, 20480, 247500 }, + { 44100, TMDS_593M, 8918, 937500 }, + { 44100, TMDS_594M, 9408, 990000 }, + { 48000, TMDS_593M, 5824, 562500 }, + { 48000, TMDS_594M, 6144, 594000 }, + { 32000, TMDS_593M, 5824, 843750 }, + { 32000, TMDS_594M, 3072, 445500 }, + { 88200, TMDS_593M, 17836, 937500 }, + { 88200, TMDS_594M, 18816, 990000 }, + { 96000, TMDS_593M, 11648, 562500 }, + { 96000, TMDS_594M, 12288, 594000 }, + { 176400, TMDS_593M, 35672, 937500 }, + { 176400, TMDS_594M, 37632, 990000 }, + { 192000, TMDS_593M, 23296, 562500 }, + { 192000, TMDS_594M, 24576, 594000 }, }; /* get AUD_CONFIG_PIXEL_CLOCK_HDMI_* value for mode */ diff -Nrup linux-4.4.143/drivers/gpu/drm/imx/imx-ldb.c linux-4.4.189/drivers/gpu/drm/imx/imx-ldb.c --- linux-4.4.143/drivers/gpu/drm/imx/imx-ldb.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/imx/imx-ldb.c 2019-08-11 03:20:49.000000000 -0700 @@ -526,6 +526,9 @@ static int imx_ldb_bind(struct device *d return PTR_ERR(imx_ldb->regmap); } + /* disable LDB by resetting the control register to POR default */ + regmap_write(imx_ldb->regmap, IOMUXC_GPR2, 0); + imx_ldb->dev = dev; if (of_id) @@ -566,14 +569,14 @@ static int imx_ldb_bind(struct device *d if (ret || i < 0 || i > 1) return -EINVAL; + if (!of_device_is_available(child)) + continue; + if (dual && i > 0) { dev_warn(dev, "dual-channel mode, ignoring second output\n"); continue; } - if (!of_device_is_available(child)) - continue; - channel = &imx_ldb->channel[i]; channel->ldb = imx_ldb; channel->chno = i; diff -Nrup linux-4.4.143/drivers/gpu/drm/mgag200/mgag200_ttm.c linux-4.4.189/drivers/gpu/drm/mgag200/mgag200_ttm.c --- linux-4.4.143/drivers/gpu/drm/mgag200/mgag200_ttm.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/mgag200/mgag200_ttm.c 2019-08-11 03:20:49.000000000 -0700 @@ -274,6 +274,9 @@ int mgag200_mm_init(struct mga_device *m return ret; } + arch_io_reserve_memtype_wc(pci_resource_start(dev->pdev, 0), + pci_resource_len(dev->pdev, 0)); + mdev->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0), pci_resource_len(dev->pdev, 0)); @@ -282,10 +285,14 @@ int mgag200_mm_init(struct mga_device *m void mgag200_mm_fini(struct mga_device *mdev) { + struct drm_device *dev = mdev->dev; + ttm_bo_device_release(&mdev->ttm.bdev); mgag200_ttm_global_release(mdev); + arch_io_free_memtype_wc(pci_resource_start(dev->pdev, 0), + pci_resource_len(dev->pdev, 0)); arch_phys_wc_del(mdev->fb_mtrr); mdev->fb_mtrr = 0; } diff -Nrup linux-4.4.143/drivers/gpu/drm/msm/msm_atomic.c linux-4.4.189/drivers/gpu/drm/msm/msm_atomic.c --- linux-4.4.143/drivers/gpu/drm/msm/msm_atomic.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/msm/msm_atomic.c 2019-08-11 03:20:49.000000000 -0700 @@ -107,7 +107,12 @@ static void msm_atomic_wait_for_commit_d if (old_state->legacy_cursor_update) continue; + if (drm_crtc_vblank_get(crtc)) + continue; + kms->funcs->wait_for_crtc_commit_done(kms, crtc); + + drm_crtc_vblank_put(crtc); } } diff -Nrup linux-4.4.143/drivers/gpu/drm/msm/msm_rd.c linux-4.4.189/drivers/gpu/drm/msm/msm_rd.c --- linux-4.4.143/drivers/gpu/drm/msm/msm_rd.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/msm/msm_rd.c 2019-08-11 03:20:49.000000000 -0700 @@ -103,7 +103,9 @@ static void rd_write(struct msm_rd_state char *fptr = &fifo->buf[fifo->head]; int n; - wait_event(rd->fifo_event, circ_space(&rd->fifo) > 0); + wait_event(rd->fifo_event, circ_space(&rd->fifo) > 0 || !rd->open); + if (!rd->open) + return; n = min(sz, circ_space_to_end(&rd->fifo)); memcpy(fptr, ptr, n); @@ -192,7 +194,10 @@ out: static int rd_release(struct inode *inode, struct file *file) { struct msm_rd_state *rd = inode->i_private; + rd->open = false; + wake_up_all(&rd->fifo_event); + return 0; } diff -Nrup linux-4.4.143/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h linux-4.4.189/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h --- linux-4.4.143/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/nouveau/include/nvkm/subdev/i2c.h 2019-08-11 03:20:49.000000000 -0700 @@ -37,6 +37,7 @@ struct nvkm_i2c_bus { struct mutex mutex; struct list_head head; struct i2c_adapter i2c; + u8 enabled; }; int nvkm_i2c_bus_acquire(struct nvkm_i2c_bus *); @@ -56,6 +57,7 @@ struct nvkm_i2c_aux { struct mutex mutex; struct list_head head; struct i2c_adapter i2c; + u8 enabled; u32 intr; }; diff -Nrup linux-4.4.143/drivers/gpu/drm/nouveau/nouveau_connector.c linux-4.4.189/drivers/gpu/drm/nouveau/nouveau_connector.c --- linux-4.4.143/drivers/gpu/drm/nouveau/nouveau_connector.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/nouveau/nouveau_connector.c 2019-08-11 03:20:49.000000000 -0700 @@ -253,12 +253,16 @@ nouveau_connector_detect(struct drm_conn nv_connector->edid = NULL; } - /* Outputs are only polled while runtime active, so acquiring a - * runtime PM ref here is unnecessary (and would deadlock upon - * runtime suspend because it waits for polling to finish). + /* Outputs are only polled while runtime active, so resuming the + * device here is unnecessary (and would deadlock upon runtime suspend + * because it waits for polling to finish). We do however, want to + * prevent the autosuspend timer from elapsing during this operation + * if possible. */ - if (!drm_kms_helper_is_poll_worker()) { - ret = pm_runtime_get_sync(connector->dev->dev); + if (drm_kms_helper_is_poll_worker()) { + pm_runtime_get_noresume(dev->dev); + } else { + ret = pm_runtime_get_sync(dev->dev); if (ret < 0 && ret != -EACCES) return conn_status; } @@ -329,10 +333,8 @@ detect_analog: out: - if (!drm_kms_helper_is_poll_worker()) { - pm_runtime_mark_last_busy(connector->dev->dev); - pm_runtime_put_autosuspend(connector->dev->dev); - } + pm_runtime_mark_last_busy(dev->dev); + pm_runtime_put_autosuspend(dev->dev); return conn_status; } diff -Nrup linux-4.4.143/drivers/gpu/drm/nouveau/nouveau_fbcon.c linux-4.4.189/drivers/gpu/drm/nouveau/nouveau_fbcon.c --- linux-4.4.143/drivers/gpu/drm/nouveau/nouveau_fbcon.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/nouveau/nouveau_fbcon.c 2019-08-11 03:20:49.000000000 -0700 @@ -235,7 +235,7 @@ void nouveau_fbcon_accel_save_disable(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); - if (drm->fbcon) { + if (drm->fbcon && drm->fbcon->helper.fbdev) { drm->fbcon->saved_flags = drm->fbcon->helper.fbdev->flags; drm->fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED; } @@ -245,7 +245,7 @@ void nouveau_fbcon_accel_restore(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); - if (drm->fbcon) { + if (drm->fbcon && drm->fbcon->helper.fbdev) { drm->fbcon->helper.fbdev->flags = drm->fbcon->saved_flags; } } @@ -257,7 +257,8 @@ nouveau_fbcon_accel_fini(struct drm_devi struct nouveau_fbdev *fbcon = drm->fbcon; if (fbcon && drm->channel) { console_lock(); - fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED; + if (fbcon->helper.fbdev) + fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED; console_unlock(); nouveau_channel_idle(drm->channel); nvif_object_fini(&fbcon->twod); diff -Nrup linux-4.4.143/drivers/gpu/drm/nouveau/nouveau_gem.c linux-4.4.189/drivers/gpu/drm/nouveau/nouveau_gem.c --- linux-4.4.143/drivers/gpu/drm/nouveau/nouveau_gem.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/nouveau/nouveau_gem.c 2019-08-11 03:20:49.000000000 -0700 @@ -602,7 +602,7 @@ nouveau_gem_pushbuf_reloc_apply(struct n struct nouveau_bo *nvbo; uint32_t data; - if (unlikely(r->bo_index > req->nr_buffers)) { + if (unlikely(r->bo_index >= req->nr_buffers)) { NV_PRINTK(err, cli, "reloc bo index invalid\n"); ret = -EINVAL; break; @@ -612,7 +612,7 @@ nouveau_gem_pushbuf_reloc_apply(struct n if (b->presumed.valid) continue; - if (unlikely(r->reloc_bo_index > req->nr_buffers)) { + if (unlikely(r->reloc_bo_index >= req->nr_buffers)) { NV_PRINTK(err, cli, "reloc container bo index invalid\n"); ret = -EINVAL; break; diff -Nrup linux-4.4.143/drivers/gpu/drm/nouveau/nouveau_ttm.c linux-4.4.189/drivers/gpu/drm/nouveau/nouveau_ttm.c --- linux-4.4.143/drivers/gpu/drm/nouveau/nouveau_ttm.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/nouveau/nouveau_ttm.c 2019-08-11 03:20:49.000000000 -0700 @@ -397,6 +397,9 @@ nouveau_ttm_init(struct nouveau_drm *drm /* VRAM init */ drm->gem.vram_available = drm->device.info.ram_user; + arch_io_reserve_memtype_wc(device->func->resource_addr(device, 1), + device->func->resource_size(device, 1)); + ret = ttm_bo_init_mm(&drm->ttm.bdev, TTM_PL_VRAM, drm->gem.vram_available >> PAGE_SHIFT); if (ret) { @@ -429,6 +432,8 @@ nouveau_ttm_init(struct nouveau_drm *drm void nouveau_ttm_fini(struct nouveau_drm *drm) { + struct nvkm_device *device = nvxx_device(&drm->device); + ttm_bo_clean_mm(&drm->ttm.bdev, TTM_PL_VRAM); ttm_bo_clean_mm(&drm->ttm.bdev, TTM_PL_TT); @@ -438,4 +443,7 @@ nouveau_ttm_fini(struct nouveau_drm *drm arch_phys_wc_del(drm->ttm.mtrr); drm->ttm.mtrr = 0; + arch_io_free_memtype_wc(device->func->resource_addr(device, 1), + device->func->resource_size(device, 1)); + } diff -Nrup linux-4.4.143/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c linux-4.4.189/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c --- linux-4.4.143/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c 2019-08-11 03:20:49.000000000 -0700 @@ -23,6 +23,10 @@ #ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER #include "priv.h" +#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) +#include +#endif + static int nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev) { @@ -85,6 +89,15 @@ nvkm_device_tegra_probe_iommu(struct nvk unsigned long pgsize_bitmap; int ret; +#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) + if (dev->archdata.mapping) { + struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); + + arm_iommu_detach_device(dev); + arm_iommu_release_mapping(mapping); + } +#endif + if (!tdev->func->iommu_bit) return; diff -Nrup linux-4.4.143/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm204.c linux-4.4.189/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm204.c --- linux-4.4.143/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm204.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/gm204.c 2019-08-11 03:20:49.000000000 -0700 @@ -161,7 +161,8 @@ gm204_devinit_post(struct nvkm_devinit * } /* load and execute some other ucode image (bios therm?) */ - return pmu_load(init, 0x01, post, NULL, NULL); + pmu_load(init, 0x01, post, NULL, NULL); + return 0; } static const struct nvkm_devinit_func diff -Nrup linux-4.4.143/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c linux-4.4.189/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c --- linux-4.4.143/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c 2019-08-11 03:20:49.000000000 -0700 @@ -105,9 +105,15 @@ nvkm_i2c_aux_acquire(struct nvkm_i2c_aux { struct nvkm_i2c_pad *pad = aux->pad; int ret; + AUX_TRACE(aux, "acquire"); mutex_lock(&aux->mutex); - ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_AUX); + + if (aux->enabled) + ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_AUX); + else + ret = -EIO; + if (ret) mutex_unlock(&aux->mutex); return ret; @@ -141,6 +147,24 @@ nvkm_i2c_aux_del(struct nvkm_i2c_aux **p } } +void +nvkm_i2c_aux_init(struct nvkm_i2c_aux *aux) +{ + AUX_TRACE(aux, "init"); + mutex_lock(&aux->mutex); + aux->enabled = true; + mutex_unlock(&aux->mutex); +} + +void +nvkm_i2c_aux_fini(struct nvkm_i2c_aux *aux) +{ + AUX_TRACE(aux, "fini"); + mutex_lock(&aux->mutex); + aux->enabled = false; + mutex_unlock(&aux->mutex); +} + int nvkm_i2c_aux_ctor(const struct nvkm_i2c_aux_func *func, struct nvkm_i2c_pad *pad, int id, diff -Nrup linux-4.4.143/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h linux-4.4.189/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h --- linux-4.4.143/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.h 2019-08-11 03:20:49.000000000 -0700 @@ -14,6 +14,8 @@ int nvkm_i2c_aux_ctor(const struct nvkm_ int nvkm_i2c_aux_new_(const struct nvkm_i2c_aux_func *, struct nvkm_i2c_pad *, int id, struct nvkm_i2c_aux **); void nvkm_i2c_aux_del(struct nvkm_i2c_aux **); +void nvkm_i2c_aux_init(struct nvkm_i2c_aux *); +void nvkm_i2c_aux_fini(struct nvkm_i2c_aux *); int nvkm_i2c_aux_xfer(struct nvkm_i2c_aux *, bool retry, u8 type, u32 addr, u8 *data, u8 size); diff -Nrup linux-4.4.143/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c linux-4.4.189/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c --- linux-4.4.143/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c 2019-08-11 03:20:49.000000000 -0700 @@ -160,8 +160,18 @@ nvkm_i2c_fini(struct nvkm_subdev *subdev { struct nvkm_i2c *i2c = nvkm_i2c(subdev); struct nvkm_i2c_pad *pad; + struct nvkm_i2c_bus *bus; + struct nvkm_i2c_aux *aux; u32 mask; + list_for_each_entry(aux, &i2c->aux, head) { + nvkm_i2c_aux_fini(aux); + } + + list_for_each_entry(bus, &i2c->bus, head) { + nvkm_i2c_bus_fini(bus); + } + if ((mask = (1 << i2c->func->aux) - 1), i2c->func->aux_stat) { i2c->func->aux_mask(i2c, NVKM_I2C_ANY, mask, 0); i2c->func->aux_stat(i2c, &mask, &mask, &mask, &mask); @@ -175,11 +185,31 @@ nvkm_i2c_fini(struct nvkm_subdev *subdev } static int +nvkm_i2c_preinit(struct nvkm_subdev *subdev) +{ + struct nvkm_i2c *i2c = nvkm_i2c(subdev); + struct nvkm_i2c_bus *bus; + struct nvkm_i2c_pad *pad; + + /* + * We init our i2c busses as early as possible, since they may be + * needed by the vbios init scripts on some cards + */ + list_for_each_entry(pad, &i2c->pad, head) + nvkm_i2c_pad_init(pad); + list_for_each_entry(bus, &i2c->bus, head) + nvkm_i2c_bus_init(bus); + + return 0; +} + +static int nvkm_i2c_init(struct nvkm_subdev *subdev) { struct nvkm_i2c *i2c = nvkm_i2c(subdev); struct nvkm_i2c_bus *bus; struct nvkm_i2c_pad *pad; + struct nvkm_i2c_aux *aux; list_for_each_entry(pad, &i2c->pad, head) { nvkm_i2c_pad_init(pad); @@ -189,6 +219,10 @@ nvkm_i2c_init(struct nvkm_subdev *subdev nvkm_i2c_bus_init(bus); } + list_for_each_entry(aux, &i2c->aux, head) { + nvkm_i2c_aux_init(aux); + } + return 0; } @@ -223,6 +257,7 @@ nvkm_i2c_dtor(struct nvkm_subdev *subdev static const struct nvkm_subdev_func nvkm_i2c = { .dtor = nvkm_i2c_dtor, + .preinit = nvkm_i2c_preinit, .init = nvkm_i2c_init, .fini = nvkm_i2c_fini, .intr = nvkm_i2c_intr, diff -Nrup linux-4.4.143/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c linux-4.4.189/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c --- linux-4.4.143/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c 2019-08-11 03:20:49.000000000 -0700 @@ -110,6 +110,19 @@ nvkm_i2c_bus_init(struct nvkm_i2c_bus *b BUS_TRACE(bus, "init"); if (bus->func->init) bus->func->init(bus); + + mutex_lock(&bus->mutex); + bus->enabled = true; + mutex_unlock(&bus->mutex); +} + +void +nvkm_i2c_bus_fini(struct nvkm_i2c_bus *bus) +{ + BUS_TRACE(bus, "fini"); + mutex_lock(&bus->mutex); + bus->enabled = false; + mutex_unlock(&bus->mutex); } void @@ -126,9 +139,15 @@ nvkm_i2c_bus_acquire(struct nvkm_i2c_bus { struct nvkm_i2c_pad *pad = bus->pad; int ret; + BUS_TRACE(bus, "acquire"); mutex_lock(&bus->mutex); - ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_I2C); + + if (bus->enabled) + ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_I2C); + else + ret = -EIO; + if (ret) mutex_unlock(&bus->mutex); return ret; diff -Nrup linux-4.4.143/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h linux-4.4.189/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h --- linux-4.4.143/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.h 2019-08-11 03:20:49.000000000 -0700 @@ -17,6 +17,7 @@ int nvkm_i2c_bus_new_(const struct nvkm_ int id, struct nvkm_i2c_bus **); void nvkm_i2c_bus_del(struct nvkm_i2c_bus **); void nvkm_i2c_bus_init(struct nvkm_i2c_bus *); +void nvkm_i2c_bus_fini(struct nvkm_i2c_bus *); int nvkm_i2c_bit_xfer(struct nvkm_i2c_bus *, struct i2c_msg *, int); diff -Nrup linux-4.4.143/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c linux-4.4.189/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c --- linux-4.4.143/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c 2019-08-11 03:20:49.000000000 -0700 @@ -262,6 +262,17 @@ static int dmm_txn_commit(struct dmm_txn } txn->last_pat->next_pa = 0; + /* ensure that the written descriptors are visible to DMM */ + wmb(); + + /* + * NOTE: the wmb() above should be enough, but there seems to be a bug + * in OMAP's memory barrier implementation, which in some rare cases may + * cause the writes not to be observable after wmb(). + */ + + /* read back to ensure the data is in RAM */ + readl(&txn->last_pat->next_pa); /* write to PAT_DESCR to clear out any pending transaction */ writel(0x0, dmm->base + reg[PAT_DESCR][engine->id]); diff -Nrup linux-4.4.143/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c linux-4.4.189/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c --- linux-4.4.143/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c 2019-08-11 03:20:49.000000000 -0700 @@ -823,7 +823,7 @@ static void s6e8aa0_read_mtp_id(struct s int ret, i; ret = s6e8aa0_dcs_read(ctx, 0xd1, id, ARRAY_SIZE(id)); - if (ret < ARRAY_SIZE(id) || id[0] == 0x00) { + if (ret < 0 || ret < ARRAY_SIZE(id) || id[0] == 0x00) { dev_err(ctx->dev, "read id failed\n"); ctx->error = -EIO; return; diff -Nrup linux-4.4.143/drivers/gpu/drm/panel/panel-simple.c linux-4.4.189/drivers/gpu/drm/panel/panel-simple.c --- linux-4.4.143/drivers/gpu/drm/panel/panel-simple.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/panel/panel-simple.c 2019-08-11 03:20:49.000000000 -0700 @@ -1389,7 +1389,14 @@ static int panel_simple_dsi_probe(struct dsi->format = desc->format; dsi->lanes = desc->lanes; - return mipi_dsi_attach(dsi); + err = mipi_dsi_attach(dsi); + if (err) { + struct panel_simple *panel = dev_get_drvdata(&dsi->dev); + + drm_panel_remove(&panel->base); + } + + return err; } static int panel_simple_dsi_remove(struct mipi_dsi_device *dsi) diff -Nrup linux-4.4.143/drivers/gpu/drm/radeon/evergreen_cs.c linux-4.4.189/drivers/gpu/drm/radeon/evergreen_cs.c --- linux-4.4.143/drivers/gpu/drm/radeon/evergreen_cs.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/radeon/evergreen_cs.c 2019-08-11 03:20:49.000000000 -0700 @@ -1299,6 +1299,7 @@ static int evergreen_cs_handle_reg(struc return -EINVAL; } ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); + break; case CB_TARGET_MASK: track->cb_target_mask = radeon_get_ib_value(p, idx); track->cb_dirty = true; diff -Nrup linux-4.4.143/drivers/gpu/drm/radeon/radeon_connectors.c linux-4.4.189/drivers/gpu/drm/radeon/radeon_connectors.c --- linux-4.4.143/drivers/gpu/drm/radeon/radeon_connectors.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/radeon/radeon_connectors.c 2019-08-11 03:20:49.000000000 -0700 @@ -844,7 +844,7 @@ static int radeon_lvds_get_modes(struct return ret; } -static int radeon_lvds_mode_valid(struct drm_connector *connector, +static enum drm_mode_status radeon_lvds_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct drm_encoder *encoder = radeon_best_single_encoder(connector); @@ -993,7 +993,7 @@ static int radeon_vga_get_modes(struct d return ret; } -static int radeon_vga_mode_valid(struct drm_connector *connector, +static enum drm_mode_status radeon_vga_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct drm_device *dev = connector->dev; @@ -1136,7 +1136,7 @@ static int radeon_tv_get_modes(struct dr return 1; } -static int radeon_tv_mode_valid(struct drm_connector *connector, +static enum drm_mode_status radeon_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { if ((mode->hdisplay > 1024) || (mode->vdisplay > 768)) @@ -1477,7 +1477,7 @@ static void radeon_dvi_force(struct drm_ radeon_connector->use_digital = true; } -static int radeon_dvi_mode_valid(struct drm_connector *connector, +static enum drm_mode_status radeon_dvi_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct drm_device *dev = connector->dev; @@ -1778,7 +1778,7 @@ out: return ret; } -static int radeon_dp_mode_valid(struct drm_connector *connector, +static enum drm_mode_status radeon_dp_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { struct drm_device *dev = connector->dev; diff -Nrup linux-4.4.143/drivers/gpu/drm/radeon/radeon_object.c linux-4.4.189/drivers/gpu/drm/radeon/radeon_object.c --- linux-4.4.143/drivers/gpu/drm/radeon/radeon_object.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/radeon/radeon_object.c 2019-08-11 03:20:49.000000000 -0700 @@ -447,6 +447,10 @@ void radeon_bo_force_delete(struct radeo int radeon_bo_init(struct radeon_device *rdev) { + /* reserve PAT memory space to WC for VRAM */ + arch_io_reserve_memtype_wc(rdev->mc.aper_base, + rdev->mc.aper_size); + /* Add an MTRR for the VRAM */ if (!rdev->fastfb_working) { rdev->mc.vram_mtrr = arch_phys_wc_add(rdev->mc.aper_base, @@ -464,6 +468,7 @@ void radeon_bo_fini(struct radeon_device { radeon_ttm_fini(rdev); arch_phys_wc_del(rdev->mc.vram_mtrr); + arch_io_free_memtype_wc(rdev->mc.aper_base, rdev->mc.aper_size); } /* Returns how many bytes TTM can move per IB. diff -Nrup linux-4.4.143/drivers/gpu/drm/radeon/radeon_ttm.c linux-4.4.189/drivers/gpu/drm/radeon/radeon_ttm.c --- linux-4.4.143/drivers/gpu/drm/radeon/radeon_ttm.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/radeon/radeon_ttm.c 2019-08-11 03:20:49.000000000 -0700 @@ -557,7 +557,7 @@ static int radeon_ttm_tt_pin_userptr(str struct page **pages = ttm->pages + pinned; r = get_user_pages(current, current->mm, userptr, num_pages, - write, 0, pages, NULL); + write ? FOLL_WRITE : 0, pages, NULL); if (r < 0) goto release_pages; diff -Nrup linux-4.4.143/drivers/gpu/drm/udl/udl_fb.c linux-4.4.189/drivers/gpu/drm/udl/udl_fb.c --- linux-4.4.143/drivers/gpu/drm/udl/udl_fb.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/udl/udl_fb.c 2019-08-11 03:20:49.000000000 -0700 @@ -341,7 +341,7 @@ static int udl_fb_open(struct fb_info *i struct fb_deferred_io *fbdefio; - fbdefio = kmalloc(sizeof(struct fb_deferred_io), GFP_KERNEL); + fbdefio = kzalloc(sizeof(struct fb_deferred_io), GFP_KERNEL); if (fbdefio) { fbdefio->delay = DL_DEFIO_WRITE_DELAY; diff -Nrup linux-4.4.143/drivers/gpu/drm/udl/udl_main.c linux-4.4.189/drivers/gpu/drm/udl/udl_main.c --- linux-4.4.143/drivers/gpu/drm/udl/udl_main.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/udl/udl_main.c 2019-08-11 03:20:49.000000000 -0700 @@ -141,18 +141,13 @@ static void udl_free_urb_list(struct drm struct list_head *node; struct urb_node *unode; struct urb *urb; - int ret; unsigned long flags; DRM_DEBUG("Waiting for completes and freeing all render urbs\n"); /* keep waiting and freeing, until we've got 'em all */ while (count--) { - - /* Getting interrupted means a leak, but ok at shutdown*/ - ret = down_interruptible(&udl->urbs.limit_sem); - if (ret) - break; + down(&udl->urbs.limit_sem); spin_lock_irqsave(&udl->urbs.lock, flags); @@ -176,17 +171,22 @@ static void udl_free_urb_list(struct drm static int udl_alloc_urb_list(struct drm_device *dev, int count, size_t size) { struct udl_device *udl = dev->dev_private; - int i = 0; struct urb *urb; struct urb_node *unode; char *buf; + size_t wanted_size = count * size; spin_lock_init(&udl->urbs.lock); +retry: udl->urbs.size = size; INIT_LIST_HEAD(&udl->urbs.list); - while (i < count) { + sema_init(&udl->urbs.limit_sem, 0); + udl->urbs.count = 0; + udl->urbs.available = 0; + + while (udl->urbs.count * size < wanted_size) { unode = kzalloc(sizeof(struct urb_node), GFP_KERNEL); if (!unode) break; @@ -202,11 +202,16 @@ static int udl_alloc_urb_list(struct drm } unode->urb = urb; - buf = usb_alloc_coherent(udl->udev, MAX_TRANSFER, GFP_KERNEL, + buf = usb_alloc_coherent(udl->udev, size, GFP_KERNEL, &urb->transfer_dma); if (!buf) { kfree(unode); usb_free_urb(urb); + if (size > PAGE_SIZE) { + size /= 2; + udl_free_urb_list(dev); + goto retry; + } break; } @@ -217,16 +222,14 @@ static int udl_alloc_urb_list(struct drm list_add_tail(&unode->entry, &udl->urbs.list); - i++; + up(&udl->urbs.limit_sem); + udl->urbs.count++; + udl->urbs.available++; } - sema_init(&udl->urbs.limit_sem, i); - udl->urbs.count = i; - udl->urbs.available = i; - - DRM_DEBUG("allocated %d %d byte urbs\n", i, (int) size); + DRM_DEBUG("allocated %d %d byte urbs\n", udl->urbs.count, (int) size); - return i; + return udl->urbs.count; } struct urb *udl_get_urb(struct drm_device *dev) diff -Nrup linux-4.4.143/drivers/gpu/drm/via/via_dmablit.c linux-4.4.189/drivers/gpu/drm/via/via_dmablit.c --- linux-4.4.143/drivers/gpu/drm/via/via_dmablit.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/via/via_dmablit.c 2019-08-11 03:20:49.000000000 -0700 @@ -242,8 +242,8 @@ via_lock_all_dma_pages(drm_via_sg_info_t ret = get_user_pages(current, current->mm, (unsigned long)xfer->mem_addr, vsg->num_pages, - (vsg->direction == DMA_FROM_DEVICE), - 0, vsg->pages, NULL); + (vsg->direction == DMA_FROM_DEVICE) ? FOLL_WRITE : 0, + vsg->pages, NULL); up_read(¤t->mm->mmap_sem); if (ret != vsg->num_pages) { diff -Nrup linux-4.4.143/drivers/gpu/drm/virtio/virtgpu_ioctl.c linux-4.4.189/drivers/gpu/drm/virtio/virtgpu_ioctl.c --- linux-4.4.143/drivers/gpu/drm/virtio/virtgpu_ioctl.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/virtio/virtgpu_ioctl.c 2019-08-11 03:20:49.000000000 -0700 @@ -535,6 +535,9 @@ static int virtio_gpu_get_caps_ioctl(str ret = wait_event_timeout(vgdev->resp_wq, atomic_read(&cache_ent->is_valid), 5 * HZ); + /* is_valid check must proceed before copy of the cache entry. */ + smp_rmb(); + ptr = cache_ent->caps_cache; copy_exit: diff -Nrup linux-4.4.143/drivers/gpu/drm/virtio/virtgpu_vq.c linux-4.4.189/drivers/gpu/drm/virtio/virtgpu_vq.c --- linux-4.4.143/drivers/gpu/drm/virtio/virtgpu_vq.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/virtio/virtgpu_vq.c 2019-08-11 03:20:49.000000000 -0700 @@ -618,6 +618,8 @@ static void virtio_gpu_cmd_capset_cb(str cache_ent->id == le32_to_cpu(cmd->capset_id)) { memcpy(cache_ent->caps_cache, resp->capset_data, cache_ent->size); + /* Copy must occur before is_valid is signalled. */ + smp_wmb(); atomic_set(&cache_ent->is_valid, 1); break; } diff -Nrup linux-4.4.143/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c linux-4.4.189/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c --- linux-4.4.143/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c 2019-08-11 03:20:49.000000000 -0700 @@ -594,13 +594,16 @@ out_fixup: static int vmw_dma_masks(struct vmw_private *dev_priv) { struct drm_device *dev = dev_priv->dev; + int ret = 0; - if (intel_iommu_enabled && + ret = dma_set_mask_and_coherent(dev->dev, DMA_BIT_MASK(64)); + if (dev_priv->map_mode != vmw_dma_phys && (sizeof(unsigned long) == 4 || vmw_restrict_dma_mask)) { DRM_INFO("Restricting DMA addresses to 44 bits.\n"); - return dma_set_mask(dev->dev, DMA_BIT_MASK(44)); + return dma_set_mask_and_coherent(dev->dev, DMA_BIT_MASK(44)); } - return 0; + + return ret; } #else static int vmw_dma_masks(struct vmw_private *dev_priv) diff -Nrup linux-4.4.143/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c linux-4.4.189/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c --- linux-4.4.143/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c 2019-08-11 03:20:49.000000000 -0700 @@ -2442,7 +2442,8 @@ static int vmw_cmd_dx_set_shader(struct cmd = container_of(header, typeof(*cmd), header); - if (cmd->body.type >= SVGA3D_SHADERTYPE_DX10_MAX) { + if (cmd->body.type >= SVGA3D_SHADERTYPE_DX10_MAX || + cmd->body.type < SVGA3D_SHADERTYPE_MIN) { DRM_ERROR("Illegal shader type %u.\n", (unsigned) cmd->body.type); return -EINVAL; @@ -2681,6 +2682,10 @@ static int vmw_cmd_dx_view_define(struct if (view_type == vmw_view_max) return -EINVAL; cmd = container_of(header, typeof(*cmd), header); + if (unlikely(cmd->sid == SVGA3D_INVALID_ID)) { + DRM_ERROR("Invalid surface id.\n"); + return -EINVAL; + } ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface, user_surface_converter, &cmd->sid, &srf_node); @@ -3663,7 +3668,7 @@ int vmw_execbuf_fence_commands(struct dr *p_fence = NULL; } - return 0; + return ret; } /** diff -Nrup linux-4.4.143/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c linux-4.4.189/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c --- linux-4.4.143/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c 2018-07-22 05:25:54.000000000 -0700 +++ linux-4.4.189/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c 2019-08-11 03:20:49.000000000 -0700 @@ -531,11 +531,9 @@ static int vmw_fb_set_par(struct fb_info 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }; - struct drm_display_mode *old_mode; struct drm_display_mode *mode; int ret; - old_mode = par->set_mode; mode = drm_mode_duplicate(vmw_priv->dev, &new_mode); if (!mode) { DRM_ERROR("Could not create new fb mode.\n"); @@ -546,11 +544,7 @@ static int vmw_fb_set_par(struct fb_info mode->vdisplay = var->yres; vmw_guess_mode_timing(mode); - if (old_mode && drm_mode_equal(old_mode, mode)) { - drm_mode_destroy(vmw_priv->dev, mode); - mode = old_mode; - old_mode = NULL; - } else if (!vmw_kms_validate_mode_vram(vmw_priv, + if (!vmw_kms_validate_mode_vram(vmw_priv, mode->hdisplay * DIV_ROUND_UP(var->bits_per_pixel, 8), mode->vdisplay)) { @@ -613,8 +607,8 @@ static int vmw_fb_set_par(struct fb_info schedule_delayed_work(&par->local_work, 0); out_unlock: - if (old_mode) - drm_mode_destroy(vmw_priv->dev, old_mode); + if (par->set_mode) + drm_mode_destroy(vmw_priv->dev, par->set_mode); par->set_mode = mode; drm_modeset_unlock_all(vmw_priv->dev);