[2.6.32+drm33-longterm] Linux 2.6.32.38+drm33.17
Stefan Bader
stefan.bader at canonical.com
Mon May 2 09:12:43 UTC 2011
On 05/02/2011 10:42 AM, Stefan Bader wrote:
> I am announcing the release of the 2.6.32.38+drm33.17 longterm tree.
>
> This tree is based on 2.6.32 and generally has all of the stable updates
> applied. Except those to the DRM subsystem, which was based on 2.6.33 and
> took updates from that upstream stable as long as that existed. It will
> continue to add patches to the DRM subsystem as long as they are valid
> according to the stable update rules (Documentation/stable_kernel_rules.txt).
> DRM patches for this tree should be sent to kernel-team at lists.ubuntu.com.
>
> This release updates the DRM subsystem only.
>
> The updated 2.6.32.y-drm33.z tree can be found at:
> git://git.kernel.org/pub/scm/linux/kernel/git/smb/linux-2.6.32.y-drm33.z.git
> and can be browsed through git web via:
> http://git.kernel.org/?p=linux/kernel/git/smb/linux-2.6.32.y-drm33.z.git;a=summary
>
> -Stefan
>
Note that last time I looked there were 2 changes we already carried through
security updates and one which we were carrying even longer (not to care about
the lid status).
-Stefan
> ------
>
> * drm/i915: set DIDL using the ACPI video output device _ADR method return.
> * drm/radeon/kms: MC vram map needs to be >= pci aperture size
> * drm/radeon/kms: make sure blit addr masks are 64 bit
> * drm/radeon/kms: fix handling of tex lookup disable in cs checker on r2xx
> * drm/i915: Free hardware status page on unload when physically mapped
> * drm/i915/overlay: Ensure that the reg_bo is in the GTT prior to writing.
> * drm/radeon/kms/atom: set sane defaults in atombios_get_encoder_mode()
> * drm/radeon/kms: fix typos in disabled vbios code
> * drm/radeon/kms: add workaround for dce3 ddc line vbios bug
> * drm/radeon/kms: fix interlaced and doublescan handling
> * drm/i915/sdvo: Always add a 30ms delay to make SDVO TV detection reliable
> * drm/radeon/kms: don't apply 7xx HDP flush workaround on AGP
> * drm/ttm: Fix two race conditions + fix busy codepaths
> * drm/i915: overlay on gen2 can't address above 1G
> * drm/i915: fix memory corruption with GM965 and >4GB RAM
> * drm/radeon: add quirk to make HP nx6125 laptop resume.
> * drm/radeon/kms: add quirk to make HP DV5000 laptop resume
> * drm/i915: Sanity check pread/pwrite
> * drm/i915: Rephrase pwrite bounds checking to avoid any potential overflow
> * drm/i915: Stop trying to use ACPI lid status to determine LVDS connection.
> * Linux 2.6.32.38+drm33.17
>
> Makefile | 2 +-
> drivers/gpu/drm/i915/i915_dma.c | 18 ++++++
> drivers/gpu/drm/i915/i915_gem.c | 44 ++++++++-------
> drivers/gpu/drm/i915/i915_opregion.c | 54 ++++++++++++++++-
> drivers/gpu/drm/i915/intel_lvds.c | 52 +-----------------
> drivers/gpu/drm/i915/intel_overlay.c | 8 +++
> drivers/gpu/drm/i915/intel_sdvo.c | 8 +-
> drivers/gpu/drm/radeon/r100.c | 6 ++
> drivers/gpu/drm/radeon/r100_track.h | 1 +
> drivers/gpu/drm/radeon/r200.c | 2 +
> drivers/gpu/drm/radeon/r600.c | 11 +++-
> drivers/gpu/drm/radeon/r600_blit_kms.c | 8 +-
> drivers/gpu/drm/radeon/r600_reg.h | 1 +
> drivers/gpu/drm/radeon/radeon_atombios.c | 8 +++
> drivers/gpu/drm/radeon/radeon_bios.c | 12 ++--
> drivers/gpu/drm/radeon/radeon_combios.c | 16 +++++
> drivers/gpu/drm/radeon/radeon_connectors.c | 34 +++++++++++
> drivers/gpu/drm/radeon/radeon_encoders.c | 18 +++++-
> drivers/gpu/drm/radeon/radeon_reg.h | 1 +
> drivers/gpu/drm/ttm/ttm_bo.c | 84 +++++++++++++++++++++++----
> include/drm/ttm/ttm_bo_api.h | 4 +-
> 21 files changed, 282 insertions(+), 110 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index 6b2feae..8ea6c3f 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -1,7 +1,7 @@
> VERSION = 2
> PATCHLEVEL = 6
> SUBLEVEL = 32
> -EXTRAVERSION = .38+drm33.16
> +EXTRAVERSION = .38+drm33.17
> NAME = Man-Eating Seals of Antiquity
>
> # *DOCUMENTATION*
> diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
> index 7f13d50..be27acc 100644
> --- a/drivers/gpu/drm/i915/i915_dma.c
> +++ b/drivers/gpu/drm/i915/i915_dma.c
> @@ -1407,6 +1407,21 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
> goto free_priv;
> }
>
> + /* overlay on gen2 is broken and can't address above 1G */
> + if (IS_GEN2(dev))
> + pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(30));
> +
> + /* 965GM sometimes incorrectly writes to hardware status page (HWS)
> + * using 32bit addressing, overwriting memory if HWS is located
> + * above 4GB.
> + *
> + * The documentation also mentions an issue with undefined
> + * behaviour if any general state is accessed within a page above 4GB,
> + * which also needs to be handled carefully.
> + */
> + if (IS_I965G(dev) && !IS_G4X(dev) && !IS_IRONLAKE(dev))
> + pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(32));
> +
> dev_priv->regs = ioremap(base, size);
> if (!dev_priv->regs) {
> DRM_ERROR("failed to map registers\n");
> @@ -1583,6 +1598,9 @@ int i915_driver_unload(struct drm_device *dev)
> i915_gem_lastclose(dev);
>
> intel_cleanup_overlay(dev);
> +
> + if (!I915_NEED_GFX_HWS(dev))
> + i915_free_hws(dev);
> }
>
> pci_dev_put(dev_priv->bridge_dev);
> diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> index ad3c4a2..a34fd44 100644
> --- a/drivers/gpu/drm/i915/i915_gem.c
> +++ b/drivers/gpu/drm/i915/i915_gem.c
> @@ -482,14 +482,17 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
> return -EBADF;
> obj_priv = obj->driver_private;
>
> - /* Bounds check source.
> - *
> - * XXX: This could use review for overflow issues...
> - */
> - if (args->offset > obj->size || args->size > obj->size ||
> - args->offset + args->size > obj->size) {
> - drm_gem_object_unreference(obj);
> - return -EINVAL;
> + /* Bounds check source. */
> + if (args->offset > obj->size || args->size > obj->size - args->offset) {
> + ret = -EINVAL;
> + goto err;
> + }
> +
> + if (!access_ok(VERIFY_WRITE,
> + (char __user *)(uintptr_t)args->data_ptr,
> + args->size)) {
> + ret = -EFAULT;
> + goto err;
> }
>
> if (i915_gem_object_needs_bit17_swizzle(obj)) {
> @@ -501,8 +504,8 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data,
> file_priv);
> }
>
> +err:
> drm_gem_object_unreference(obj);
> -
> return ret;
> }
>
> @@ -592,8 +595,6 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj,
>
> user_data = (char __user *) (uintptr_t) args->data_ptr;
> remain = args->size;
> - if (!access_ok(VERIFY_READ, user_data, remain))
> - return -EFAULT;
>
>
> mutex_lock(&dev->struct_mutex);
> @@ -955,14 +956,17 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
> return -EBADF;
> obj_priv = obj->driver_private;
>
> - /* Bounds check destination.
> - *
> - * XXX: This could use review for overflow issues...
> - */
> - if (args->offset > obj->size || args->size > obj->size ||
> - args->offset + args->size > obj->size) {
> - drm_gem_object_unreference(obj);
> - return -EINVAL;
> + /* Bounds check destination. */
> + if (args->offset > obj->size || args->size > obj->size - args->offset) {
> + ret = -EINVAL;
> + goto err;
> + }
> +
> + if (!access_ok(VERIFY_READ,
> + (char __user *)(uintptr_t)args->data_ptr,
> + args->size)) {
> + ret = -EFAULT;
> + goto err;
> }
>
> /* We can only do the GTT pwrite on untiled buffers, as otherwise
> @@ -995,8 +999,8 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
> DRM_INFO("pwrite failed %d\n", ret);
> #endif
>
> +err:
> drm_gem_object_unreference(obj);
> -
> return ret;
> }
>
> diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
> index 7cc8410..8fcc75c 100644
> --- a/drivers/gpu/drm/i915/i915_opregion.c
> +++ b/drivers/gpu/drm/i915/i915_opregion.c
> @@ -382,8 +382,57 @@ static void intel_didl_outputs(struct drm_device *dev)
> struct drm_i915_private *dev_priv = dev->dev_private;
> struct intel_opregion *opregion = &dev_priv->opregion;
> struct drm_connector *connector;
> + acpi_handle handle;
> + struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL;
> + unsigned long long device_id;
> + acpi_status status;
> int i = 0;
>
> + handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev);
> + if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev)))
> + return;
> +
> + if (acpi_is_video_device(acpi_dev))
> + acpi_video_bus = acpi_dev;
> + else {
> + list_for_each_entry(acpi_cdev, &acpi_dev->children, node) {
> + if (acpi_is_video_device(acpi_cdev)) {
> + acpi_video_bus = acpi_cdev;
> + break;
> + }
> + }
> + }
> +
> + if (!acpi_video_bus) {
> + printk(KERN_WARNING "No ACPI video bus found\n");
> + return;
> + }
> +
> + list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) {
> + if (i >= 8) {
> + dev_printk (KERN_ERR, &dev->pdev->dev,
> + "More than 8 outputs detected\n");
> + return;
> + }
> + status =
> + acpi_evaluate_integer(acpi_cdev->handle, "_ADR",
> + NULL, &device_id);
> + if (ACPI_SUCCESS(status)) {
> + if (!device_id)
> + goto blind_set;
> + opregion->acpi->didl[i] = (u32)(device_id & 0x0f0f);
> + i++;
> + }
> + }
> +
> +end:
> + /* If fewer than 8 outputs, the list must be null terminated */
> + if (i < 8)
> + opregion->acpi->didl[i] = 0;
> + return;
> +
> +blind_set:
> + i = 0;
> list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
> int output_type = ACPI_OTHER_OUTPUT;
> if (i >= 8) {
> @@ -416,10 +465,7 @@ static void intel_didl_outputs(struct drm_device *dev)
> opregion->acpi->didl[i] |= (1<<31) | output_type | i;
> i++;
> }
> -
> - /* If fewer than 8 outputs, the list must be null terminated */
> - if (i < 8)
> - opregion->acpi->didl[i] = 0;
> + goto end;
> }
>
> int intel_opregion_init(struct drm_device *dev, int resume)
> diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> index 49c724e..d34c09f 100644
> --- a/drivers/gpu/drm/i915/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/intel_lvds.c
> @@ -599,53 +599,6 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
> I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control);
> }
>
> -/* Some lid devices report incorrect lid status, assume they're connected */
> -static const struct dmi_system_id bad_lid_status[] = {
> - {
> - .ident = "Compaq nx9020",
> - .matches = {
> - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
> - DMI_MATCH(DMI_BOARD_NAME, "3084"),
> - },
> - },
> - {
> - .ident = "Samsung SX20S",
> - .matches = {
> - DMI_MATCH(DMI_SYS_VENDOR, "Samsung Electronics"),
> - DMI_MATCH(DMI_BOARD_NAME, "SX20S"),
> - },
> - },
> - {
> - .ident = "Aspire One",
> - .matches = {
> - DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
> - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire one"),
> - },
> - },
> - {
> - .ident = "Aspire 1810T",
> - .matches = {
> - DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
> - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1810T"),
> - },
> - },
> - {
> - .ident = "PC-81005",
> - .matches = {
> - DMI_MATCH(DMI_SYS_VENDOR, "MALATA"),
> - DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"),
> - },
> - },
> - {
> - .ident = "Clevo M5x0N",
> - .matches = {
> - DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."),
> - DMI_MATCH(DMI_BOARD_NAME, "M5x0N"),
> - },
> - },
> - { }
> -};
> -
> /**
> * Detect the LVDS connection.
> *
> @@ -661,12 +614,9 @@ static enum drm_connector_status intel_lvds_detect(struct drm_connector *connect
> /* ACPI lid methods were generally unreliable in this generation, so
> * don't even bother.
> */
> - if (IS_GEN2(dev))
> + if (IS_GEN2(dev) || IS_GEN3(dev))
> return connector_status_connected;
>
> - if (!dmi_check_system(bad_lid_status) && !acpi_lid_open())
> - status = connector_status_disconnected;
> -
> return status;
> }
>
> diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c
> index ed4058e..f240e17 100644
> --- a/drivers/gpu/drm/i915/intel_overlay.c
> +++ b/drivers/gpu/drm/i915/intel_overlay.c
> @@ -1371,6 +1371,12 @@ void intel_setup_overlay(struct drm_device *dev)
> goto out_free_bo;
> }
> overlay->flip_addr = overlay->reg_bo->gtt_offset;
> +
> + ret = i915_gem_object_set_to_gtt_domain(reg_bo, true);
> + if (ret) {
> + DRM_ERROR("failed to move overlay register bo into the GTT\n");
> + goto out_unpin_bo;
> + }
> } else {
> ret = i915_gem_attach_phys_object(dev, reg_bo,
> I915_GEM_PHYS_OVERLAY_REGS);
> @@ -1402,6 +1408,8 @@ void intel_setup_overlay(struct drm_device *dev)
> DRM_INFO("initialized overlay support\n");
> return;
>
> +out_unpin_bo:
> + i915_gem_object_unpin(reg_bo);
> out_free_bo:
> drm_gem_object_unreference(reg_bo);
> out_free:
> diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
> index 48daee5..fe83986 100644
> --- a/drivers/gpu/drm/i915/intel_sdvo.c
> +++ b/drivers/gpu/drm/i915/intel_sdvo.c
> @@ -1693,10 +1693,10 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect
>
> intel_sdvo_write_cmd(intel_output,
> SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
> - if (sdvo_priv->is_tv) {
> - /* add 30ms delay when the output type is SDVO-TV */
> - mdelay(30);
> - }
> + /* add 30ms delay when the output type might be TV */
> + if (sdvo_priv->caps.output_flags &
> + (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_CVBS0))
> + mdelay(30);
> status = intel_sdvo_read_response(intel_output, &response, 2);
>
> DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8);
> diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
> index 947570c..6021e91 100644
> --- a/drivers/gpu/drm/radeon/r100.c
> +++ b/drivers/gpu/drm/radeon/r100.c
> @@ -1918,6 +1918,9 @@ void r100_vram_init_sizes(struct radeon_device *rdev)
> rdev->mc.vram_location = 0xFFFFFFFFUL;
> /* Fix for RN50, M6, M7 with 8/16/32(??) MBs of VRAM -
> * Novell bug 204882 + along with lots of ubuntu ones */
> + if (rdev->mc.aper_size > config_aper_size)
> + config_aper_size = rdev->mc.aper_size;
> +
> if (config_aper_size > rdev->mc.real_vram_size)
> rdev->mc.mc_vram_size = config_aper_size;
> else
> @@ -2825,6 +2828,8 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
> for (u = 0; u < track->num_texture; u++) {
> if (!track->textures[u].enabled)
> continue;
> + if (track->textures[u].lookup_disable)
> + continue;
> robj = track->textures[u].robj;
> if (robj == NULL) {
> DRM_ERROR("No texture bound to unit %u\n", u);
> @@ -3073,6 +3078,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track
> track->textures[i].robj = NULL;
> /* CS IB emission code makes sure texture unit are disabled */
> track->textures[i].enabled = false;
> + track->textures[i].lookup_disable = false;
> track->textures[i].roundup_w = true;
> track->textures[i].roundup_h = true;
> if (track->separate_cube)
> diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h
> index a2fada0..e19ef4a 100644
> --- a/drivers/gpu/drm/radeon/r100_track.h
> +++ b/drivers/gpu/drm/radeon/r100_track.h
> @@ -46,6 +46,7 @@ struct r100_cs_track_texture {
> unsigned height_11;
> bool use_pitch;
> bool enabled;
> + bool lookup_disable;
> bool roundup_w;
> bool roundup_h;
> unsigned compress_format;
> diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c
> index f890fd3..7ebd2ba 100644
> --- a/drivers/gpu/drm/radeon/r200.c
> +++ b/drivers/gpu/drm/radeon/r200.c
> @@ -400,6 +400,8 @@ int r200_packet0_check(struct radeon_cs_parser *p,
> track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
> track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
> }
> + if (idx_value & R200_TXFORMAT_LOOKUP_DISABLE)
> + track->textures[i].lookup_disable = true;
> switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) {
> case R200_TXFORMAT_I8:
> case R200_TXFORMAT_RGB332:
> diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
> index 814a621..3d70f6c 100644
> --- a/drivers/gpu/drm/radeon/r600.c
> +++ b/drivers/gpu/drm/radeon/r600.c
> @@ -371,12 +371,15 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)
> u32 tmp;
>
> /* flush hdp cache so updates hit vram */
> - if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) {
> + if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
> + !(rdev->flags & RADEON_IS_AGP)) {
> void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
> u32 tmp;
>
> /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read
> * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
> + * This seems to cause problems on some AGP cards. Just use the old
> + * method for them.
> */
> WREG32(HDP_DEBUG1, 0);
> tmp = readl((void __iomem *)ptr);
> @@ -2940,10 +2943,12 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev)
> void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo)
> {
> /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read
> - * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
> + * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL.
> + * This seems to cause problems on some AGP cards. Just use the old
> + * method for them.
> */
> if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
> - rdev->vram_scratch.ptr) {
> + rdev->vram_scratch.ptr && !(rdev->flags & RADEON_IS_AGP)) {
> void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
> u32 tmp;
>
> diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c
> index 446b765..d6a30a9 100644
> --- a/drivers/gpu/drm/radeon/r600_blit_kms.c
> +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
> @@ -629,8 +629,8 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
> int src_x = src_gpu_addr & 255;
> int dst_x = dst_gpu_addr & 255;
> int h = 1;
> - src_gpu_addr = src_gpu_addr & ~255;
> - dst_gpu_addr = dst_gpu_addr & ~255;
> + src_gpu_addr = src_gpu_addr & ~255ULL;
> + dst_gpu_addr = dst_gpu_addr & ~255ULL;
>
> if (!src_x && !dst_x) {
> h = (cur_size / max_bytes);
> @@ -723,8 +723,8 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
> int src_x = (src_gpu_addr & 255);
> int dst_x = (dst_gpu_addr & 255);
> int h = 1;
> - src_gpu_addr = src_gpu_addr & ~255;
> - dst_gpu_addr = dst_gpu_addr & ~255;
> + src_gpu_addr = src_gpu_addr & ~255ULL;
> + dst_gpu_addr = dst_gpu_addr & ~255ULL;
>
> if (!src_x && !dst_x) {
> h = (cur_size / max_bytes);
> diff --git a/drivers/gpu/drm/radeon/r600_reg.h b/drivers/gpu/drm/radeon/r600_reg.h
> index d0e28ff..fb3dfef 100644
> --- a/drivers/gpu/drm/radeon/r600_reg.h
> +++ b/drivers/gpu/drm/radeon/r600_reg.h
> @@ -86,6 +86,7 @@
> #define R600_HDP_NONSURFACE_BASE 0x2c04
>
> #define R600_BUS_CNTL 0x5420
> +# define R600_BIOS_ROM_DIS (1 << 1)
> #define R600_CONFIG_CNTL 0x5424
> #define R600_CONFIG_MEMSIZE 0x5428
> #define R600_CONFIG_F0_BASE 0x542C
> diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
> index 7c9b013..cddf2c9 100644
> --- a/drivers/gpu/drm/radeon/radeon_atombios.c
> +++ b/drivers/gpu/drm/radeon/radeon_atombios.c
> @@ -83,6 +83,14 @@ static inline struct radeon_i2c_bus_rec radeon_lookup_i2c_gpio(struct radeon_dev
> for (i = 0; i < ATOM_MAX_SUPPORTED_DEVICE; i++) {
> gpio = &i2c_info->asGPIO_Info[i];
>
> + /* some DCE3 boards have bad data for this entry */
> + if (ASIC_IS_DCE3(rdev)) {
> + if ((i == 4) &&
> + (gpio->usClkMaskRegisterIndex == 0x1fda) &&
> + (gpio->sucI2cId.ucAccess == 0x94))
> + gpio->sucI2cId.ucAccess = 0x14;
> + }
> +
> if (gpio->sucI2cId.ucAccess == id) {
> i2c.mask_clk_reg = le16_to_cpu(gpio->usClkMaskRegisterIndex) * 4;
> i2c.mask_data_reg = le16_to_cpu(gpio->usDataMaskRegisterIndex) * 4;
> diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
> index 9069217..cd734bd 100644
> --- a/drivers/gpu/drm/radeon/radeon_bios.c
> +++ b/drivers/gpu/drm/radeon/radeon_bios.c
> @@ -106,7 +106,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev)
> bool r;
>
> viph_control = RREG32(RADEON_VIPH_CONTROL);
> - bus_cntl = RREG32(RADEON_BUS_CNTL);
> + bus_cntl = RREG32(R600_BUS_CNTL);
> d1vga_control = RREG32(AVIVO_D1VGA_CONTROL);
> d2vga_control = RREG32(AVIVO_D2VGA_CONTROL);
> vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL);
> @@ -115,7 +115,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev)
> /* disable VIP */
> WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN));
> /* enable the rom */
> - WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM));
> + WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
> /* Disable VGA mode */
> WREG32(AVIVO_D1VGA_CONTROL,
> (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE |
> @@ -154,7 +154,7 @@ static bool r700_read_disabled_bios(struct radeon_device *rdev)
> cg_spll_status = RREG32(R600_CG_SPLL_STATUS);
> }
> WREG32(RADEON_VIPH_CONTROL, viph_control);
> - WREG32(RADEON_BUS_CNTL, bus_cntl);
> + WREG32(R600_BUS_CNTL, bus_cntl);
> WREG32(AVIVO_D1VGA_CONTROL, d1vga_control);
> WREG32(AVIVO_D2VGA_CONTROL, d2vga_control);
> WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control);
> @@ -179,7 +179,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev)
> bool r;
>
> viph_control = RREG32(RADEON_VIPH_CONTROL);
> - bus_cntl = RREG32(RADEON_BUS_CNTL);
> + bus_cntl = RREG32(R600_BUS_CNTL);
> d1vga_control = RREG32(AVIVO_D1VGA_CONTROL);
> d2vga_control = RREG32(AVIVO_D2VGA_CONTROL);
> vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL);
> @@ -194,7 +194,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev)
> /* disable VIP */
> WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN));
> /* enable the rom */
> - WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM));
> + WREG32(R600_BUS_CNTL, (bus_cntl & ~R600_BIOS_ROM_DIS));
> /* Disable VGA mode */
> WREG32(AVIVO_D1VGA_CONTROL,
> (d1vga_control & ~(AVIVO_DVGA_CONTROL_MODE_ENABLE |
> @@ -225,7 +225,7 @@ static bool r600_read_disabled_bios(struct radeon_device *rdev)
>
> /* restore regs */
> WREG32(RADEON_VIPH_CONTROL, viph_control);
> - WREG32(RADEON_BUS_CNTL, bus_cntl);
> + WREG32(R600_BUS_CNTL, bus_cntl);
> WREG32(AVIVO_D1VGA_CONTROL, d1vga_control);
> WREG32(AVIVO_D2VGA_CONTROL, d2vga_control);
> WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control);
> diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
> index 44770b9..16024e2 100644
> --- a/drivers/gpu/drm/radeon/radeon_combios.c
> +++ b/drivers/gpu/drm/radeon/radeon_combios.c
> @@ -2849,6 +2849,22 @@ void radeon_combios_asic_init(struct drm_device *dev)
> combios_write_ram_size(dev);
> }
>
> + /* quirk for rs4xx HP nx6125 laptop to make it resume
> + * - it hangs on resume inside the dynclk 1 table.
> + */
> + if (rdev->family == CHIP_RS480 &&
> + rdev->pdev->subsystem_vendor == 0x103c &&
> + rdev->pdev->subsystem_device == 0x308b)
> + return;
> +
> + /* quirk for rs4xx HP dv5000 laptop to make it resume
> + * - it hangs on resume inside the dynclk 1 table.
> + */
> + if (rdev->family == CHIP_RS480 &&
> + rdev->pdev->subsystem_vendor == 0x103c &&
> + rdev->pdev->subsystem_device == 0x30a4)
> + return;
> +
> /* DYN CLK 1 */
> table = combios_get_table_offset(dev, COMBIOS_DYN_CLK_1_TABLE);
> if (table)
> diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
> index c263f8e..e9f8c44 100644
> --- a/drivers/gpu/drm/radeon/radeon_connectors.c
> +++ b/drivers/gpu/drm/radeon/radeon_connectors.c
> @@ -1095,6 +1095,8 @@ radeon_add_atom_connector(struct drm_device *dev,
> drm_connector_attach_property(&radeon_connector->base,
> rdev->mode_info.load_detect_property,
> 1);
> + connector->interlace_allowed = true;
> + connector->doublescan_allowed = true;
> break;
> case DRM_MODE_CONNECTOR_DVIA:
> drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
> @@ -1110,6 +1112,8 @@ radeon_add_atom_connector(struct drm_device *dev,
> drm_connector_attach_property(&radeon_connector->base,
> rdev->mode_info.load_detect_property,
> 1);
> + connector->interlace_allowed = true;
> + connector->doublescan_allowed = true;
> break;
> case DRM_MODE_CONNECTOR_DVII:
> case DRM_MODE_CONNECTOR_DVID:
> @@ -1138,6 +1142,11 @@ radeon_add_atom_connector(struct drm_device *dev,
> rdev->mode_info.load_detect_property,
> 1);
> }
> + connector->interlace_allowed = true;
> + if (connector_type == DRM_MODE_CONNECTOR_DVII)
> + connector->doublescan_allowed = true;
> + else
> + connector->doublescan_allowed = false;
> break;
> case DRM_MODE_CONNECTOR_HDMIA:
> case DRM_MODE_CONNECTOR_HDMIB:
> @@ -1160,6 +1169,11 @@ radeon_add_atom_connector(struct drm_device *dev,
> rdev->mode_info.coherent_mode_property,
> 1);
> subpixel_order = SubPixelHorizontalRGB;
> + connector->interlace_allowed = true;
> + if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
> + connector->doublescan_allowed = true;
> + else
> + connector->doublescan_allowed = false;
> break;
> case DRM_MODE_CONNECTOR_DisplayPort:
> case DRM_MODE_CONNECTOR_eDP:
> @@ -1192,6 +1206,9 @@ radeon_add_atom_connector(struct drm_device *dev,
> drm_connector_attach_property(&radeon_connector->base,
> rdev->mode_info.coherent_mode_property,
> 1);
> + connector->interlace_allowed = true;
> + /* in theory with a DP to VGA converter... */
> + connector->doublescan_allowed = false;
> break;
> case DRM_MODE_CONNECTOR_SVIDEO:
> case DRM_MODE_CONNECTOR_Composite:
> @@ -1209,6 +1226,8 @@ radeon_add_atom_connector(struct drm_device *dev,
> rdev->mode_info.tv_std_property,
> radeon_atombios_get_tv_info(rdev));
> }
> + connector->interlace_allowed = false;
> + connector->doublescan_allowed = false;
> break;
> case DRM_MODE_CONNECTOR_LVDS:
> radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
> @@ -1230,6 +1249,8 @@ radeon_add_atom_connector(struct drm_device *dev,
> dev->mode_config.scaling_mode_property,
> DRM_MODE_SCALE_FULLSCREEN);
> subpixel_order = SubPixelHorizontalRGB;
> + connector->interlace_allowed = false;
> + connector->doublescan_allowed = false;
> break;
> }
>
> @@ -1297,6 +1318,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
> drm_connector_attach_property(&radeon_connector->base,
> rdev->mode_info.load_detect_property,
> 1);
> + connector->interlace_allowed = true;
> + connector->doublescan_allowed = true;
> break;
> case DRM_MODE_CONNECTOR_DVIA:
> drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
> @@ -1312,6 +1335,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
> drm_connector_attach_property(&radeon_connector->base,
> rdev->mode_info.load_detect_property,
> 1);
> + connector->interlace_allowed = true;
> + connector->doublescan_allowed = true;
> break;
> case DRM_MODE_CONNECTOR_DVII:
> case DRM_MODE_CONNECTOR_DVID:
> @@ -1329,6 +1354,11 @@ radeon_add_legacy_connector(struct drm_device *dev,
> 1);
> }
> subpixel_order = SubPixelHorizontalRGB;
> + connector->interlace_allowed = true;
> + if (connector_type == DRM_MODE_CONNECTOR_DVII)
> + connector->doublescan_allowed = true;
> + else
> + connector->doublescan_allowed = false;
> break;
> case DRM_MODE_CONNECTOR_SVIDEO:
> case DRM_MODE_CONNECTOR_Composite:
> @@ -1353,6 +1383,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
> rdev->mode_info.tv_std_property,
> radeon_combios_get_tv_info(rdev));
> }
> + connector->interlace_allowed = false;
> + connector->doublescan_allowed = false;
> break;
> case DRM_MODE_CONNECTOR_LVDS:
> drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
> @@ -1368,6 +1400,8 @@ radeon_add_legacy_connector(struct drm_device *dev,
> dev->mode_config.scaling_mode_property,
> DRM_MODE_SCALE_FULLSCREEN);
> subpixel_order = SubPixelHorizontalRGB;
> + connector->interlace_allowed = false;
> + connector->doublescan_allowed = false;
> break;
> }
>
> diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c
> index 7626bd5..ea55516 100644
> --- a/drivers/gpu/drm/radeon/radeon_encoders.c
> +++ b/drivers/gpu/drm/radeon/radeon_encoders.c
> @@ -587,11 +587,23 @@ atombios_get_encoder_mode(struct drm_encoder *encoder)
> struct drm_connector *connector;
> struct radeon_connector *radeon_connector;
> struct radeon_connector_atom_dig *radeon_dig_connector;
> + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
>
> connector = radeon_get_connector_for_encoder(encoder);
> - if (!connector)
> - return 0;
> -
> + if (!connector) {
> + switch (radeon_encoder->encoder_id) {
> + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
> + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
> + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
> + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
> + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
> + return ATOM_ENCODER_MODE_DVI;
> + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
> + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
> + default:
> + return ATOM_ENCODER_MODE_CRT;
> + }
> + }
> radeon_connector = to_radeon_connector(connector);
>
> switch (connector->connector_type) {
> diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h
> index 6d0a009..57bcc8e 100644
> --- a/drivers/gpu/drm/radeon/radeon_reg.h
> +++ b/drivers/gpu/drm/radeon/radeon_reg.h
> @@ -2827,6 +2827,7 @@
> # define R200_TXFORMAT_ST_ROUTE_STQ5 (5 << 24)
> # define R200_TXFORMAT_ST_ROUTE_MASK (7 << 24)
> # define R200_TXFORMAT_ST_ROUTE_SHIFT 24
> +# define R200_TXFORMAT_LOOKUP_DISABLE (1 << 27)
> # define R200_TXFORMAT_ALPHA_MASK_ENABLE (1 << 28)
> # define R200_TXFORMAT_CHROMA_KEY_ENABLE (1 << 29)
> # define R200_TXFORMAT_CUBIC_MAP_ENABLE (1 << 30)
> diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
> index c7320ce..acbfa27 100644
> --- a/drivers/gpu/drm/ttm/ttm_bo.c
> +++ b/drivers/gpu/drm/ttm/ttm_bo.c
> @@ -443,6 +443,43 @@ out_err:
> }
>
> /**
> + * Call bo::reserved and with the lru lock held.
> + * Will release GPU memory type usage on destruction.
> + * This is the place to put in driver specific hooks.
> + * Will release the bo::reserved lock and the
> + * lru lock on exit.
> + */
> +
> +static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo)
> +{
> + struct ttm_bo_global *glob = bo->glob;
> +
> + if (bo->ttm) {
> +
> + /**
> + * Release the lru_lock, since we don't want to have
> + * an atomic requirement on ttm_tt[unbind|destroy].
> + */
> +
> + spin_unlock(&glob->lru_lock);
> + ttm_tt_unbind(bo->ttm);
> + ttm_tt_destroy(bo->ttm);
> + bo->ttm = NULL;
> + spin_lock(&glob->lru_lock);
> + }
> +
> + if (bo->mem.mm_node) {
> + drm_mm_put_block(bo->mem.mm_node);
> + bo->mem.mm_node = NULL;
> + }
> +
> + atomic_set(&bo->reserved, 0);
> + wake_up_all(&bo->event_queue);
> + spin_unlock(&glob->lru_lock);
> +}
> +
> +
> +/**
> * If bo idle, remove from delayed- and lru lists, and unref.
> * If not idle, and already on delayed list, do nothing.
> * If not idle, and not on delayed list, put on delayed list,
> @@ -457,6 +494,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
> int ret;
>
> spin_lock(&bo->lock);
> +retry:
> (void) ttm_bo_wait(bo, false, false, !remove_all);
>
> if (!bo->sync_obj) {
> @@ -465,32 +503,52 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool remove_all)
> spin_unlock(&bo->lock);
>
> spin_lock(&glob->lru_lock);
> - put_count = ttm_bo_del_from_lru(bo);
> + ret = ttm_bo_reserve_locked(bo, false, !remove_all, false, 0);
> +
> + /**
> + * Someone else has the object reserved. Bail and retry.
> + */
>
> - ret = ttm_bo_reserve_locked(bo, false, false, false, 0);
> - BUG_ON(ret);
> - if (bo->ttm)
> - ttm_tt_unbind(bo->ttm);
> + if (unlikely(ret == -EBUSY)) {
> + spin_unlock(&glob->lru_lock);
> + spin_lock(&bo->lock);
> + goto requeue;
> + }
> +
> + /**
> + * We can re-check for sync object without taking
> + * the bo::lock since setting the sync object requires
> + * also bo::reserved. A busy object at this point may
> + * be caused by another thread starting an accelerated
> + * eviction.
> + */
> +
> + if (unlikely(bo->sync_obj)) {
> + atomic_set(&bo->reserved, 0);
> + wake_up_all(&bo->event_queue);
> + spin_unlock(&glob->lru_lock);
> + spin_lock(&bo->lock);
> + if (remove_all)
> + goto retry;
> + else
> + goto requeue;
> + }
> +
> + put_count = ttm_bo_del_from_lru(bo);
>
> if (!list_empty(&bo->ddestroy)) {
> list_del_init(&bo->ddestroy);
> ++put_count;
> }
> - if (bo->mem.mm_node) {
> - bo->mem.mm_node->private = NULL;
> - drm_mm_put_block(bo->mem.mm_node);
> - bo->mem.mm_node = NULL;
> - }
> - spin_unlock(&glob->lru_lock);
>
> - atomic_set(&bo->reserved, 0);
> + ttm_bo_cleanup_memtype_use(bo);
>
> while (put_count--)
> kref_put(&bo->list_kref, ttm_bo_ref_bug);
>
> return 0;
> }
> -
> +requeue:
> spin_lock(&glob->lru_lock);
> if (list_empty(&bo->ddestroy)) {
> void *sync_obj = bo->sync_obj;
> diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h
> index 81eb9f4..d30dc3c 100644
> --- a/include/drm/ttm/ttm_bo_api.h
> +++ b/include/drm/ttm/ttm_bo_api.h
> @@ -224,9 +224,11 @@ struct ttm_buffer_object {
>
> atomic_t reserved;
>
> -
> /**
> * Members protected by the bo::lock
> + * In addition, setting sync_obj to anything else
> + * than NULL requires bo::reserved to be held. This allows for
> + * checking NULL while reserved but not holding bo::lock.
> */
>
> void *sync_obj_arg;
>
More information about the kernel-team
mailing list