Commit 2c35cd01 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6

* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
  drm/radeon/kms: only warn on mipmap size checks in r600 cs checker (v2)
  drm/radeon/kms: force legacy pll algo for RV620 LVDS
  drm: fix race between driver loading and userspace open.
  drm: Use a nondestructive mode for output detect when polling (v2)
  drm/radeon/kms: fix the colorbuffer CS checker for r300-r500
  drm/radeon/kms: increase lockup detection interval to 10 sec for r100-r500
  drm/radeon/kms/evergreen: fix backend setup
  drm: Use a nondestructive mode for output detect when polling
  drm/radeon: add some missing copyright headers
  drm: Only decouple the old_fb from the crtc is we call mode_set*
  drm/radeon/kms: don't enable underscan with interlaced modes
  drm/radeon/kms: add connector table for Mac x800
  drm/radeon/kms: fix regression in RMX code (v2)
  drm: Fix regression in disable polling e58f637b
parents 9c03f162 fe725d4f
...@@ -103,8 +103,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, ...@@ -103,8 +103,8 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
if (connector->funcs->force) if (connector->funcs->force)
connector->funcs->force(connector); connector->funcs->force(connector);
} else { } else {
connector->status = connector->funcs->detect(connector); connector->status = connector->funcs->detect(connector, true);
drm_helper_hpd_irq_event(dev); drm_kms_helper_poll_enable(dev);
} }
if (connector->status == connector_status_disconnected) { if (connector->status == connector_status_disconnected) {
...@@ -637,13 +637,13 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) ...@@ -637,13 +637,13 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
mode_changed = true; mode_changed = true;
if (mode_changed) { if (mode_changed) {
old_fb = set->crtc->fb;
set->crtc->fb = set->fb;
set->crtc->enabled = (set->mode != NULL); set->crtc->enabled = (set->mode != NULL);
if (set->mode != NULL) { if (set->mode != NULL) {
DRM_DEBUG_KMS("attempting to set mode from" DRM_DEBUG_KMS("attempting to set mode from"
" userspace\n"); " userspace\n");
drm_mode_debug_printmodeline(set->mode); drm_mode_debug_printmodeline(set->mode);
old_fb = set->crtc->fb;
set->crtc->fb = set->fb;
if (!drm_crtc_helper_set_mode(set->crtc, set->mode, if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
set->x, set->y, set->x, set->y,
old_fb)) { old_fb)) {
...@@ -866,7 +866,7 @@ static void output_poll_execute(struct work_struct *work) ...@@ -866,7 +866,7 @@ static void output_poll_execute(struct work_struct *work)
!(connector->polled & DRM_CONNECTOR_POLL_HPD)) !(connector->polled & DRM_CONNECTOR_POLL_HPD))
continue; continue;
status = connector->funcs->detect(connector); status = connector->funcs->detect(connector, false);
if (old_status != status) if (old_status != status)
changed = true; changed = true;
} }
......
...@@ -164,6 +164,8 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, ...@@ -164,6 +164,8 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
dev->hose = pdev->sysdata; dev->hose = pdev->sysdata;
#endif #endif
mutex_lock(&drm_global_mutex);
if ((ret = drm_fill_in_dev(dev, ent, driver))) { if ((ret = drm_fill_in_dev(dev, ent, driver))) {
printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
goto err_g2; goto err_g2;
...@@ -199,6 +201,7 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, ...@@ -199,6 +201,7 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
driver->name, driver->major, driver->minor, driver->patchlevel, driver->name, driver->major, driver->minor, driver->patchlevel,
driver->date, pci_name(pdev), dev->primary->index); driver->date, pci_name(pdev), dev->primary->index);
mutex_unlock(&drm_global_mutex);
return 0; return 0;
err_g4: err_g4:
...@@ -210,6 +213,7 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, ...@@ -210,6 +213,7 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
pci_disable_device(pdev); pci_disable_device(pdev);
err_g1: err_g1:
kfree(dev); kfree(dev);
mutex_unlock(&drm_global_mutex);
return ret; return ret;
} }
EXPORT_SYMBOL(drm_get_pci_dev); EXPORT_SYMBOL(drm_get_pci_dev);
......
...@@ -53,6 +53,8 @@ int drm_get_platform_dev(struct platform_device *platdev, ...@@ -53,6 +53,8 @@ int drm_get_platform_dev(struct platform_device *platdev,
dev->platformdev = platdev; dev->platformdev = platdev;
dev->dev = &platdev->dev; dev->dev = &platdev->dev;
mutex_lock(&drm_global_mutex);
ret = drm_fill_in_dev(dev, NULL, driver); ret = drm_fill_in_dev(dev, NULL, driver);
if (ret) { if (ret) {
...@@ -87,6 +89,8 @@ int drm_get_platform_dev(struct platform_device *platdev, ...@@ -87,6 +89,8 @@ int drm_get_platform_dev(struct platform_device *platdev,
list_add_tail(&dev->driver_item, &driver->device_list); list_add_tail(&dev->driver_item, &driver->device_list);
mutex_unlock(&drm_global_mutex);
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
driver->name, driver->major, driver->minor, driver->patchlevel, driver->name, driver->major, driver->minor, driver->patchlevel,
driver->date, dev->primary->index); driver->date, dev->primary->index);
...@@ -100,6 +104,7 @@ int drm_get_platform_dev(struct platform_device *platdev, ...@@ -100,6 +104,7 @@ int drm_get_platform_dev(struct platform_device *platdev,
drm_put_minor(&dev->control); drm_put_minor(&dev->control);
err_g1: err_g1:
kfree(dev); kfree(dev);
mutex_unlock(&drm_global_mutex);
return ret; return ret;
} }
EXPORT_SYMBOL(drm_get_platform_dev); EXPORT_SYMBOL(drm_get_platform_dev);
......
...@@ -159,7 +159,7 @@ static ssize_t status_show(struct device *device, ...@@ -159,7 +159,7 @@ static ssize_t status_show(struct device *device,
struct drm_connector *connector = to_drm_connector(device); struct drm_connector *connector = to_drm_connector(device);
enum drm_connector_status status; enum drm_connector_status status;
status = connector->funcs->detect(connector); status = connector->funcs->detect(connector, true);
return snprintf(buf, PAGE_SIZE, "%s\n", return snprintf(buf, PAGE_SIZE, "%s\n",
drm_get_connector_status_name(status)); drm_get_connector_status_name(status));
} }
......
...@@ -400,7 +400,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder ...@@ -400,7 +400,8 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder
return status; return status;
} }
static enum drm_connector_status intel_crt_detect(struct drm_connector *connector) static enum drm_connector_status
intel_crt_detect(struct drm_connector *connector, bool force)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct drm_encoder *encoder = intel_attached_encoder(connector); struct drm_encoder *encoder = intel_attached_encoder(connector);
...@@ -419,6 +420,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto ...@@ -419,6 +420,9 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connecto
if (intel_crt_detect_ddc(encoder)) if (intel_crt_detect_ddc(encoder))
return connector_status_connected; return connector_status_connected;
if (!force)
return connector->status;
/* for pre-945g platforms use load detect */ /* for pre-945g platforms use load detect */
if (encoder->crtc && encoder->crtc->enabled) { if (encoder->crtc && encoder->crtc->enabled) {
status = intel_crt_load_detect(encoder->crtc, intel_encoder); status = intel_crt_load_detect(encoder->crtc, intel_encoder);
......
...@@ -1386,7 +1386,7 @@ ironlake_dp_detect(struct drm_connector *connector) ...@@ -1386,7 +1386,7 @@ ironlake_dp_detect(struct drm_connector *connector)
* \return false if DP port is disconnected. * \return false if DP port is disconnected.
*/ */
static enum drm_connector_status static enum drm_connector_status
intel_dp_detect(struct drm_connector *connector) intel_dp_detect(struct drm_connector *connector, bool force)
{ {
struct drm_encoder *encoder = intel_attached_encoder(connector); struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
......
...@@ -221,7 +221,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, ...@@ -221,7 +221,8 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder,
* *
* Unimplemented. * Unimplemented.
*/ */
static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) static enum drm_connector_status
intel_dvo_detect(struct drm_connector *connector, bool force)
{ {
struct drm_encoder *encoder = intel_attached_encoder(connector); struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
......
...@@ -139,7 +139,7 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, ...@@ -139,7 +139,7 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder,
} }
static enum drm_connector_status static enum drm_connector_status
intel_hdmi_detect(struct drm_connector *connector) intel_hdmi_detect(struct drm_connector *connector, bool force)
{ {
struct drm_encoder *encoder = intel_attached_encoder(connector); struct drm_encoder *encoder = intel_attached_encoder(connector);
struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
......
...@@ -445,7 +445,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, ...@@ -445,7 +445,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder,
* connected and closed means disconnected. We also send hotplug events as * connected and closed means disconnected. We also send hotplug events as
* needed, using lid status notification from the input layer. * needed, using lid status notification from the input layer.
*/ */
static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector) static enum drm_connector_status
intel_lvds_detect(struct drm_connector *connector, bool force)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
enum drm_connector_status status = connector_status_connected; enum drm_connector_status status = connector_status_connected;
...@@ -540,7 +541,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, ...@@ -540,7 +541,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
* the LID nofication event. * the LID nofication event.
*/ */
if (connector) if (connector)
connector->status = connector->funcs->detect(connector); connector->status = connector->funcs->detect(connector,
false);
/* Don't force modeset on machines where it causes a GPU lockup */ /* Don't force modeset on machines where it causes a GPU lockup */
if (dmi_check_system(intel_no_modeset_on_lid)) if (dmi_check_system(intel_no_modeset_on_lid))
return NOTIFY_OK; return NOTIFY_OK;
......
...@@ -1417,7 +1417,7 @@ intel_analog_is_connected(struct drm_device *dev) ...@@ -1417,7 +1417,7 @@ intel_analog_is_connected(struct drm_device *dev)
if (!analog_connector) if (!analog_connector)
return false; return false;
if (analog_connector->funcs->detect(analog_connector) == if (analog_connector->funcs->detect(analog_connector, false) ==
connector_status_disconnected) connector_status_disconnected)
return false; return false;
...@@ -1486,7 +1486,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) ...@@ -1486,7 +1486,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
return status; return status;
} }
static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) static enum drm_connector_status
intel_sdvo_detect(struct drm_connector *connector, bool force)
{ {
uint16_t response; uint16_t response;
struct drm_encoder *encoder = intel_attached_encoder(connector); struct drm_encoder *encoder = intel_attached_encoder(connector);
......
...@@ -1341,7 +1341,7 @@ static void intel_tv_find_better_format(struct drm_connector *connector) ...@@ -1341,7 +1341,7 @@ static void intel_tv_find_better_format(struct drm_connector *connector)
* we have a pipe programmed in order to probe the TV. * we have a pipe programmed in order to probe the TV.
*/ */
static enum drm_connector_status static enum drm_connector_status
intel_tv_detect(struct drm_connector *connector) intel_tv_detect(struct drm_connector *connector, bool force)
{ {
struct drm_display_mode mode; struct drm_display_mode mode;
struct drm_encoder *encoder = intel_attached_encoder(connector); struct drm_encoder *encoder = intel_attached_encoder(connector);
...@@ -1353,7 +1353,7 @@ intel_tv_detect(struct drm_connector *connector) ...@@ -1353,7 +1353,7 @@ intel_tv_detect(struct drm_connector *connector)
if (encoder->crtc && encoder->crtc->enabled) { if (encoder->crtc && encoder->crtc->enabled) {
type = intel_tv_detect_type(intel_tv); type = intel_tv_detect_type(intel_tv);
} else { } else if (force) {
struct drm_crtc *crtc; struct drm_crtc *crtc;
int dpms_mode; int dpms_mode;
...@@ -1364,10 +1364,9 @@ intel_tv_detect(struct drm_connector *connector) ...@@ -1364,10 +1364,9 @@ intel_tv_detect(struct drm_connector *connector)
intel_release_load_detect_pipe(&intel_tv->base, connector, intel_release_load_detect_pipe(&intel_tv->base, connector,
dpms_mode); dpms_mode);
} else } else
type = -1; return connector_status_unknown;
} } else
return connector->status;
intel_tv->type = type;
if (type < 0) if (type < 0)
return connector_status_disconnected; return connector_status_disconnected;
......
...@@ -168,7 +168,7 @@ nouveau_connector_set_encoder(struct drm_connector *connector, ...@@ -168,7 +168,7 @@ nouveau_connector_set_encoder(struct drm_connector *connector,
} }
static enum drm_connector_status static enum drm_connector_status
nouveau_connector_detect(struct drm_connector *connector) nouveau_connector_detect(struct drm_connector *connector, bool force)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct nouveau_connector *nv_connector = nouveau_connector(connector); struct nouveau_connector *nv_connector = nouveau_connector(connector);
...@@ -246,7 +246,7 @@ nouveau_connector_detect(struct drm_connector *connector) ...@@ -246,7 +246,7 @@ nouveau_connector_detect(struct drm_connector *connector)
} }
static enum drm_connector_status static enum drm_connector_status
nouveau_connector_detect_lvds(struct drm_connector *connector) nouveau_connector_detect_lvds(struct drm_connector *connector, bool force)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
...@@ -267,7 +267,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector) ...@@ -267,7 +267,7 @@ nouveau_connector_detect_lvds(struct drm_connector *connector)
/* Try retrieving EDID via DDC */ /* Try retrieving EDID via DDC */
if (!dev_priv->vbios.fp_no_ddc) { if (!dev_priv->vbios.fp_no_ddc) {
status = nouveau_connector_detect(connector); status = nouveau_connector_detect(connector, force);
if (status == connector_status_connected) if (status == connector_status_connected)
goto out; goto out;
} }
......
...@@ -539,14 +539,15 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, ...@@ -539,14 +539,15 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
pll->algo = PLL_ALGO_LEGACY; pll->algo = PLL_ALGO_LEGACY;
pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER; pll->flags |= RADEON_PLL_PREFER_CLOSEST_LOWER;
} }
/* There is some evidence (often anecdotal) that RV515 LVDS /* There is some evidence (often anecdotal) that RV515/RV620 LVDS
* (on some boards at least) prefers the legacy algo. I'm not * (on some boards at least) prefers the legacy algo. I'm not
* sure whether this should handled generically or on a * sure whether this should handled generically or on a
* case-by-case quirk basis. Both algos should work fine in the * case-by-case quirk basis. Both algos should work fine in the
* majority of cases. * majority of cases.
*/ */
if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) && if ((radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) &&
(rdev->family == CHIP_RV515)) { ((rdev->family == CHIP_RV515) ||
(rdev->family == CHIP_RV620))) {
/* allow the user to overrride just in case */ /* allow the user to overrride just in case */
if (radeon_new_pll == 1) if (radeon_new_pll == 1)
pll->algo = PLL_ALGO_NEW; pll->algo = PLL_ALGO_NEW;
......
...@@ -1160,14 +1160,25 @@ static void evergreen_gpu_init(struct radeon_device *rdev) ...@@ -1160,14 +1160,25 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
EVERGREEN_MAX_BACKENDS_MASK)); EVERGREEN_MAX_BACKENDS_MASK));
break; break;
} }
} else } else {
gb_backend_map = switch (rdev->family) {
evergreen_get_tile_pipe_to_backend_map(rdev, case CHIP_CYPRESS:
rdev->config.evergreen.max_tile_pipes, case CHIP_HEMLOCK:
rdev->config.evergreen.max_backends, gb_backend_map = 0x66442200;
((EVERGREEN_MAX_BACKENDS_MASK << break;
rdev->config.evergreen.max_backends) & case CHIP_JUNIPER:
EVERGREEN_MAX_BACKENDS_MASK)); gb_backend_map = 0x00006420;
break;
default:
gb_backend_map =
evergreen_get_tile_pipe_to_backend_map(rdev,
rdev->config.evergreen.max_tile_pipes,
rdev->config.evergreen.max_backends,
((EVERGREEN_MAX_BACKENDS_MASK <<
rdev->config.evergreen.max_backends) &
EVERGREEN_MAX_BACKENDS_MASK));
}
}
rdev->config.evergreen.tile_config = gb_addr_config; rdev->config.evergreen.tile_config = gb_addr_config;
WREG32(GB_BACKEND_MAP, gb_backend_map); WREG32(GB_BACKEND_MAP, gb_backend_map);
......
...@@ -2020,18 +2020,7 @@ bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *l ...@@ -2020,18 +2020,7 @@ bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *l
return false; return false;
} }
elapsed = jiffies_to_msecs(cjiffies - lockup->last_jiffies); elapsed = jiffies_to_msecs(cjiffies - lockup->last_jiffies);
if (elapsed >= 3000) { if (elapsed >= 10000) {
/* very likely the improbable case where current
* rptr is equal to last recorded, a while ago, rptr
* this is more likely a false positive update tracking
* information which should force us to be recall at
* latter point
*/
lockup->last_cp_rptr = cp->rptr;
lockup->last_jiffies = jiffies;
return false;
}
if (elapsed >= 1000) {
dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed); dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed);
return true; return true;
} }
...@@ -3308,13 +3297,14 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) ...@@ -3308,13 +3297,14 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
unsigned long size; unsigned long size;
unsigned prim_walk; unsigned prim_walk;
unsigned nverts; unsigned nverts;
unsigned num_cb = track->num_cb;
for (i = 0; i < track->num_cb; i++) { if (!track->zb_cb_clear && !track->color_channel_mask &&
!track->blend_read_enable)
num_cb = 0;
for (i = 0; i < num_cb; i++) {
if (track->cb[i].robj == NULL) { if (track->cb[i].robj == NULL) {
if (!(track->zb_cb_clear || track->color_channel_mask ||
track->blend_read_enable)) {
continue;
}
DRM_ERROR("[drm] No buffer for color buffer %d !\n", i); DRM_ERROR("[drm] No buffer for color buffer %d !\n", i);
return -EINVAL; return -EINVAL;
} }
......
/*
* Copyright 2009 Advanced Micro Devices, Inc.
* Copyright 2009 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
#include "drmP.h" #include "drmP.h"
#include "drm.h" #include "drm.h"
#include "radeon_drm.h" #include "radeon_drm.h"
......
/*
* Copyright 2009 Advanced Micro Devices, Inc.
* Copyright 2009 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
#ifndef R600_BLIT_SHADERS_H #ifndef R600_BLIT_SHADERS_H
#define R600_BLIT_SHADERS_H #define R600_BLIT_SHADERS_H
......
...@@ -1170,9 +1170,8 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i ...@@ -1170,9 +1170,8 @@ static inline int r600_check_texture_resource(struct radeon_cs_parser *p, u32 i
/* using get ib will give us the offset into the mipmap bo */ /* using get ib will give us the offset into the mipmap bo */
word0 = radeon_get_ib_value(p, idx + 3) << 8; word0 = radeon_get_ib_value(p, idx + 3) << 8;
if ((mipmap_size + word0) > radeon_bo_size(mipmap)) { if ((mipmap_size + word0) > radeon_bo_size(mipmap)) {
dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n",
w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture)); w0, h0, bpe, blevel, nlevels, word0, mipmap_size, radeon_bo_size(texture));*/
return -EINVAL;
} }
return 0; return 0;
} }
......
...@@ -1485,6 +1485,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) ...@@ -1485,6 +1485,11 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
/* PowerMac8,1 ? */ /* PowerMac8,1 ? */
/* imac g5 isight */ /* imac g5 isight */
rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT; rdev->mode_info.connector_table = CT_IMAC_G5_ISIGHT;
} else if ((rdev->pdev->device == 0x4a48) &&
(rdev->pdev->subsystem_vendor == 0x1002) &&
(rdev->pdev->subsystem_device == 0x4a48)) {
/* Mac X800 */
rdev->mode_info.connector_table = CT_MAC_X800;
} else } else
#endif /* CONFIG_PPC_PMAC */ #endif /* CONFIG_PPC_PMAC */
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
...@@ -1961,6 +1966,48 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) ...@@ -1961,6 +1966,48 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
CONNECTOR_OBJECT_ID_VGA, CONNECTOR_OBJECT_ID_VGA,
&hpd); &hpd);
break; break;
case CT_MAC_X800:
DRM_INFO("Connector Table: %d (mac x800)\n",
rdev->mode_info.connector_table);
/* DVI - primary dac, internal tmds */
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
hpd.hpd = RADEON_HPD_1; /* ??? */
radeon_add_legacy_encoder(dev,
radeon_get_encoder_enum(dev,
ATOM_DEVICE_DFP1_SUPPORT,
0),
ATOM_DEVICE_DFP1_SUPPORT);
radeon_add_legacy_encoder(dev,
radeon_get_encoder_enum(dev,
ATOM_DEVICE_CRT1_SUPPORT,
1),
ATOM_DEVICE_CRT1_SUPPORT);
radeon_add_legacy_connector(dev, 0,
ATOM_DEVICE_DFP1_SUPPORT |
ATOM_DEVICE_CRT1_SUPPORT,
DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I,
&hpd);
/* DVI - tv dac, dvo */
ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
hpd.hpd = RADEON_HPD_2; /* ??? */
radeon_add_legacy_encoder(dev,
radeon_get_encoder_enum(dev,
ATOM_DEVICE_DFP2_SUPPORT,
0),
ATOM_DEVICE_DFP2_SUPPORT);
radeon_add_legacy_encoder(dev,
radeon_get_encoder_enum(dev,
ATOM_DEVICE_CRT2_SUPPORT,
2),
ATOM_DEVICE_CRT2_SUPPORT);
radeon_add_legacy_connector(dev, 1,
ATOM_DEVICE_DFP2_SUPPORT |
ATOM_DEVICE_CRT2_SUPPORT,
DRM_MODE_CONNECTOR_DVII, &ddc_i2c,
CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I,
&hpd);
break;
default: default:
DRM_INFO("Connector table: %d (invalid)\n", DRM_INFO("Connector table: %d (invalid)\n",
rdev->mode_info.connector_table); rdev->mode_info.connector_table);
......
...@@ -481,7 +481,8 @@ static int radeon_lvds_mode_valid(struct drm_connector *connector, ...@@ -481,7 +481,8 @@ static int radeon_lvds_mode_valid(struct drm_connector *connector,
return MODE_OK; return MODE_OK;
} }
static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector) static enum drm_connector_status
radeon_lvds_detect(struct drm_connector *connector, bool force)
{ {
struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct drm_encoder *encoder = radeon_best_single_encoder(connector); struct drm_encoder *encoder = radeon_best_single_encoder(connector);
...@@ -594,7 +595,8 @@ static int radeon_vga_mode_valid(struct drm_connector *connector, ...@@ -594,7 +595,8 @@ static int radeon_vga_mode_valid(struct drm_connector *connector,
return MODE_OK; return MODE_OK;
} }
static enum drm_connector_status radeon_vga_detect(struct drm_connector *connector) static enum drm_connector_status
radeon_vga_detect(struct drm_connector *connector, bool force)
{ {
struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct drm_encoder *encoder; struct drm_encoder *encoder;
...@@ -691,7 +693,8 @@ static int radeon_tv_mode_valid(struct drm_connector *connector, ...@@ -691,7 +693,8 @@ static int radeon_tv_mode_valid(struct drm_connector *connector,
return MODE_OK; return MODE_OK;
} }
static enum drm_connector_status radeon_tv_detect(struct drm_connector *connector) static enum drm_connector_status
radeon_tv_detect(struct drm_connector *connector, bool force)
{ {
struct drm_encoder *encoder; struct drm_encoder *encoder;
struct drm_encoder_helper_funcs *encoder_funcs; struct drm_encoder_helper_funcs *encoder_funcs;
...@@ -748,7 +751,8 @@ static int radeon_dvi_get_modes(struct drm_connector *connector) ...@@ -748,7 +751,8 @@ static int radeon_dvi_get_modes(struct drm_connector *connector)
* we have to check if this analog encoder is shared with anyone else (TV) * we have to check if this analog encoder is shared with anyone else (TV)
* if its shared we have to set the other connector to disconnected. * if its shared we have to set the other connector to disconnected.
*/ */
static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connector) static enum drm_connector_status
radeon_dvi_detect(struct drm_connector *connector, bool force)
{ {
struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector *radeon_connector = to_radeon_connector(connector);
struct drm_encoder *encoder = NULL; struct drm_encoder *encoder = NULL;
...@@ -972,7 +976,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector) ...@@ -972,7 +976,8 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
return ret; return ret;
} }
static enum drm_connector_status radeon_dp_detect(struct drm_connector *connector) static enum drm_connector_status
radeon_dp_detect(struct drm_connector *connector, bool force)
{ {
struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct radeon_connector *radeon_connector = to_radeon_connector(connector);
enum drm_connector_status ret = connector_status_disconnected; enum drm_connector_status ret = connector_status_disconnected;
......
...@@ -1140,17 +1140,18 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, ...@@ -1140,17 +1140,18 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc,
radeon_crtc->rmx_type = radeon_encoder->rmx_type; radeon_crtc->rmx_type = radeon_encoder->rmx_type;
else else
radeon_crtc->rmx_type = RMX_OFF; radeon_crtc->rmx_type = RMX_OFF;
src_v = crtc->mode.vdisplay;
dst_v = radeon_crtc->native_mode.vdisplay;
src_h = crtc->mode.hdisplay;
dst_h = radeon_crtc->native_mode.vdisplay;
/* copy native mode */ /* copy native mode */
memcpy(&radeon_crtc->native_mode, memcpy(&radeon_crtc->native_mode,
&radeon_encoder->native_mode, &radeon_encoder->native_mode,
sizeof(struct drm_display_mode)); sizeof(struct drm_display_mode));
src_v = crtc->mode.vdisplay;
dst_v = radeon_crtc->native_mode.vdisplay;
src_h = crtc->mode.hdisplay;
dst_h = radeon_crtc->native_mode.hdisplay;
/* fix up for overscan on hdmi */ /* fix up for overscan on hdmi */
if (ASIC_IS_AVIVO(rdev) && if (ASIC_IS_AVIVO(rdev) &&
(!(mode->flags & DRM_MODE_FLAG_INTERLACE)) &&
((radeon_encoder->underscan_type == UNDERSCAN_ON) || ((radeon_encoder->underscan_type == UNDERSCAN_ON) ||
((radeon_encoder->underscan_type == UNDERSCAN_AUTO) && ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) &&
drm_detect_hdmi_monitor(radeon_connector->edid) && drm_detect_hdmi_monitor(radeon_connector->edid) &&
......
...@@ -204,7 +204,7 @@ struct radeon_i2c_chan { ...@@ -204,7 +204,7 @@ struct radeon_i2c_chan {
/* mostly for macs, but really any system without connector tables */ /* mostly for macs, but really any system without connector tables */
enum radeon_connector_table { enum radeon_connector_table {
CT_NONE, CT_NONE = 0,
CT_GENERIC, CT_GENERIC,
CT_IBOOK, CT_IBOOK,
CT_POWERBOOK_EXTERNAL, CT_POWERBOOK_EXTERNAL,
...@@ -215,6 +215,7 @@ enum radeon_connector_table { ...@@ -215,6 +215,7 @@ enum radeon_connector_table {
CT_IMAC_G5_ISIGHT, CT_IMAC_G5_ISIGHT,
CT_EMAC, CT_EMAC,
CT_RN50_POWER, CT_RN50_POWER,
CT_MAC_X800,
}; };
enum radeon_dvo_chip { enum radeon_dvo_chip {
......
...@@ -335,7 +335,8 @@ static void vmw_ldu_connector_restore(struct drm_connector *connector) ...@@ -335,7 +335,8 @@ static void vmw_ldu_connector_restore(struct drm_connector *connector)
} }
static enum drm_connector_status static enum drm_connector_status
vmw_ldu_connector_detect(struct drm_connector *connector) vmw_ldu_connector_detect(struct drm_connector *connector,
bool force)
{ {
if (vmw_connector_to_ldu(connector)->pref_active) if (vmw_connector_to_ldu(connector)->pref_active)
return connector_status_connected; return connector_status_connected;
...@@ -516,7 +517,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) ...@@ -516,7 +517,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
drm_connector_init(dev, connector, &vmw_legacy_connector_funcs, drm_connector_init(dev, connector, &vmw_legacy_connector_funcs,
DRM_MODE_CONNECTOR_LVDS); DRM_MODE_CONNECTOR_LVDS);
connector->status = vmw_ldu_connector_detect(connector); connector->status = vmw_ldu_connector_detect(connector, true);
drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs, drm_encoder_init(dev, encoder, &vmw_legacy_encoder_funcs,
DRM_MODE_ENCODER_LVDS); DRM_MODE_ENCODER_LVDS);
...@@ -610,7 +611,7 @@ int vmw_kms_ldu_update_layout(struct vmw_private *dev_priv, unsigned num, ...@@ -610,7 +611,7 @@ int vmw_kms_ldu_update_layout(struct vmw_private *dev_priv, unsigned num,
ldu->pref_height = 600; ldu->pref_height = 600;
ldu->pref_active = false; ldu->pref_active = false;
} }
con->status = vmw_ldu_connector_detect(con); con->status = vmw_ldu_connector_detect(con, true);
} }
mutex_unlock(&dev->mode_config.mutex); mutex_unlock(&dev->mode_config.mutex);
......
...@@ -386,7 +386,15 @@ struct drm_connector_funcs { ...@@ -386,7 +386,15 @@ struct drm_connector_funcs {
void (*dpms)(struct drm_connector *connector, int mode); void (*dpms)(struct drm_connector *connector, int mode);
void (*save)(struct drm_connector *connector); void (*save)(struct drm_connector *connector);
void (*restore)(struct drm_connector *connector); void (*restore)(struct drm_connector *connector);
enum drm_connector_status (*detect)(struct drm_connector *connector);
/* Check to see if anything is attached to the connector.
* @force is set to false whilst polling, true when checking the
* connector due to user request. @force can be used by the driver
* to avoid expensive, destructive operations during automated
* probing.
*/
enum drm_connector_status (*detect)(struct drm_connector *connector,
bool force);
int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height); int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height);
int (*set_property)(struct drm_connector *connector, struct drm_property *property, int (*set_property)(struct drm_connector *connector, struct drm_property *property,
uint64_t val); uint64_t val);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment