forked from Minki/linux
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: vgaarb: Wrap vga_(get|put) in CONFIG_VGA_ARB drm/radeon/kms: add missing scratch update in dp_detect drm/modes: Fix CVT-R modeline generation drm: fix regression in drm locking since BKL removal. drm/radeon/kms: remove stray radeon_i2c_destroy drm: mm: fix range restricted allocations drm/nouveau: drop drm_global_mutex before sleeping in submission path drm: export drm_global_mutex for drivers to use drm/nv20: Don't use pushbuf calls on the original nv20. drm/nouveau: Fix TMDS on some DCB1.5 boards. drm/nouveau: Fix backlight control on PPC machines with an internal TMDS panel. drm/nv30: Apply modesetting to the correct slave encoder drm/nouveau: Use a helper function to match PCI device/subsystem IDs. drm/nv50: add dcb type 14 to enum to prevent compiler complaint
This commit is contained in:
commit
06f01e73ef
@ -41,6 +41,7 @@
|
||||
|
||||
/* from BKL pushdown: note that nothing else serializes idr_find() */
|
||||
DEFINE_MUTEX(drm_global_mutex);
|
||||
EXPORT_SYMBOL(drm_global_mutex);
|
||||
|
||||
static int drm_open_helper(struct inode *inode, struct file *filp,
|
||||
struct drm_device * dev);
|
||||
|
@ -92,7 +92,9 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
|
||||
}
|
||||
|
||||
/* Contention */
|
||||
mutex_unlock(&drm_global_mutex);
|
||||
schedule();
|
||||
mutex_lock(&drm_global_mutex);
|
||||
if (signal_pending(current)) {
|
||||
ret = -EINTR;
|
||||
break;
|
||||
|
@ -285,21 +285,21 @@ void drm_mm_put_block(struct drm_mm_node *cur)
|
||||
|
||||
EXPORT_SYMBOL(drm_mm_put_block);
|
||||
|
||||
static int check_free_mm_node(struct drm_mm_node *entry, unsigned long size,
|
||||
unsigned alignment)
|
||||
static int check_free_hole(unsigned long start, unsigned long end,
|
||||
unsigned long size, unsigned alignment)
|
||||
{
|
||||
unsigned wasted = 0;
|
||||
|
||||
if (entry->size < size)
|
||||
if (end - start < size)
|
||||
return 0;
|
||||
|
||||
if (alignment) {
|
||||
register unsigned tmp = entry->start % alignment;
|
||||
unsigned tmp = start % alignment;
|
||||
if (tmp)
|
||||
wasted = alignment - tmp;
|
||||
}
|
||||
|
||||
if (entry->size >= size + wasted) {
|
||||
if (end >= start + size + wasted) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -320,7 +320,8 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
|
||||
best_size = ~0UL;
|
||||
|
||||
list_for_each_entry(entry, &mm->free_stack, free_stack) {
|
||||
if (!check_free_mm_node(entry, size, alignment))
|
||||
if (!check_free_hole(entry->start, entry->start + entry->size,
|
||||
size, alignment))
|
||||
continue;
|
||||
|
||||
if (!best_match)
|
||||
@ -353,10 +354,12 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm,
|
||||
best_size = ~0UL;
|
||||
|
||||
list_for_each_entry(entry, &mm->free_stack, free_stack) {
|
||||
if (entry->start > end || (entry->start+entry->size) < start)
|
||||
continue;
|
||||
unsigned long adj_start = entry->start < start ?
|
||||
start : entry->start;
|
||||
unsigned long adj_end = entry->start + entry->size > end ?
|
||||
end : entry->start + entry->size;
|
||||
|
||||
if (!check_free_mm_node(entry, size, alignment))
|
||||
if (!check_free_hole(adj_start, adj_end, size, alignment))
|
||||
continue;
|
||||
|
||||
if (!best_match)
|
||||
@ -449,7 +452,8 @@ int drm_mm_scan_add_block(struct drm_mm_node *node)
|
||||
node->free_stack.prev = prev_free;
|
||||
node->free_stack.next = next_free;
|
||||
|
||||
if (check_free_mm_node(node, mm->scan_size, mm->scan_alignment)) {
|
||||
if (check_free_hole(node->start, node->start + node->size,
|
||||
mm->scan_size, mm->scan_alignment)) {
|
||||
mm->scan_hit_start = node->start;
|
||||
mm->scan_hit_size = node->size;
|
||||
|
||||
|
@ -251,7 +251,10 @@ struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay,
|
||||
drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK;
|
||||
/* Fill in HSync values */
|
||||
drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2;
|
||||
drm_mode->hsync_start = drm_mode->hsync_end = CVT_RB_H_SYNC;
|
||||
drm_mode->hsync_start = drm_mode->hsync_end - CVT_RB_H_SYNC;
|
||||
/* Fill in VSync values */
|
||||
drm_mode->vsync_start = drm_mode->vdisplay + CVT_RB_VFPORCH;
|
||||
drm_mode->vsync_end = drm_mode->vsync_start + vsync;
|
||||
}
|
||||
/* 15/13. Find pixel clock frequency (kHz for xf86) */
|
||||
drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod;
|
||||
|
@ -3869,27 +3869,10 @@ static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entr
|
||||
}
|
||||
#ifdef __powerpc__
|
||||
/* Powerbook specific quirks */
|
||||
if ((dev->pci_device & 0xffff) == 0x0179 ||
|
||||
(dev->pci_device & 0xffff) == 0x0189 ||
|
||||
(dev->pci_device & 0xffff) == 0x0329) {
|
||||
if (script == LVDS_RESET) {
|
||||
nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72);
|
||||
|
||||
} else if (script == LVDS_PANEL_ON) {
|
||||
bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL,
|
||||
bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL)
|
||||
| (1 << 31));
|
||||
bios_wr32(bios, NV_PCRTC_GPIO_EXT,
|
||||
bios_rd32(bios, NV_PCRTC_GPIO_EXT) | 1);
|
||||
|
||||
} else if (script == LVDS_PANEL_OFF) {
|
||||
bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL,
|
||||
bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL)
|
||||
& ~(1 << 31));
|
||||
bios_wr32(bios, NV_PCRTC_GPIO_EXT,
|
||||
bios_rd32(bios, NV_PCRTC_GPIO_EXT) & ~3);
|
||||
}
|
||||
}
|
||||
if (script == LVDS_RESET &&
|
||||
(dev->pci_device == 0x0179 || dev->pci_device == 0x0189 ||
|
||||
dev->pci_device == 0x0329))
|
||||
nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@ -4381,11 +4364,8 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b
|
||||
*
|
||||
* For the moment, a quirk will do :)
|
||||
*/
|
||||
if ((dev->pdev->device == 0x01d7) &&
|
||||
(dev->pdev->subsystem_vendor == 0x1028) &&
|
||||
(dev->pdev->subsystem_device == 0x01c2)) {
|
||||
if (nv_match_device(dev, 0x01d7, 0x1028, 0x01c2))
|
||||
bios->fp.duallink_transition_clk = 80000;
|
||||
}
|
||||
|
||||
/* set dual_link flag for EDID case */
|
||||
if (pxclk && (chip_version < 0x25 || chip_version > 0x28))
|
||||
@ -5814,9 +5794,7 @@ parse_dcb_gpio_table(struct nvbios *bios)
|
||||
*/
|
||||
|
||||
/* Apple iMac G4 NV18 */
|
||||
if (dev->pdev->device == 0x0189 &&
|
||||
dev->pdev->subsystem_vendor == 0x10de &&
|
||||
dev->pdev->subsystem_device == 0x0010) {
|
||||
if (nv_match_device(dev, 0x0189, 0x10de, 0x0010)) {
|
||||
struct dcb_gpio_entry *gpio = new_gpio_entry(bios);
|
||||
|
||||
gpio->tag = DCB_GPIO_TVDAC0;
|
||||
@ -5898,9 +5876,7 @@ apply_dcb_connector_quirks(struct nvbios *bios, int idx)
|
||||
struct drm_device *dev = bios->dev;
|
||||
|
||||
/* Gigabyte NX85T */
|
||||
if ((dev->pdev->device == 0x0421) &&
|
||||
(dev->pdev->subsystem_vendor == 0x1458) &&
|
||||
(dev->pdev->subsystem_device == 0x344c)) {
|
||||
if (nv_match_device(dev, 0x0421, 0x1458, 0x344c)) {
|
||||
if (cte->type == DCB_CONNECTOR_HDMI_1)
|
||||
cte->type = DCB_CONNECTOR_DVI_I;
|
||||
}
|
||||
@ -6153,7 +6129,7 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb,
|
||||
entry->tmdsconf.slave_addr = (conf & 0x00000070) >> 4;
|
||||
|
||||
break;
|
||||
case 0xe:
|
||||
case OUTPUT_EOL:
|
||||
/* weird g80 mobile type that "nv" treats as a terminator */
|
||||
dcb->entries--;
|
||||
return false;
|
||||
@ -6190,23 +6166,15 @@ parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb,
|
||||
entry->type = OUTPUT_TV;
|
||||
break;
|
||||
case 2:
|
||||
case 4:
|
||||
if (conn & 0x10)
|
||||
entry->type = OUTPUT_LVDS;
|
||||
else
|
||||
entry->type = OUTPUT_TMDS;
|
||||
break;
|
||||
case 3:
|
||||
entry->type = OUTPUT_LVDS;
|
||||
break;
|
||||
case 4:
|
||||
switch ((conn & 0x000000f0) >> 4) {
|
||||
case 0:
|
||||
entry->type = OUTPUT_TMDS;
|
||||
break;
|
||||
case 1:
|
||||
entry->type = OUTPUT_LVDS;
|
||||
break;
|
||||
default:
|
||||
NV_ERROR(dev, "Unknown DCB subtype 4/%d\n",
|
||||
(conn & 0x000000f0) >> 4);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NV_ERROR(dev, "Unknown DCB type %d\n", conn & 0x0000000f);
|
||||
return false;
|
||||
@ -6321,9 +6289,7 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf)
|
||||
* nasty problems until this is sorted (assuming it's not a
|
||||
* VBIOS bug).
|
||||
*/
|
||||
if ((dev->pdev->device == 0x040d) &&
|
||||
(dev->pdev->subsystem_vendor == 0x1028) &&
|
||||
(dev->pdev->subsystem_device == 0x019b)) {
|
||||
if (nv_match_device(dev, 0x040d, 0x1028, 0x019b)) {
|
||||
if (*conn == 0x02026312 && *conf == 0x00000020)
|
||||
return false;
|
||||
}
|
||||
|
@ -95,6 +95,7 @@ enum dcb_type {
|
||||
OUTPUT_TMDS = 2,
|
||||
OUTPUT_LVDS = 3,
|
||||
OUTPUT_DP = 6,
|
||||
OUTPUT_EOL = 14, /* DCB 4.0+, appears to be end-of-list */
|
||||
OUTPUT_ANY = -1
|
||||
};
|
||||
|
||||
|
@ -1389,6 +1389,15 @@ nv_two_reg_pll(struct drm_device *dev)
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
nv_match_device(struct drm_device *dev, unsigned device,
|
||||
unsigned sub_vendor, unsigned sub_device)
|
||||
{
|
||||
return dev->pdev->device == device &&
|
||||
dev->pdev->subsystem_vendor == sub_vendor &&
|
||||
dev->pdev->subsystem_device == sub_device;
|
||||
}
|
||||
|
||||
#define NV_SW 0x0000506e
|
||||
#define NV_SW_DMA_SEMAPHORE 0x00000060
|
||||
#define NV_SW_SEMAPHORE_OFFSET 0x00000064
|
||||
|
@ -337,7 +337,9 @@ retry:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_unlock(&drm_global_mutex);
|
||||
ret = ttm_bo_wait_cpu(&nvbo->bo, false);
|
||||
mutex_lock(&drm_global_mutex);
|
||||
if (ret) {
|
||||
NV_ERROR(dev, "fail wait_cpu\n");
|
||||
return ret;
|
||||
@ -663,7 +665,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
|
||||
push[i].length);
|
||||
}
|
||||
} else
|
||||
if (dev_priv->card_type >= NV_20) {
|
||||
if (dev_priv->chipset >= 0x25) {
|
||||
ret = RING_SPACE(chan, req->nr_push * 2);
|
||||
if (ret) {
|
||||
NV_ERROR(dev, "cal_space: %d\n", ret);
|
||||
@ -738,7 +740,7 @@ out_next:
|
||||
req->suffix0 = 0x00000000;
|
||||
req->suffix1 = 0x00000000;
|
||||
} else
|
||||
if (dev_priv->card_type >= NV_20) {
|
||||
if (dev_priv->chipset >= 0x25) {
|
||||
req->suffix0 = 0x00020000;
|
||||
req->suffix1 = 0x00000000;
|
||||
} else {
|
||||
|
@ -444,6 +444,7 @@ static void nv04_dfp_commit(struct drm_encoder *encoder)
|
||||
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
|
||||
struct dcb_entry *dcbe = nv_encoder->dcb;
|
||||
int head = nouveau_crtc(encoder->crtc)->index;
|
||||
struct drm_encoder *slave_encoder;
|
||||
|
||||
if (dcbe->type == OUTPUT_TMDS)
|
||||
run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock);
|
||||
@ -462,9 +463,10 @@ static void nv04_dfp_commit(struct drm_encoder *encoder)
|
||||
NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000);
|
||||
|
||||
/* Init external transmitters */
|
||||
if (get_tmds_slave(encoder))
|
||||
get_slave_funcs(get_tmds_slave(encoder))->mode_set(
|
||||
encoder, &nv_encoder->mode, &nv_encoder->mode);
|
||||
slave_encoder = get_tmds_slave(encoder);
|
||||
if (slave_encoder)
|
||||
get_slave_funcs(slave_encoder)->mode_set(
|
||||
slave_encoder, &nv_encoder->mode, &nv_encoder->mode);
|
||||
|
||||
helper->dpms(encoder, DRM_MODE_DPMS_ON);
|
||||
|
||||
@ -473,6 +475,27 @@ static void nv04_dfp_commit(struct drm_encoder *encoder)
|
||||
nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
|
||||
}
|
||||
|
||||
static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode)
|
||||
{
|
||||
#ifdef __powerpc__
|
||||
struct drm_device *dev = encoder->dev;
|
||||
|
||||
/* BIOS scripts usually take care of the backlight, thanks
|
||||
* Apple for your consistency.
|
||||
*/
|
||||
if (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 ||
|
||||
dev->pci_device == 0x0329) {
|
||||
if (mode == DRM_MODE_DPMS_ON) {
|
||||
nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 0, 1 << 31);
|
||||
nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 1);
|
||||
} else {
|
||||
nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 1 << 31, 0);
|
||||
nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool is_powersaving_dpms(int mode)
|
||||
{
|
||||
return (mode != DRM_MODE_DPMS_ON);
|
||||
@ -520,6 +543,7 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode)
|
||||
LVDS_PANEL_OFF, 0);
|
||||
}
|
||||
|
||||
nv04_dfp_update_backlight(encoder, mode);
|
||||
nv04_dfp_update_fp_control(encoder, mode);
|
||||
|
||||
if (mode == DRM_MODE_DPMS_ON)
|
||||
@ -543,6 +567,7 @@ static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode)
|
||||
NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n",
|
||||
mode, nv_encoder->dcb->index);
|
||||
|
||||
nv04_dfp_update_backlight(encoder, mode);
|
||||
nv04_dfp_update_fp_control(encoder, mode);
|
||||
}
|
||||
|
||||
|
@ -121,18 +121,14 @@ static bool
|
||||
get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask)
|
||||
{
|
||||
/* Zotac FX5200 */
|
||||
if (dev->pdev->device == 0x0322 &&
|
||||
dev->pdev->subsystem_vendor == 0x19da &&
|
||||
(dev->pdev->subsystem_device == 0x1035 ||
|
||||
dev->pdev->subsystem_device == 0x2035)) {
|
||||
if (nv_match_device(dev, 0x0322, 0x19da, 0x1035) ||
|
||||
nv_match_device(dev, 0x0322, 0x19da, 0x2035)) {
|
||||
*pin_mask = 0xc;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* MSI nForce2 IGP */
|
||||
if (dev->pdev->device == 0x01f0 &&
|
||||
dev->pdev->subsystem_vendor == 0x1462 &&
|
||||
dev->pdev->subsystem_device == 0x5710) {
|
||||
if (nv_match_device(dev, 0x01f0, 0x1462, 0x5710)) {
|
||||
*pin_mask = 0xc;
|
||||
return false;
|
||||
}
|
||||
|
@ -999,6 +999,7 @@ static enum drm_connector_status radeon_dp_detect(struct drm_connector *connecto
|
||||
}
|
||||
}
|
||||
|
||||
radeon_connector_update_scratch_regs(connector, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -637,8 +637,6 @@ void radeon_pm_fini(struct radeon_device *rdev)
|
||||
}
|
||||
|
||||
radeon_hwmon_fini(rdev);
|
||||
if (rdev->pm.i2c_bus)
|
||||
radeon_i2c_destroy(rdev->pm.i2c_bus);
|
||||
}
|
||||
|
||||
void radeon_pm_compute_clocks(struct radeon_device *rdev)
|
||||
|
@ -93,8 +93,11 @@ extern void vga_set_legacy_decoding(struct pci_dev *pdev,
|
||||
* Nested calls are supported (a per-resource counter is maintained)
|
||||
*/
|
||||
|
||||
extern int vga_get(struct pci_dev *pdev, unsigned int rsrc,
|
||||
int interruptible);
|
||||
#if defined(CONFIG_VGA_ARB)
|
||||
extern int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible);
|
||||
#else
|
||||
static inline int vga_get(struct pci_dev *pdev, unsigned int rsrc, int interruptible) { return 0; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* vga_get_interruptible
|
||||
@ -131,7 +134,11 @@ static inline int vga_get_uninterruptible(struct pci_dev *pdev,
|
||||
* are already locked by another card. It can be called in any context
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_VGA_ARB)
|
||||
extern int vga_tryget(struct pci_dev *pdev, unsigned int rsrc);
|
||||
#else
|
||||
static inline int vga_tryget(struct pci_dev *pdev, unsigned int rsrc) { return 0; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* vga_put - release lock on legacy VGA resources
|
||||
@ -146,7 +153,11 @@ extern int vga_tryget(struct pci_dev *pdev, unsigned int rsrc);
|
||||
* released if the counter reaches 0.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_VGA_ARB)
|
||||
extern void vga_put(struct pci_dev *pdev, unsigned int rsrc);
|
||||
#else
|
||||
#define vga_put(pdev, rsrc)
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user