提交 42be79e3 编写于 作者: L Linus Torvalds

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

* 'drm-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (76 commits)
  drm/radeon/kms: enable ACPI powermanagement mode on radeon gpus.
  drm/radeon/kms: rs400/480 should set common registers.
  drm/radeon/kms: add sanity check to wptr.
  drm/radeon/kms/evergreen: get DP working
  drm/radeon/kms: add hw_i2c module option
  drm/radeon/kms: use new pre/post_xfer i2c bit algo hooks
  drm/radeon/kms: disable MSI on IGP chips
  drm/radeon/kms: display watermark updates (v2)
  drm/radeon/kms/dp: disable training pattern on the sink at the end of link training
  drm/radeon/kms: minor fixes for eDP with LCD* device tags (v2)
  drm/radeon/kms/dp: remove extraneous training complete call
  drm/radeon/kms/atom: minor fixes to transmitter setup
  drm/radeon/kms: Only restrict BO to visible VRAM size when pinning to VRAM.
  drm: fix build error when SYSRQ is disabled
  drm/radeon/kms: fix macbookpro connector quirk
  drm/radeon/r6xx/r7xx: further safe reg clean up
  drm/radeon: bump the UMS driver version for r6xx/r7xx const buffer support
  drm/radeon/kms: bump the version for r6xx/r7xx const buffer support
  drm/radeon/r6xx/r7xx: CS parser fixes
  drm/radeon/kms: fix some typos in r6xx/r7xx hpd setup
  ...

Fix up MSI-related conflicts in drivers/gpu/drm/radeon/radeon_irq_kms.c
...@@ -104,6 +104,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, ...@@ -104,6 +104,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
if (connector->status == connector_status_disconnected) { if (connector->status == connector_status_disconnected) {
DRM_DEBUG_KMS("%s is disconnected\n", DRM_DEBUG_KMS("%s is disconnected\n",
drm_get_connector_name(connector)); drm_get_connector_name(connector));
drm_mode_connector_update_edid_property(connector, NULL);
goto prune; goto prune;
} }
......
...@@ -707,15 +707,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, ...@@ -707,15 +707,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
mode->vsync_end = mode->vsync_start + vsync_pulse_width; mode->vsync_end = mode->vsync_start + vsync_pulse_width;
mode->vtotal = mode->vdisplay + vblank; mode->vtotal = mode->vdisplay + vblank;
/* perform the basic check for the detailed timing */
if (mode->hsync_end > mode->htotal ||
mode->vsync_end > mode->vtotal) {
drm_mode_destroy(dev, mode);
DRM_DEBUG_KMS("Incorrect detailed timing. "
"Sync is beyond the blank.\n");
return NULL;
}
/* Some EDIDs have bogus h/vtotal values */ /* Some EDIDs have bogus h/vtotal values */
if (mode->hsync_end > mode->htotal) if (mode->hsync_end > mode->htotal)
mode->htotal = mode->hsync_end + 1; mode->htotal = mode->hsync_end + 1;
......
...@@ -283,6 +283,8 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { ...@@ -283,6 +283,8 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
.help_msg = "force-fb(V)", .help_msg = "force-fb(V)",
.action_msg = "Restore framebuffer console", .action_msg = "Restore framebuffer console",
}; };
#else
static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { };
#endif #endif
static void drm_fb_helper_on(struct fb_info *info) static void drm_fb_helper_on(struct fb_info *info)
......
...@@ -140,14 +140,16 @@ int drm_open(struct inode *inode, struct file *filp) ...@@ -140,14 +140,16 @@ int drm_open(struct inode *inode, struct file *filp)
spin_unlock(&dev->count_lock); spin_unlock(&dev->count_lock);
} }
out: out:
mutex_lock(&dev->struct_mutex); if (!retcode) {
if (minor->type == DRM_MINOR_LEGACY) { mutex_lock(&dev->struct_mutex);
BUG_ON((dev->dev_mapping != NULL) && if (minor->type == DRM_MINOR_LEGACY) {
(dev->dev_mapping != inode->i_mapping)); if (dev->dev_mapping == NULL)
if (dev->dev_mapping == NULL) dev->dev_mapping = inode->i_mapping;
dev->dev_mapping = inode->i_mapping; else if (dev->dev_mapping != inode->i_mapping)
retcode = -ENODEV;
}
mutex_unlock(&dev->struct_mutex);
} }
mutex_unlock(&dev->struct_mutex);
return retcode; return retcode;
} }
......
...@@ -12,7 +12,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ ...@@ -12,7 +12,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
nouveau_dp.o nouveau_grctx.o \ nouveau_dp.o nouveau_grctx.o \
nv04_timer.o \ nv04_timer.o \
nv04_mc.o nv40_mc.o nv50_mc.o \ nv04_mc.o nv40_mc.o nv50_mc.o \
nv04_fb.o nv10_fb.o nv40_fb.o \ nv04_fb.o nv10_fb.o nv40_fb.o nv50_fb.o \
nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \
nv04_graph.o nv10_graph.o nv20_graph.o \ nv04_graph.o nv10_graph.o nv20_graph.o \
nv40_graph.o nv50_graph.o \ nv40_graph.o nv50_graph.o \
......
...@@ -5210,6 +5210,21 @@ divine_connector_type(struct nvbios *bios, int index) ...@@ -5210,6 +5210,21 @@ divine_connector_type(struct nvbios *bios, int index)
return type; return type;
} }
static void
apply_dcb_connector_quirks(struct nvbios *bios, int idx)
{
struct dcb_connector_table_entry *cte = &bios->dcb.connector.entry[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 (cte->type == DCB_CONNECTOR_HDMI_1)
cte->type = DCB_CONNECTOR_DVI_I;
}
}
static void static void
parse_dcb_connector_table(struct nvbios *bios) parse_dcb_connector_table(struct nvbios *bios)
{ {
...@@ -5238,13 +5253,14 @@ parse_dcb_connector_table(struct nvbios *bios) ...@@ -5238,13 +5253,14 @@ parse_dcb_connector_table(struct nvbios *bios)
entry = conntab + conntab[1]; entry = conntab + conntab[1];
cte = &ct->entry[0]; cte = &ct->entry[0];
for (i = 0; i < conntab[2]; i++, entry += conntab[3], cte++) { for (i = 0; i < conntab[2]; i++, entry += conntab[3], cte++) {
cte->index = i;
if (conntab[3] == 2) if (conntab[3] == 2)
cte->entry = ROM16(entry[0]); cte->entry = ROM16(entry[0]);
else else
cte->entry = ROM32(entry[0]); cte->entry = ROM32(entry[0]);
cte->type = (cte->entry & 0x000000ff) >> 0; cte->type = (cte->entry & 0x000000ff) >> 0;
cte->index = (cte->entry & 0x00000f00) >> 8; cte->index2 = (cte->entry & 0x00000f00) >> 8;
switch (cte->entry & 0x00033000) { switch (cte->entry & 0x00033000) {
case 0x00001000: case 0x00001000:
cte->gpio_tag = 0x07; cte->gpio_tag = 0x07;
...@@ -5266,6 +5282,8 @@ parse_dcb_connector_table(struct nvbios *bios) ...@@ -5266,6 +5282,8 @@ parse_dcb_connector_table(struct nvbios *bios)
if (cte->type == 0xff) if (cte->type == 0xff)
continue; continue;
apply_dcb_connector_quirks(bios, i);
NV_INFO(dev, " %d: 0x%08x: type 0x%02x idx %d tag 0x%02x\n", NV_INFO(dev, " %d: 0x%08x: type 0x%02x idx %d tag 0x%02x\n",
i, cte->entry, cte->type, cte->index, cte->gpio_tag); i, cte->entry, cte->type, cte->index, cte->gpio_tag);
...@@ -5287,10 +5305,16 @@ parse_dcb_connector_table(struct nvbios *bios) ...@@ -5287,10 +5305,16 @@ parse_dcb_connector_table(struct nvbios *bios)
break; break;
default: default:
cte->type = divine_connector_type(bios, cte->index); cte->type = divine_connector_type(bios, cte->index);
NV_WARN(dev, "unknown type, using 0x%02x", cte->type); NV_WARN(dev, "unknown type, using 0x%02x\n", cte->type);
break; break;
} }
if (nouveau_override_conntype) {
int type = divine_connector_type(bios, cte->index);
if (type != cte->type)
NV_WARN(dev, " -> type 0x%02x\n", cte->type);
}
} }
} }
......
...@@ -72,9 +72,10 @@ enum dcb_connector_type { ...@@ -72,9 +72,10 @@ enum dcb_connector_type {
}; };
struct dcb_connector_table_entry { struct dcb_connector_table_entry {
uint8_t index;
uint32_t entry; uint32_t entry;
enum dcb_connector_type type; enum dcb_connector_type type;
uint8_t index; uint8_t index2;
uint8_t gpio_tag; uint8_t gpio_tag;
}; };
......
...@@ -439,8 +439,7 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl) ...@@ -439,8 +439,7 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
switch (bo->mem.mem_type) { switch (bo->mem.mem_type) {
case TTM_PL_VRAM: case TTM_PL_VRAM:
nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT | nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT);
TTM_PL_FLAG_SYSTEM);
break; break;
default: default:
nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM); nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM);
......
...@@ -302,7 +302,7 @@ nouveau_connector_detect(struct drm_connector *connector) ...@@ -302,7 +302,7 @@ nouveau_connector_detect(struct drm_connector *connector)
detect_analog: detect_analog:
nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG); nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG);
if (!nv_encoder) if (!nv_encoder && !nouveau_tv_disable)
nv_encoder = find_encoder_by_type(connector, OUTPUT_TV); nv_encoder = find_encoder_by_type(connector, OUTPUT_TV);
if (nv_encoder) { if (nv_encoder) {
struct drm_encoder *encoder = to_drm_encoder(nv_encoder); struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
......
...@@ -190,6 +190,11 @@ nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo, ...@@ -190,6 +190,11 @@ nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo,
nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8); nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8);
chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max; chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max;
DRM_MEMORYBARRIER();
/* Flush writes. */
nouveau_bo_rd32(pb, 0);
nvchan_wr32(chan, 0x8c, chan->dma.ib_put); nvchan_wr32(chan, 0x8c, chan->dma.ib_put);
chan->dma.ib_free--; chan->dma.ib_free--;
} }
......
...@@ -83,6 +83,14 @@ MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration"); ...@@ -83,6 +83,14 @@ MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration");
int nouveau_nofbaccel = 0; int nouveau_nofbaccel = 0;
module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400); module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400);
MODULE_PARM_DESC(override_conntype, "Ignore DCB connector type");
int nouveau_override_conntype = 0;
module_param_named(override_conntype, nouveau_override_conntype, int, 0400);
MODULE_PARM_DESC(tv_disable, "Disable TV-out detection\n");
int nouveau_tv_disable = 0;
module_param_named(tv_disable, nouveau_tv_disable, int, 0400);
MODULE_PARM_DESC(tv_norm, "Default TV norm.\n" MODULE_PARM_DESC(tv_norm, "Default TV norm.\n"
"\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n" "\t\tSupported: PAL, PAL-M, PAL-N, PAL-Nc, NTSC-M, NTSC-J,\n"
"\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n" "\t\t\thd480i, hd480p, hd576i, hd576p, hd720p, hd1080i.\n"
...@@ -154,9 +162,11 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) ...@@ -154,9 +162,11 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state)
if (pm_state.event == PM_EVENT_PRETHAW) if (pm_state.event == PM_EVENT_PRETHAW)
return 0; return 0;
NV_INFO(dev, "Disabling fbcon acceleration...\n");
fbdev_flags = dev_priv->fbdev_info->flags; fbdev_flags = dev_priv->fbdev_info->flags;
dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED; dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED;
NV_INFO(dev, "Unpinning framebuffer(s)...\n");
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_framebuffer *nouveau_fb; struct nouveau_framebuffer *nouveau_fb;
......
...@@ -681,6 +681,7 @@ extern int nouveau_uscript_tmds; ...@@ -681,6 +681,7 @@ extern int nouveau_uscript_tmds;
extern int nouveau_vram_pushbuf; extern int nouveau_vram_pushbuf;
extern int nouveau_vram_notify; extern int nouveau_vram_notify;
extern int nouveau_fbpercrtc; extern int nouveau_fbpercrtc;
extern int nouveau_tv_disable;
extern char *nouveau_tv_norm; extern char *nouveau_tv_norm;
extern int nouveau_reg_debug; extern int nouveau_reg_debug;
extern char *nouveau_vbios; extern char *nouveau_vbios;
...@@ -688,6 +689,7 @@ extern int nouveau_ctxfw; ...@@ -688,6 +689,7 @@ extern int nouveau_ctxfw;
extern int nouveau_ignorelid; extern int nouveau_ignorelid;
extern int nouveau_nofbaccel; extern int nouveau_nofbaccel;
extern int nouveau_noaccel; extern int nouveau_noaccel;
extern int nouveau_override_conntype;
extern int nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state); extern int nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state);
extern int nouveau_pci_resume(struct pci_dev *pdev); extern int nouveau_pci_resume(struct pci_dev *pdev);
...@@ -926,6 +928,10 @@ extern void nv40_fb_takedown(struct drm_device *); ...@@ -926,6 +928,10 @@ extern void nv40_fb_takedown(struct drm_device *);
extern void nv40_fb_set_region_tiling(struct drm_device *, int, uint32_t, extern void nv40_fb_set_region_tiling(struct drm_device *, int, uint32_t,
uint32_t, uint32_t); uint32_t, uint32_t);
/* nv50_fb.c */
extern int nv50_fb_init(struct drm_device *);
extern void nv50_fb_takedown(struct drm_device *);
/* nv04_fifo.c */ /* nv04_fifo.c */
extern int nv04_fifo_init(struct drm_device *); extern int nv04_fifo_init(struct drm_device *);
extern void nv04_fifo_disable(struct drm_device *); extern void nv04_fifo_disable(struct drm_device *);
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#include "nouveau_drm.h" #include "nouveau_drm.h"
#include "nv50_display.h" #include "nv50_display.h"
static int nouveau_stub_init(struct drm_device *dev) { return 0; }
static void nouveau_stub_takedown(struct drm_device *dev) {} static void nouveau_stub_takedown(struct drm_device *dev) {}
static int nouveau_init_engine_ptrs(struct drm_device *dev) static int nouveau_init_engine_ptrs(struct drm_device *dev)
...@@ -277,8 +276,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) ...@@ -277,8 +276,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->timer.init = nv04_timer_init; engine->timer.init = nv04_timer_init;
engine->timer.read = nv04_timer_read; engine->timer.read = nv04_timer_read;
engine->timer.takedown = nv04_timer_takedown; engine->timer.takedown = nv04_timer_takedown;
engine->fb.init = nouveau_stub_init; engine->fb.init = nv50_fb_init;
engine->fb.takedown = nouveau_stub_takedown; engine->fb.takedown = nv50_fb_takedown;
engine->graph.grclass = nv50_graph_grclass; engine->graph.grclass = nv50_graph_grclass;
engine->graph.init = nv50_graph_init; engine->graph.init = nv50_graph_init;
engine->graph.takedown = nv50_graph_takedown; engine->graph.takedown = nv50_graph_takedown;
......
...@@ -230,9 +230,9 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode) ...@@ -230,9 +230,9 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode)
struct drm_framebuffer *fb = crtc->fb; struct drm_framebuffer *fb = crtc->fb;
/* Calculate our timings */ /* Calculate our timings */
int horizDisplay = (mode->crtc_hdisplay >> 3) - 1; int horizDisplay = (mode->crtc_hdisplay >> 3) - 1;
int horizStart = (mode->crtc_hsync_start >> 3) - 1; int horizStart = (mode->crtc_hsync_start >> 3) + 1;
int horizEnd = (mode->crtc_hsync_end >> 3) - 1; int horizEnd = (mode->crtc_hsync_end >> 3) + 1;
int horizTotal = (mode->crtc_htotal >> 3) - 5; int horizTotal = (mode->crtc_htotal >> 3) - 5;
int horizBlankStart = (mode->crtc_hdisplay >> 3) - 1; int horizBlankStart = (mode->crtc_hdisplay >> 3) - 1;
int horizBlankEnd = (mode->crtc_htotal >> 3) - 1; int horizBlankEnd = (mode->crtc_htotal >> 3) - 1;
......
...@@ -118,8 +118,8 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) ...@@ -118,8 +118,8 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
return; return;
} }
width = ALIGN(image->width, 32); width = ALIGN(image->width, 8);
dsize = (width * image->height) >> 5; dsize = ALIGN(width * image->height, 32) >> 5;
if (info->fix.visual == FB_VISUAL_TRUECOLOR || if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
info->fix.visual == FB_VISUAL_DIRECTCOLOR) { info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
...@@ -136,8 +136,8 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) ...@@ -136,8 +136,8 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
((image->dx + image->width) & 0xffff)); ((image->dx + image->width) & 0xffff));
OUT_RING(chan, bg); OUT_RING(chan, bg);
OUT_RING(chan, fg); OUT_RING(chan, fg);
OUT_RING(chan, (image->height << 16) | image->width);
OUT_RING(chan, (image->height << 16) | width); OUT_RING(chan, (image->height << 16) | width);
OUT_RING(chan, (image->height << 16) | image->width);
OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff)); OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
while (dsize) { while (dsize) {
......
...@@ -522,8 +522,8 @@ int nv50_display_create(struct drm_device *dev) ...@@ -522,8 +522,8 @@ int nv50_display_create(struct drm_device *dev)
} }
for (i = 0 ; i < dcb->connector.entries; i++) { for (i = 0 ; i < dcb->connector.entries; i++) {
if (i != 0 && dcb->connector.entry[i].index == if (i != 0 && dcb->connector.entry[i].index2 ==
dcb->connector.entry[i - 1].index) dcb->connector.entry[i - 1].index2)
continue; continue;
nouveau_connector_create(dev, &dcb->connector.entry[i]); nouveau_connector_create(dev, &dcb->connector.entry[i]);
} }
......
#include "drmP.h"
#include "drm.h"
#include "nouveau_drv.h"
#include "nouveau_drm.h"
int
nv50_fb_init(struct drm_device *dev)
{
/* This is needed to get meaningful information from 100c90
* on traps. No idea what these values mean exactly. */
struct drm_nouveau_private *dev_priv = dev->dev_private;
switch (dev_priv->chipset) {
case 0x50:
nv_wr32(dev, 0x100c90, 0x0707ff);
break;
case 0xa5:
case 0xa8:
nv_wr32(dev, 0x100c90, 0x0d0fff);
break;
default:
nv_wr32(dev, 0x100c90, 0x1d07ff);
break;
}
return 0;
}
void
nv50_fb_takedown(struct drm_device *dev)
{
}
...@@ -233,7 +233,7 @@ nv50_fbcon_accel_init(struct fb_info *info) ...@@ -233,7 +233,7 @@ nv50_fbcon_accel_init(struct fb_info *info)
BEGIN_RING(chan, NvSub2D, 0x0808, 3); BEGIN_RING(chan, NvSub2D, 0x0808, 3);
OUT_RING(chan, 0); OUT_RING(chan, 0);
OUT_RING(chan, 0); OUT_RING(chan, 0);
OUT_RING(chan, 0); OUT_RING(chan, 1);
BEGIN_RING(chan, NvSub2D, 0x081c, 1); BEGIN_RING(chan, NvSub2D, 0x081c, 1);
OUT_RING(chan, 1); OUT_RING(chan, 1);
BEGIN_RING(chan, NvSub2D, 0x0840, 4); BEGIN_RING(chan, NvSub2D, 0x0840, 4);
......
...@@ -56,6 +56,10 @@ nv50_graph_init_intr(struct drm_device *dev) ...@@ -56,6 +56,10 @@ nv50_graph_init_intr(struct drm_device *dev)
static void static void
nv50_graph_init_regs__nv(struct drm_device *dev) nv50_graph_init_regs__nv(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private;
uint32_t units = nv_rd32(dev, 0x1540);
int i;
NV_DEBUG(dev, "\n"); NV_DEBUG(dev, "\n");
nv_wr32(dev, 0x400804, 0xc0000000); nv_wr32(dev, 0x400804, 0xc0000000);
...@@ -65,6 +69,20 @@ nv50_graph_init_regs__nv(struct drm_device *dev) ...@@ -65,6 +69,20 @@ nv50_graph_init_regs__nv(struct drm_device *dev)
nv_wr32(dev, 0x405018, 0xc0000000); nv_wr32(dev, 0x405018, 0xc0000000);
nv_wr32(dev, 0x402000, 0xc0000000); nv_wr32(dev, 0x402000, 0xc0000000);
for (i = 0; i < 16; i++) {
if (units & 1 << i) {
if (dev_priv->chipset < 0xa0) {
nv_wr32(dev, 0x408900 + (i << 12), 0xc0000000);
nv_wr32(dev, 0x408e08 + (i << 12), 0xc0000000);
nv_wr32(dev, 0x408314 + (i << 12), 0xc0000000);
} else {
nv_wr32(dev, 0x408600 + (i << 11), 0xc0000000);
nv_wr32(dev, 0x408708 + (i << 11), 0xc0000000);
nv_wr32(dev, 0x40831c + (i << 11), 0xc0000000);
}
}
}
nv_wr32(dev, 0x400108, 0xffffffff); nv_wr32(dev, 0x400108, 0xffffffff);
nv_wr32(dev, 0x400824, 0x00004000); nv_wr32(dev, 0x400824, 0x00004000);
...@@ -229,10 +247,6 @@ nv50_graph_create_context(struct nouveau_channel *chan) ...@@ -229,10 +247,6 @@ nv50_graph_create_context(struct nouveau_channel *chan)
nouveau_grctx_vals_load(dev, ctx); nouveau_grctx_vals_load(dev, ctx);
} }
nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12); nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12);
if ((dev_priv->chipset & 0xf0) == 0xa0)
nv_wo32(dev, ctx, 0x00004/4, 0x00000000);
else
nv_wo32(dev, ctx, 0x0011c/4, 0x00000000);
dev_priv->engine.instmem.finish_access(dev); dev_priv->engine.instmem.finish_access(dev);
return 0; return 0;
......
...@@ -64,6 +64,9 @@ ...@@ -64,6 +64,9 @@
#define CP_FLAG_ALWAYS ((2 * 32) + 13) #define CP_FLAG_ALWAYS ((2 * 32) + 13)
#define CP_FLAG_ALWAYS_FALSE 0 #define CP_FLAG_ALWAYS_FALSE 0
#define CP_FLAG_ALWAYS_TRUE 1 #define CP_FLAG_ALWAYS_TRUE 1
#define CP_FLAG_INTR ((2 * 32) + 15)
#define CP_FLAG_INTR_NOT_PENDING 0
#define CP_FLAG_INTR_PENDING 1
#define CP_CTX 0x00100000 #define CP_CTX 0x00100000
#define CP_CTX_COUNT 0x000f0000 #define CP_CTX_COUNT 0x000f0000
...@@ -214,6 +217,8 @@ nv50_grctx_init(struct nouveau_grctx *ctx) ...@@ -214,6 +217,8 @@ nv50_grctx_init(struct nouveau_grctx *ctx)
cp_name(ctx, cp_setup_save); cp_name(ctx, cp_setup_save);
cp_set (ctx, UNK1D, SET); cp_set (ctx, UNK1D, SET);
cp_wait(ctx, STATUS, BUSY); cp_wait(ctx, STATUS, BUSY);
cp_wait(ctx, INTR, PENDING);
cp_bra (ctx, STATUS, BUSY, cp_setup_save);
cp_set (ctx, UNK01, SET); cp_set (ctx, UNK01, SET);
cp_set (ctx, SWAP_DIRECTION, SAVE); cp_set (ctx, SWAP_DIRECTION, SAVE);
...@@ -269,7 +274,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) ...@@ -269,7 +274,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
int offset, base; int offset, base;
uint32_t units = nv_rd32 (ctx->dev, 0x1540); uint32_t units = nv_rd32 (ctx->dev, 0x1540);
/* 0800 */ /* 0800: DISPATCH */
cp_ctx(ctx, 0x400808, 7); cp_ctx(ctx, 0x400808, 7);
gr_def(ctx, 0x400814, 0x00000030); gr_def(ctx, 0x400814, 0x00000030);
cp_ctx(ctx, 0x400834, 0x32); cp_ctx(ctx, 0x400834, 0x32);
...@@ -300,7 +305,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) ...@@ -300,7 +305,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
gr_def(ctx, 0x400b20, 0x0001629d); gr_def(ctx, 0x400b20, 0x0001629d);
} }
/* 0C00 */ /* 0C00: VFETCH */
cp_ctx(ctx, 0x400c08, 0x2); cp_ctx(ctx, 0x400c08, 0x2);
gr_def(ctx, 0x400c08, 0x0000fe0c); gr_def(ctx, 0x400c08, 0x0000fe0c);
...@@ -326,7 +331,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) ...@@ -326,7 +331,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
cp_ctx(ctx, 0x401540, 0x5); cp_ctx(ctx, 0x401540, 0x5);
gr_def(ctx, 0x401550, 0x00001018); gr_def(ctx, 0x401550, 0x00001018);
/* 1800 */ /* 1800: STREAMOUT */
cp_ctx(ctx, 0x401814, 0x1); cp_ctx(ctx, 0x401814, 0x1);
gr_def(ctx, 0x401814, 0x000000ff); gr_def(ctx, 0x401814, 0x000000ff);
if (dev_priv->chipset == 0x50) { if (dev_priv->chipset == 0x50) {
...@@ -641,7 +646,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx) ...@@ -641,7 +646,7 @@ nv50_graph_construct_mmio(struct nouveau_grctx *ctx)
if (dev_priv->chipset == 0x50) if (dev_priv->chipset == 0x50)
cp_ctx(ctx, 0x4063e0, 0x1); cp_ctx(ctx, 0x4063e0, 0x1);
/* 6800 */ /* 6800: M2MF */
if (dev_priv->chipset < 0x90) { if (dev_priv->chipset < 0x90) {
cp_ctx(ctx, 0x406814, 0x2b); cp_ctx(ctx, 0x406814, 0x2b);
gr_def(ctx, 0x406818, 0x00000f80); gr_def(ctx, 0x406818, 0x00000f80);
......
...@@ -50,7 +50,7 @@ $(obj)/r600_cs.o: $(obj)/r600_reg_safe.h ...@@ -50,7 +50,7 @@ $(obj)/r600_cs.o: $(obj)/r600_reg_safe.h
radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \ radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o \
radeon_irq.o r300_cmdbuf.o r600_cp.o radeon_irq.o r300_cmdbuf.o r600_cp.o
# add KMS driver # add KMS driver
radeon-y += radeon_device.o radeon_kms.o \ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
radeon_atombios.o radeon_agp.o atombios_crtc.o radeon_combios.o \ radeon_atombios.o radeon_agp.o atombios_crtc.o radeon_combios.o \
atom.o radeon_fence.o radeon_ttm.o radeon_object.o radeon_gart.o \ atom.o radeon_fence.o radeon_ttm.o radeon_object.o radeon_gart.o \
radeon_legacy_crtc.o radeon_legacy_encoders.o radeon_connectors.o \ radeon_legacy_crtc.o radeon_legacy_encoders.o radeon_connectors.o \
......
...@@ -52,15 +52,17 @@ ...@@ -52,15 +52,17 @@
typedef struct { typedef struct {
struct atom_context *ctx; struct atom_context *ctx;
uint32_t *ps, *ws; uint32_t *ps, *ws;
int ps_shift; int ps_shift;
uint16_t start; uint16_t start;
unsigned last_jump;
unsigned long last_jump_jiffies;
bool abort;
} atom_exec_context; } atom_exec_context;
int atom_debug = 0; int atom_debug = 0;
static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params); static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params);
void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params); int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params);
static uint32_t atom_arg_mask[8] = static uint32_t atom_arg_mask[8] =
{ 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000, { 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000,
...@@ -604,12 +606,17 @@ static void atom_op_beep(atom_exec_context *ctx, int *ptr, int arg) ...@@ -604,12 +606,17 @@ static void atom_op_beep(atom_exec_context *ctx, int *ptr, int arg)
static void atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg) static void atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg)
{ {
int idx = U8((*ptr)++); int idx = U8((*ptr)++);
int r = 0;
if (idx < ATOM_TABLE_NAMES_CNT) if (idx < ATOM_TABLE_NAMES_CNT)
SDEBUG(" table: %d (%s)\n", idx, atom_table_names[idx]); SDEBUG(" table: %d (%s)\n", idx, atom_table_names[idx]);
else else
SDEBUG(" table: %d\n", idx); SDEBUG(" table: %d\n", idx);
if (U16(ctx->ctx->cmd_table + 4 + 2 * idx)) if (U16(ctx->ctx->cmd_table + 4 + 2 * idx))
atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift); r = atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
if (r) {
ctx->abort = true;
}
} }
static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg) static void atom_op_clear(atom_exec_context *ctx, int *ptr, int arg)
...@@ -673,6 +680,8 @@ static void atom_op_eot(atom_exec_context *ctx, int *ptr, int arg) ...@@ -673,6 +680,8 @@ static void atom_op_eot(atom_exec_context *ctx, int *ptr, int arg)
static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg) static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
{ {
int execute = 0, target = U16(*ptr); int execute = 0, target = U16(*ptr);
unsigned long cjiffies;
(*ptr) += 2; (*ptr) += 2;
switch (arg) { switch (arg) {
case ATOM_COND_ABOVE: case ATOM_COND_ABOVE:
...@@ -700,8 +709,25 @@ static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg) ...@@ -700,8 +709,25 @@ static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
if (arg != ATOM_COND_ALWAYS) if (arg != ATOM_COND_ALWAYS)
SDEBUG(" taken: %s\n", execute ? "yes" : "no"); SDEBUG(" taken: %s\n", execute ? "yes" : "no");
SDEBUG(" target: 0x%04X\n", target); SDEBUG(" target: 0x%04X\n", target);
if (execute) if (execute) {
if (ctx->last_jump == (ctx->start + target)) {
cjiffies = jiffies;
if (time_after(cjiffies, ctx->last_jump_jiffies)) {
cjiffies -= ctx->last_jump_jiffies;
if ((jiffies_to_msecs(cjiffies) > 1000)) {
DRM_ERROR("atombios stuck in loop for more than 1sec aborting\n");
ctx->abort = true;
}
} else {
/* jiffies wrap around we will just wait a little longer */
ctx->last_jump_jiffies = jiffies;
}
} else {
ctx->last_jump = ctx->start + target;
ctx->last_jump_jiffies = jiffies;
}
*ptr = ctx->start + target; *ptr = ctx->start + target;
}
} }
static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg) static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg)
...@@ -1104,7 +1130,7 @@ static struct { ...@@ -1104,7 +1130,7 @@ static struct {
atom_op_shr, ATOM_ARG_MC}, { atom_op_shr, ATOM_ARG_MC}, {
atom_op_debug, 0},}; atom_op_debug, 0},};
static void atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params) static int atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params)
{ {
int base = CU16(ctx->cmd_table + 4 + 2 * index); int base = CU16(ctx->cmd_table + 4 + 2 * index);
int len, ws, ps, ptr; int len, ws, ps, ptr;
...@@ -1112,7 +1138,7 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3 ...@@ -1112,7 +1138,7 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3
atom_exec_context ectx; atom_exec_context ectx;
if (!base) if (!base)
return; return -EINVAL;
len = CU16(base + ATOM_CT_SIZE_PTR); len = CU16(base + ATOM_CT_SIZE_PTR);
ws = CU8(base + ATOM_CT_WS_PTR); ws = CU8(base + ATOM_CT_WS_PTR);
...@@ -1125,6 +1151,8 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3 ...@@ -1125,6 +1151,8 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3
ectx.ps_shift = ps / 4; ectx.ps_shift = ps / 4;
ectx.start = base; ectx.start = base;
ectx.ps = params; ectx.ps = params;
ectx.abort = false;
ectx.last_jump = 0;
if (ws) if (ws)
ectx.ws = kzalloc(4 * ws, GFP_KERNEL); ectx.ws = kzalloc(4 * ws, GFP_KERNEL);
else else
...@@ -1137,6 +1165,11 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3 ...@@ -1137,6 +1165,11 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3
SDEBUG("%s @ 0x%04X\n", atom_op_names[op], ptr - 1); SDEBUG("%s @ 0x%04X\n", atom_op_names[op], ptr - 1);
else else
SDEBUG("[%d] @ 0x%04X\n", op, ptr - 1); SDEBUG("[%d] @ 0x%04X\n", op, ptr - 1);
if (ectx.abort) {
DRM_ERROR("atombios stuck executing %04X (len %d, WS %d, PS %d) @ 0x%04X\n",
base, len, ws, ps, ptr - 1);
return -EINVAL;
}
if (op < ATOM_OP_CNT && op > 0) if (op < ATOM_OP_CNT && op > 0)
opcode_table[op].func(&ectx, &ptr, opcode_table[op].func(&ectx, &ptr,
...@@ -1152,10 +1185,13 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3 ...@@ -1152,10 +1185,13 @@ static void atom_execute_table_locked(struct atom_context *ctx, int index, uint3
if (ws) if (ws)
kfree(ectx.ws); kfree(ectx.ws);
return 0;
} }
void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
{ {
int r;
mutex_lock(&ctx->mutex); mutex_lock(&ctx->mutex);
/* reset reg block */ /* reset reg block */
ctx->reg_block = 0; ctx->reg_block = 0;
...@@ -1163,8 +1199,9 @@ void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params) ...@@ -1163,8 +1199,9 @@ void atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
ctx->fb_base = 0; ctx->fb_base = 0;
/* reset io mode */ /* reset io mode */
ctx->io_mode = ATOM_IO_MM; ctx->io_mode = ATOM_IO_MM;
atom_execute_table_locked(ctx, index, params); r = atom_execute_table_locked(ctx, index, params);
mutex_unlock(&ctx->mutex); mutex_unlock(&ctx->mutex);
return r;
} }
static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 }; static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 };
...@@ -1248,9 +1285,7 @@ int atom_asic_init(struct atom_context *ctx) ...@@ -1248,9 +1285,7 @@ int atom_asic_init(struct atom_context *ctx)
if (!CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_INIT)) if (!CU16(ctx->cmd_table + 4 + 2 * ATOM_CMD_INIT))
return 1; return 1;
atom_execute_table(ctx, ATOM_CMD_INIT, ps); return atom_execute_table(ctx, ATOM_CMD_INIT, ps);
return 0;
} }
void atom_destroy(struct atom_context *ctx) void atom_destroy(struct atom_context *ctx)
...@@ -1260,12 +1295,16 @@ void atom_destroy(struct atom_context *ctx) ...@@ -1260,12 +1295,16 @@ void atom_destroy(struct atom_context *ctx)
kfree(ctx); kfree(ctx);
} }
void atom_parse_data_header(struct atom_context *ctx, int index, bool atom_parse_data_header(struct atom_context *ctx, int index,
uint16_t * size, uint8_t * frev, uint8_t * crev, uint16_t * size, uint8_t * frev, uint8_t * crev,
uint16_t * data_start) uint16_t * data_start)
{ {
int offset = index * 2 + 4; int offset = index * 2 + 4;
int idx = CU16(ctx->data_table + offset); int idx = CU16(ctx->data_table + offset);
u16 *mdt = (u16 *)(ctx->bios + ctx->data_table + 4);
if (!mdt[index])
return false;
if (size) if (size)
*size = CU16(idx); *size = CU16(idx);
...@@ -1274,38 +1313,42 @@ void atom_parse_data_header(struct atom_context *ctx, int index, ...@@ -1274,38 +1313,42 @@ void atom_parse_data_header(struct atom_context *ctx, int index,
if (crev) if (crev)
*crev = CU8(idx + 3); *crev = CU8(idx + 3);
*data_start = idx; *data_start = idx;
return; return true;
} }
void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev, bool atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t * frev,
uint8_t * crev) uint8_t * crev)
{ {
int offset = index * 2 + 4; int offset = index * 2 + 4;
int idx = CU16(ctx->cmd_table + offset); int idx = CU16(ctx->cmd_table + offset);
u16 *mct = (u16 *)(ctx->bios + ctx->cmd_table + 4);
if (!mct[index])
return false;
if (frev) if (frev)
*frev = CU8(idx + 2); *frev = CU8(idx + 2);
if (crev) if (crev)
*crev = CU8(idx + 3); *crev = CU8(idx + 3);
return; return true;
} }
int atom_allocate_fb_scratch(struct atom_context *ctx) int atom_allocate_fb_scratch(struct atom_context *ctx)
{ {
int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware); int index = GetIndexIntoMasterTable(DATA, VRAM_UsageByFirmware);
uint16_t data_offset; uint16_t data_offset;
int usage_bytes; int usage_bytes = 0;
struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage; struct _ATOM_VRAM_USAGE_BY_FIRMWARE *firmware_usage;
atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset); if (atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) {
firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset);
firmware_usage = (struct _ATOM_VRAM_USAGE_BY_FIRMWARE *)(ctx->bios + data_offset); DRM_DEBUG("atom firmware requested %08x %dkb\n",
firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware,
firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb);
DRM_DEBUG("atom firmware requested %08x %dkb\n", usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
firmware_usage->asFirmwareVramReserveInfo[0].ulStartAddrUsedByFirmware, }
firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb);
usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
if (usage_bytes == 0) if (usage_bytes == 0)
usage_bytes = 20 * 1024; usage_bytes = 20 * 1024;
/* allocate some scratch memory */ /* allocate some scratch memory */
......
...@@ -140,11 +140,13 @@ struct atom_context { ...@@ -140,11 +140,13 @@ struct atom_context {
extern int atom_debug; extern int atom_debug;
struct atom_context *atom_parse(struct card_info *, void *); struct atom_context *atom_parse(struct card_info *, void *);
void atom_execute_table(struct atom_context *, int, uint32_t *); int atom_execute_table(struct atom_context *, int, uint32_t *);
int atom_asic_init(struct atom_context *); int atom_asic_init(struct atom_context *);
void atom_destroy(struct atom_context *); void atom_destroy(struct atom_context *);
void atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size, uint8_t *frev, uint8_t *crev, uint16_t *data_start); bool atom_parse_data_header(struct atom_context *ctx, int index, uint16_t *size,
void atom_parse_cmd_header(struct atom_context *ctx, int index, uint8_t *frev, uint8_t *crev); uint8_t *frev, uint8_t *crev, uint16_t *data_start);
bool atom_parse_cmd_header(struct atom_context *ctx, int index,
uint8_t *frev, uint8_t *crev);
int atom_allocate_fb_scratch(struct atom_context *ctx); int atom_allocate_fb_scratch(struct atom_context *ctx);
#include "atom-types.h" #include "atom-types.h"
#include "atombios.h" #include "atombios.h"
......
...@@ -353,12 +353,55 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc, ...@@ -353,12 +353,55 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc,
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
} }
static void atombios_disable_ss(struct drm_crtc *crtc)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
u32 ss_cntl;
if (ASIC_IS_DCE4(rdev)) {
switch (radeon_crtc->pll_id) {
case ATOM_PPLL1:
ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL);
ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
WREG32(EVERGREEN_P1PLL_SS_CNTL, ss_cntl);
break;
case ATOM_PPLL2:
ss_cntl = RREG32(EVERGREEN_P2PLL_SS_CNTL);
ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
WREG32(EVERGREEN_P2PLL_SS_CNTL, ss_cntl);
break;
case ATOM_DCPLL:
case ATOM_PPLL_INVALID:
return;
}
} else if (ASIC_IS_AVIVO(rdev)) {
switch (radeon_crtc->pll_id) {
case ATOM_PPLL1:
ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL);
ss_cntl &= ~1;
WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl);
break;
case ATOM_PPLL2:
ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL);
ss_cntl &= ~1;
WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl);
break;
case ATOM_DCPLL:
case ATOM_PPLL_INVALID:
return;
}
}
}
union atom_enable_ss { union atom_enable_ss {
ENABLE_LVDS_SS_PARAMETERS legacy; ENABLE_LVDS_SS_PARAMETERS legacy;
ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1; ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1;
}; };
static void atombios_set_ss(struct drm_crtc *crtc, int enable) static void atombios_enable_ss(struct drm_crtc *crtc)
{ {
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
...@@ -387,9 +430,9 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable) ...@@ -387,9 +430,9 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable)
step = dig->ss->step; step = dig->ss->step;
delay = dig->ss->delay; delay = dig->ss->delay;
range = dig->ss->range; range = dig->ss->range;
} else if (enable) } else
return; return;
} else if (enable) } else
return; return;
break; break;
} }
...@@ -406,13 +449,13 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable) ...@@ -406,13 +449,13 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable)
args.v1.ucSpreadSpectrumDelay = delay; args.v1.ucSpreadSpectrumDelay = delay;
args.v1.ucSpreadSpectrumRange = range; args.v1.ucSpreadSpectrumRange = range;
args.v1.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; args.v1.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
args.v1.ucEnable = enable; args.v1.ucEnable = ATOM_ENABLE;
} else { } else {
args.legacy.usSpreadSpectrumPercentage = cpu_to_le16(percentage); args.legacy.usSpreadSpectrumPercentage = cpu_to_le16(percentage);
args.legacy.ucSpreadSpectrumType = type; args.legacy.ucSpreadSpectrumType = type;
args.legacy.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2; args.legacy.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2;
args.legacy.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4; args.legacy.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4;
args.legacy.ucEnable = enable; args.legacy.ucEnable = ATOM_ENABLE;
} }
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
} }
...@@ -478,11 +521,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, ...@@ -478,11 +521,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
/* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */
if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1)
adjusted_clock = mode->clock * 2; adjusted_clock = mode->clock * 2;
/* LVDS PLL quirks */
if (encoder->encoder_type == DRM_MODE_ENCODER_LVDS) {
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
pll->algo = dig->pll_algo;
}
} else { } else {
if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) if (encoder->encoder_type != DRM_MODE_ENCODER_DAC)
pll->flags |= RADEON_PLL_NO_ODD_POST_DIV; pll->flags |= RADEON_PLL_NO_ODD_POST_DIV;
...@@ -503,8 +541,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, ...@@ -503,8 +541,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
int index; int index;
index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll); index = GetIndexIntoMasterTable(COMMAND, AdjustDisplayPll);
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
&crev); &crev))
return adjusted_clock;
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
...@@ -542,11 +581,16 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, ...@@ -542,11 +581,16 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
} }
} else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
/* may want to enable SS on DP/eDP eventually */ /* may want to enable SS on DP/eDP eventually */
args.v3.sInput.ucDispPllConfig |= /*args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_SS_ENABLE; DISPPLL_CONFIG_SS_ENABLE;*/
if (mode->clock > 165000) if (encoder_mode == ATOM_ENCODER_MODE_DP)
args.v3.sInput.ucDispPllConfig |= args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_DUAL_LINK; DISPPLL_CONFIG_COHERENT_MODE;
else {
if (mode->clock > 165000)
args.v3.sInput.ucDispPllConfig |=
DISPPLL_CONFIG_DUAL_LINK;
}
} }
atom_execute_table(rdev->mode_info.atom_context, atom_execute_table(rdev->mode_info.atom_context,
index, (uint32_t *)&args); index, (uint32_t *)&args);
...@@ -592,8 +636,9 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc) ...@@ -592,8 +636,9 @@ static void atombios_crtc_set_dcpll(struct drm_crtc *crtc)
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
&crev); &crev))
return;
switch (frev) { switch (frev) {
case 1: case 1:
...@@ -667,8 +712,9 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode ...@@ -667,8 +712,9 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
&ref_div, &post_div); &ref_div, &post_div);
index = GetIndexIntoMasterTable(COMMAND, SetPixelClock); index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
&crev); &crev))
return;
switch (frev) { switch (frev) {
case 1: case 1:
...@@ -1083,15 +1129,12 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, ...@@ -1083,15 +1129,12 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
/* TODO color tiling */ /* TODO color tiling */
/* pick pll */ atombios_disable_ss(crtc);
radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
atombios_set_ss(crtc, 0);
/* always set DCPLL */ /* always set DCPLL */
if (ASIC_IS_DCE4(rdev)) if (ASIC_IS_DCE4(rdev))
atombios_crtc_set_dcpll(crtc); atombios_crtc_set_dcpll(crtc);
atombios_crtc_set_pll(crtc, adjusted_mode); atombios_crtc_set_pll(crtc, adjusted_mode);
atombios_set_ss(crtc, 1); atombios_enable_ss(crtc);
if (ASIC_IS_DCE4(rdev)) if (ASIC_IS_DCE4(rdev))
atombios_set_crtc_dtd_timing(crtc, adjusted_mode); atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
...@@ -1120,6 +1163,11 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, ...@@ -1120,6 +1163,11 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc,
static void atombios_crtc_prepare(struct drm_crtc *crtc) static void atombios_crtc_prepare(struct drm_crtc *crtc)
{ {
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
/* pick pll */
radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
atombios_lock_crtc(crtc, ATOM_ENABLE); atombios_lock_crtc(crtc, ATOM_ENABLE);
atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
} }
......
...@@ -745,14 +745,14 @@ void dp_link_train(struct drm_encoder *encoder, ...@@ -745,14 +745,14 @@ void dp_link_train(struct drm_encoder *encoder,
>> DP_TRAIN_PRE_EMPHASIS_SHIFT); >> DP_TRAIN_PRE_EMPHASIS_SHIFT);
/* disable the training pattern on the sink */ /* disable the training pattern on the sink */
dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE);
/* disable the training pattern on the source */
if (ASIC_IS_DCE4(rdev)) if (ASIC_IS_DCE4(rdev))
atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE); atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE);
else else
radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE, radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
dig_connector->dp_clock, enc_id, 0); dig_connector->dp_clock, enc_id, 0);
radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
dig_connector->dp_clock, enc_id, 0);
} }
int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include "drmP.h" #include "drmP.h"
#include "radeon.h" #include "radeon.h"
#include "radeon_asic.h"
#include "radeon_drm.h" #include "radeon_drm.h"
#include "rv770d.h" #include "rv770d.h"
#include "atom.h" #include "atom.h"
...@@ -436,7 +437,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev) ...@@ -436,7 +437,6 @@ static void evergreen_gpu_init(struct radeon_device *rdev)
int evergreen_mc_init(struct radeon_device *rdev) int evergreen_mc_init(struct radeon_device *rdev)
{ {
fixed20_12 a;
u32 tmp; u32 tmp;
int chansize, numchan; int chansize, numchan;
...@@ -481,12 +481,8 @@ int evergreen_mc_init(struct radeon_device *rdev) ...@@ -481,12 +481,8 @@ int evergreen_mc_init(struct radeon_device *rdev)
rdev->mc.real_vram_size = rdev->mc.aper_size; rdev->mc.real_vram_size = rdev->mc.aper_size;
} }
r600_vram_gtt_location(rdev, &rdev->mc); r600_vram_gtt_location(rdev, &rdev->mc);
/* FIXME: we should enforce default clock in case GPU is not in radeon_update_bandwidth_info(rdev);
* default setup
*/
a.full = rfixed_const(100);
rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
return 0; return 0;
} }
...@@ -746,6 +742,7 @@ int evergreen_init(struct radeon_device *rdev) ...@@ -746,6 +742,7 @@ int evergreen_init(struct radeon_device *rdev)
void evergreen_fini(struct radeon_device *rdev) void evergreen_fini(struct radeon_device *rdev)
{ {
radeon_pm_fini(rdev);
evergreen_suspend(rdev); evergreen_suspend(rdev);
#if 0 #if 0
r600_blit_fini(rdev); r600_blit_fini(rdev);
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "radeon_drm.h" #include "radeon_drm.h"
#include "radeon_reg.h" #include "radeon_reg.h"
#include "radeon.h" #include "radeon.h"
#include "radeon_asic.h"
#include "r100d.h" #include "r100d.h"
#include "rs100d.h" #include "rs100d.h"
#include "rv200d.h" #include "rv200d.h"
...@@ -235,9 +236,9 @@ int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) ...@@ -235,9 +236,9 @@ int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
void r100_pci_gart_fini(struct radeon_device *rdev) void r100_pci_gart_fini(struct radeon_device *rdev)
{ {
radeon_gart_fini(rdev);
r100_pci_gart_disable(rdev); r100_pci_gart_disable(rdev);
radeon_gart_table_ram_free(rdev); radeon_gart_table_ram_free(rdev);
radeon_gart_fini(rdev);
} }
int r100_irq_set(struct radeon_device *rdev) int r100_irq_set(struct radeon_device *rdev)
...@@ -312,10 +313,12 @@ int r100_irq_process(struct radeon_device *rdev) ...@@ -312,10 +313,12 @@ int r100_irq_process(struct radeon_device *rdev)
/* Vertical blank interrupts */ /* Vertical blank interrupts */
if (status & RADEON_CRTC_VBLANK_STAT) { if (status & RADEON_CRTC_VBLANK_STAT) {
drm_handle_vblank(rdev->ddev, 0); drm_handle_vblank(rdev->ddev, 0);
rdev->pm.vblank_sync = true;
wake_up(&rdev->irq.vblank_queue); wake_up(&rdev->irq.vblank_queue);
} }
if (status & RADEON_CRTC2_VBLANK_STAT) { if (status & RADEON_CRTC2_VBLANK_STAT) {
drm_handle_vblank(rdev->ddev, 1); drm_handle_vblank(rdev->ddev, 1);
rdev->pm.vblank_sync = true;
wake_up(&rdev->irq.vblank_queue); wake_up(&rdev->irq.vblank_queue);
} }
if (status & RADEON_FP_DETECT_STAT) { if (status & RADEON_FP_DETECT_STAT) {
...@@ -741,6 +744,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) ...@@ -741,6 +744,8 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size)
udelay(10); udelay(10);
rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR);
rdev->cp.wptr = RREG32(RADEON_CP_RB_WPTR); rdev->cp.wptr = RREG32(RADEON_CP_RB_WPTR);
/* protect against crazy HW on resume */
rdev->cp.wptr &= rdev->cp.ptr_mask;
/* Set cp mode to bus mastering & enable cp*/ /* Set cp mode to bus mastering & enable cp*/
WREG32(RADEON_CP_CSQ_MODE, WREG32(RADEON_CP_CSQ_MODE,
REG_SET(RADEON_INDIRECT2_START, indirect2_start) | REG_SET(RADEON_INDIRECT2_START, indirect2_start) |
...@@ -1804,6 +1809,7 @@ void r100_set_common_regs(struct radeon_device *rdev) ...@@ -1804,6 +1809,7 @@ void r100_set_common_regs(struct radeon_device *rdev)
{ {
struct drm_device *dev = rdev->ddev; struct drm_device *dev = rdev->ddev;
bool force_dac2 = false; bool force_dac2 = false;
u32 tmp;
/* set these so they don't interfere with anything */ /* set these so they don't interfere with anything */
WREG32(RADEON_OV0_SCALE_CNTL, 0); WREG32(RADEON_OV0_SCALE_CNTL, 0);
...@@ -1875,6 +1881,12 @@ void r100_set_common_regs(struct radeon_device *rdev) ...@@ -1875,6 +1881,12 @@ void r100_set_common_regs(struct radeon_device *rdev)
WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug); WREG32(RADEON_DISP_HW_DEBUG, disp_hw_debug);
WREG32(RADEON_DAC_CNTL2, dac2_cntl); WREG32(RADEON_DAC_CNTL2, dac2_cntl);
} }
/* switch PM block to ACPI mode */
tmp = RREG32_PLL(RADEON_PLL_PWRMGT_CNTL);
tmp &= ~RADEON_PM_MODE_SEL;
WREG32_PLL(RADEON_PLL_PWRMGT_CNTL, tmp);
} }
/* /*
...@@ -2022,6 +2034,7 @@ void r100_mc_init(struct radeon_device *rdev) ...@@ -2022,6 +2034,7 @@ void r100_mc_init(struct radeon_device *rdev)
radeon_vram_location(rdev, &rdev->mc, base); radeon_vram_location(rdev, &rdev->mc, base);
if (!(rdev->flags & RADEON_IS_AGP)) if (!(rdev->flags & RADEON_IS_AGP))
radeon_gtt_location(rdev, &rdev->mc); radeon_gtt_location(rdev, &rdev->mc);
radeon_update_bandwidth_info(rdev);
} }
...@@ -2385,6 +2398,8 @@ void r100_bandwidth_update(struct radeon_device *rdev) ...@@ -2385,6 +2398,8 @@ void r100_bandwidth_update(struct radeon_device *rdev)
uint32_t pixel_bytes1 = 0; uint32_t pixel_bytes1 = 0;
uint32_t pixel_bytes2 = 0; uint32_t pixel_bytes2 = 0;
radeon_update_display_priority(rdev);
if (rdev->mode_info.crtcs[0]->base.enabled) { if (rdev->mode_info.crtcs[0]->base.enabled) {
mode1 = &rdev->mode_info.crtcs[0]->base.mode; mode1 = &rdev->mode_info.crtcs[0]->base.mode;
pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8; pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8;
...@@ -2413,11 +2428,8 @@ void r100_bandwidth_update(struct radeon_device *rdev) ...@@ -2413,11 +2428,8 @@ void r100_bandwidth_update(struct radeon_device *rdev)
/* /*
* determine is there is enough bw for current mode * determine is there is enough bw for current mode
*/ */
mclk_ff.full = rfixed_const(rdev->clock.default_mclk); sclk_ff = rdev->pm.sclk;
temp_ff.full = rfixed_const(100); mclk_ff = rdev->pm.mclk;
mclk_ff.full = rfixed_div(mclk_ff, temp_ff);
sclk_ff.full = rfixed_const(rdev->clock.default_sclk);
sclk_ff.full = rfixed_div(sclk_ff, temp_ff);
temp = (rdev->mc.vram_width / 8) * (rdev->mc.vram_is_ddr ? 2 : 1); temp = (rdev->mc.vram_width / 8) * (rdev->mc.vram_is_ddr ? 2 : 1);
temp_ff.full = rfixed_const(temp); temp_ff.full = rfixed_const(temp);
...@@ -3440,6 +3452,7 @@ int r100_suspend(struct radeon_device *rdev) ...@@ -3440,6 +3452,7 @@ int r100_suspend(struct radeon_device *rdev)
void r100_fini(struct radeon_device *rdev) void r100_fini(struct radeon_device *rdev)
{ {
radeon_pm_fini(rdev);
r100_cp_fini(rdev); r100_cp_fini(rdev);
r100_wb_fini(rdev); r100_wb_fini(rdev);
r100_ib_fini(rdev); r100_ib_fini(rdev);
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "radeon_drm.h" #include "radeon_drm.h"
#include "radeon_reg.h" #include "radeon_reg.h"
#include "radeon.h" #include "radeon.h"
#include "radeon_asic.h"
#include "r100d.h" #include "r100d.h"
#include "r200_reg_safe.h" #include "r200_reg_safe.h"
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "drm.h" #include "drm.h"
#include "radeon_reg.h" #include "radeon_reg.h"
#include "radeon.h" #include "radeon.h"
#include "radeon_asic.h"
#include "radeon_drm.h" #include "radeon_drm.h"
#include "r100_track.h" #include "r100_track.h"
#include "r300d.h" #include "r300d.h"
...@@ -164,9 +165,9 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev) ...@@ -164,9 +165,9 @@ void rv370_pcie_gart_disable(struct radeon_device *rdev)
void rv370_pcie_gart_fini(struct radeon_device *rdev) void rv370_pcie_gart_fini(struct radeon_device *rdev)
{ {
radeon_gart_fini(rdev);
rv370_pcie_gart_disable(rdev); rv370_pcie_gart_disable(rdev);
radeon_gart_table_vram_free(rdev); radeon_gart_table_vram_free(rdev);
radeon_gart_fini(rdev);
} }
void r300_fence_ring_emit(struct radeon_device *rdev, void r300_fence_ring_emit(struct radeon_device *rdev,
...@@ -481,6 +482,7 @@ void r300_mc_init(struct radeon_device *rdev) ...@@ -481,6 +482,7 @@ void r300_mc_init(struct radeon_device *rdev)
radeon_vram_location(rdev, &rdev->mc, base); radeon_vram_location(rdev, &rdev->mc, base);
if (!(rdev->flags & RADEON_IS_AGP)) if (!(rdev->flags & RADEON_IS_AGP))
radeon_gtt_location(rdev, &rdev->mc); radeon_gtt_location(rdev, &rdev->mc);
radeon_update_bandwidth_info(rdev);
} }
void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes) void rv370_set_pcie_lanes(struct radeon_device *rdev, int lanes)
...@@ -1334,6 +1336,7 @@ int r300_suspend(struct radeon_device *rdev) ...@@ -1334,6 +1336,7 @@ int r300_suspend(struct radeon_device *rdev)
void r300_fini(struct radeon_device *rdev) void r300_fini(struct radeon_device *rdev)
{ {
radeon_pm_fini(rdev);
r100_cp_fini(rdev); r100_cp_fini(rdev);
r100_wb_fini(rdev); r100_wb_fini(rdev);
r100_ib_fini(rdev); r100_ib_fini(rdev);
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "drmP.h" #include "drmP.h"
#include "radeon_reg.h" #include "radeon_reg.h"
#include "radeon.h" #include "radeon.h"
#include "radeon_asic.h"
#include "atom.h" #include "atom.h"
#include "r100d.h" #include "r100d.h"
#include "r420d.h" #include "r420d.h"
...@@ -266,6 +267,7 @@ int r420_suspend(struct radeon_device *rdev) ...@@ -266,6 +267,7 @@ int r420_suspend(struct radeon_device *rdev)
void r420_fini(struct radeon_device *rdev) void r420_fini(struct radeon_device *rdev)
{ {
radeon_pm_fini(rdev);
r100_cp_fini(rdev); r100_cp_fini(rdev);
r100_wb_fini(rdev); r100_wb_fini(rdev);
r100_ib_fini(rdev); r100_ib_fini(rdev);
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
*/ */
#include "drmP.h" #include "drmP.h"
#include "radeon.h" #include "radeon.h"
#include "radeon_asic.h"
#include "atom.h" #include "atom.h"
#include "r520d.h" #include "r520d.h"
...@@ -121,19 +122,13 @@ static void r520_vram_get_type(struct radeon_device *rdev) ...@@ -121,19 +122,13 @@ static void r520_vram_get_type(struct radeon_device *rdev)
void r520_mc_init(struct radeon_device *rdev) void r520_mc_init(struct radeon_device *rdev)
{ {
fixed20_12 a;
r520_vram_get_type(rdev); r520_vram_get_type(rdev);
r100_vram_init_sizes(rdev); r100_vram_init_sizes(rdev);
radeon_vram_location(rdev, &rdev->mc, 0); radeon_vram_location(rdev, &rdev->mc, 0);
if (!(rdev->flags & RADEON_IS_AGP)) if (!(rdev->flags & RADEON_IS_AGP))
radeon_gtt_location(rdev, &rdev->mc); radeon_gtt_location(rdev, &rdev->mc);
/* FIXME: we should enforce default clock in case GPU is not in radeon_update_bandwidth_info(rdev);
* default setup
*/
a.full = rfixed_const(100);
rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
} }
void r520_mc_program(struct radeon_device *rdev) void r520_mc_program(struct radeon_device *rdev)
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "drmP.h" #include "drmP.h"
#include "radeon_drm.h" #include "radeon_drm.h"
#include "radeon.h" #include "radeon.h"
#include "radeon_asic.h"
#include "radeon_mode.h" #include "radeon_mode.h"
#include "r600d.h" #include "r600d.h"
#include "atom.h" #include "atom.h"
...@@ -491,9 +492,9 @@ void r600_pcie_gart_disable(struct radeon_device *rdev) ...@@ -491,9 +492,9 @@ void r600_pcie_gart_disable(struct radeon_device *rdev)
void r600_pcie_gart_fini(struct radeon_device *rdev) void r600_pcie_gart_fini(struct radeon_device *rdev)
{ {
radeon_gart_fini(rdev);
r600_pcie_gart_disable(rdev); r600_pcie_gart_disable(rdev);
radeon_gart_table_vram_free(rdev); radeon_gart_table_vram_free(rdev);
radeon_gart_fini(rdev);
} }
void r600_agp_enable(struct radeon_device *rdev) void r600_agp_enable(struct radeon_device *rdev)
...@@ -675,7 +676,6 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) ...@@ -675,7 +676,6 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
int r600_mc_init(struct radeon_device *rdev) int r600_mc_init(struct radeon_device *rdev)
{ {
fixed20_12 a;
u32 tmp; u32 tmp;
int chansize, numchan; int chansize, numchan;
...@@ -719,14 +719,10 @@ int r600_mc_init(struct radeon_device *rdev) ...@@ -719,14 +719,10 @@ int r600_mc_init(struct radeon_device *rdev)
rdev->mc.real_vram_size = rdev->mc.aper_size; rdev->mc.real_vram_size = rdev->mc.aper_size;
} }
r600_vram_gtt_location(rdev, &rdev->mc); r600_vram_gtt_location(rdev, &rdev->mc);
/* FIXME: we should enforce default clock in case GPU is not in
* default setup
*/
a.full = rfixed_const(100);
rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
if (rdev->flags & RADEON_IS_IGP) if (rdev->flags & RADEON_IS_IGP)
rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
radeon_update_bandwidth_info(rdev);
return 0; return 0;
} }
...@@ -1132,6 +1128,7 @@ void r600_gpu_init(struct radeon_device *rdev) ...@@ -1132,6 +1128,7 @@ void r600_gpu_init(struct radeon_device *rdev)
/* Setup pipes */ /* Setup pipes */
WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);
WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
tmp = R6XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8); tmp = R6XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8);
WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK); WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK);
...@@ -2119,6 +2116,7 @@ int r600_init(struct radeon_device *rdev) ...@@ -2119,6 +2116,7 @@ int r600_init(struct radeon_device *rdev)
void r600_fini(struct radeon_device *rdev) void r600_fini(struct radeon_device *rdev)
{ {
radeon_pm_fini(rdev);
r600_audio_fini(rdev); r600_audio_fini(rdev);
r600_blit_fini(rdev); r600_blit_fini(rdev);
r600_cp_fini(rdev); r600_cp_fini(rdev);
...@@ -2398,19 +2396,19 @@ static void r600_disable_interrupt_state(struct radeon_device *rdev) ...@@ -2398,19 +2396,19 @@ static void r600_disable_interrupt_state(struct radeon_device *rdev)
WREG32(DC_HPD4_INT_CONTROL, tmp); WREG32(DC_HPD4_INT_CONTROL, tmp);
if (ASIC_IS_DCE32(rdev)) { if (ASIC_IS_DCE32(rdev)) {
tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY; tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY;
WREG32(DC_HPD5_INT_CONTROL, 0); WREG32(DC_HPD5_INT_CONTROL, tmp);
tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY;
WREG32(DC_HPD6_INT_CONTROL, 0); WREG32(DC_HPD6_INT_CONTROL, tmp);
} }
} else { } else {
WREG32(DACA_AUTODETECT_INT_CONTROL, 0); WREG32(DACA_AUTODETECT_INT_CONTROL, 0);
WREG32(DACB_AUTODETECT_INT_CONTROL, 0); WREG32(DACB_AUTODETECT_INT_CONTROL, 0);
tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, 0); WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, 0); WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, 0); WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);
} }
} }
...@@ -2765,6 +2763,7 @@ int r600_irq_process(struct radeon_device *rdev) ...@@ -2765,6 +2763,7 @@ int r600_irq_process(struct radeon_device *rdev)
case 0: /* D1 vblank */ case 0: /* D1 vblank */
if (disp_int & LB_D1_VBLANK_INTERRUPT) { if (disp_int & LB_D1_VBLANK_INTERRUPT) {
drm_handle_vblank(rdev->ddev, 0); drm_handle_vblank(rdev->ddev, 0);
rdev->pm.vblank_sync = true;
wake_up(&rdev->irq.vblank_queue); wake_up(&rdev->irq.vblank_queue);
disp_int &= ~LB_D1_VBLANK_INTERRUPT; disp_int &= ~LB_D1_VBLANK_INTERRUPT;
DRM_DEBUG("IH: D1 vblank\n"); DRM_DEBUG("IH: D1 vblank\n");
...@@ -2786,6 +2785,7 @@ int r600_irq_process(struct radeon_device *rdev) ...@@ -2786,6 +2785,7 @@ int r600_irq_process(struct radeon_device *rdev)
case 0: /* D2 vblank */ case 0: /* D2 vblank */
if (disp_int & LB_D2_VBLANK_INTERRUPT) { if (disp_int & LB_D2_VBLANK_INTERRUPT) {
drm_handle_vblank(rdev->ddev, 1); drm_handle_vblank(rdev->ddev, 1);
rdev->pm.vblank_sync = true;
wake_up(&rdev->irq.vblank_queue); wake_up(&rdev->irq.vblank_queue);
disp_int &= ~LB_D2_VBLANK_INTERRUPT; disp_int &= ~LB_D2_VBLANK_INTERRUPT;
DRM_DEBUG("IH: D2 vblank\n"); DRM_DEBUG("IH: D2 vblank\n");
...@@ -2834,14 +2834,14 @@ int r600_irq_process(struct radeon_device *rdev) ...@@ -2834,14 +2834,14 @@ int r600_irq_process(struct radeon_device *rdev)
break; break;
case 10: case 10:
if (disp_int_cont2 & DC_HPD5_INTERRUPT) { if (disp_int_cont2 & DC_HPD5_INTERRUPT) {
disp_int_cont &= ~DC_HPD5_INTERRUPT; disp_int_cont2 &= ~DC_HPD5_INTERRUPT;
queue_hotplug = true; queue_hotplug = true;
DRM_DEBUG("IH: HPD5\n"); DRM_DEBUG("IH: HPD5\n");
} }
break; break;
case 12: case 12:
if (disp_int_cont2 & DC_HPD6_INTERRUPT) { if (disp_int_cont2 & DC_HPD6_INTERRUPT) {
disp_int_cont &= ~DC_HPD6_INTERRUPT; disp_int_cont2 &= ~DC_HPD6_INTERRUPT;
queue_hotplug = true; queue_hotplug = true;
DRM_DEBUG("IH: HPD6\n"); DRM_DEBUG("IH: HPD6\n");
} }
......
...@@ -181,41 +181,6 @@ int r600_audio_init(struct radeon_device *rdev) ...@@ -181,41 +181,6 @@ int r600_audio_init(struct radeon_device *rdev)
return 0; return 0;
} }
/*
* determin how the encoders and audio interface is wired together
*/
int r600_audio_tmds_index(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct drm_encoder *other;
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
return 0;
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
/* special case check if an TMDS1 is present */
list_for_each_entry(other, &dev->mode_config.encoder_list, head) {
if (to_radeon_encoder(other)->encoder_id ==
ENCODER_OBJECT_ID_INTERNAL_TMDS1)
return 1;
}
return 0;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
return 1;
default:
DRM_ERROR("Unsupported encoder type 0x%02X\n",
radeon_encoder->encoder_id);
return -1;
}
}
/* /*
* atach the audio codec to the clock source of the encoder * atach the audio codec to the clock source of the encoder
*/ */
...@@ -224,6 +189,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) ...@@ -224,6 +189,7 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
int base_rate = 48000; int base_rate = 48000;
switch (radeon_encoder->encoder_id) { switch (radeon_encoder->encoder_id) {
...@@ -231,32 +197,34 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock) ...@@ -231,32 +197,34 @@ void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
case ENCODER_OBJECT_ID_INTERNAL_LVTM1: case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
WREG32_P(R600_AUDIO_TIMING, 0, ~0x301); WREG32_P(R600_AUDIO_TIMING, 0, ~0x301);
break; break;
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
WREG32_P(R600_AUDIO_TIMING, 0x100, ~0x301); WREG32_P(R600_AUDIO_TIMING, 0x100, ~0x301);
break; break;
default: default:
DRM_ERROR("Unsupported encoder type 0x%02X\n", DRM_ERROR("Unsupported encoder type 0x%02X\n",
radeon_encoder->encoder_id); radeon_encoder->encoder_id);
return; return;
} }
switch (r600_audio_tmds_index(encoder)) { switch (dig->dig_encoder) {
case 0: case 0:
WREG32(R600_AUDIO_PLL1_MUL, base_rate*50); WREG32(R600_AUDIO_PLL1_MUL, base_rate * 50);
WREG32(R600_AUDIO_PLL1_DIV, clock*100); WREG32(R600_AUDIO_PLL1_DIV, clock * 100);
WREG32(R600_AUDIO_CLK_SRCSEL, 0); WREG32(R600_AUDIO_CLK_SRCSEL, 0);
break; break;
case 1: case 1:
WREG32(R600_AUDIO_PLL2_MUL, base_rate*50); WREG32(R600_AUDIO_PLL2_MUL, base_rate * 50);
WREG32(R600_AUDIO_PLL2_DIV, clock*100); WREG32(R600_AUDIO_PLL2_DIV, clock * 100);
WREG32(R600_AUDIO_CLK_SRCSEL, 1); WREG32(R600_AUDIO_CLK_SRCSEL, 1);
break; break;
default:
dev_err(rdev->dev, "Unsupported DIG on encoder 0x%02X\n",
radeon_encoder->encoder_id);
return;
} }
} }
......
/*
* Copyright 2009 Advanced Micro Devices, 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.
*
* Authors:
* Alex Deucher <alexander.deucher@amd.com>
*/
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
/*
* R6xx+ cards need to use the 3D engine to blit data which requires
* quite a bit of hw state setup. Rather than pull the whole 3D driver
* (which normally generates the 3D state) into the DRM, we opt to use
* statically generated state tables. The regsiter state and shaders
* were hand generated to support blitting functionality. See the 3D
* driver or documentation for descriptions of the registers and
* shader instructions.
*/
const u32 r6xx_default_state[] = const u32 r6xx_default_state[] =
{ {
0xc0002400, 0xc0002400,
......
...@@ -1548,10 +1548,13 @@ static void r700_gfx_init(struct drm_device *dev, ...@@ -1548,10 +1548,13 @@ static void r700_gfx_init(struct drm_device *dev,
RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);
RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
RADEON_WRITE(R700_CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable); RADEON_WRITE(R700_CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable);
RADEON_WRITE(R700_CGTS_SYS_TCC_DISABLE, 0); RADEON_WRITE(R700_CGTS_SYS_TCC_DISABLE, 0);
RADEON_WRITE(R700_CGTS_TCC_DISABLE, 0); RADEON_WRITE(R700_CGTS_TCC_DISABLE, 0);
RADEON_WRITE(R700_CGTS_USER_SYS_TCC_DISABLE, 0);
RADEON_WRITE(R700_CGTS_USER_TCC_DISABLE, 0);
num_qd_pipes = num_qd_pipes =
R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK) >> 8); R7XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK) >> 8);
......
...@@ -45,6 +45,7 @@ struct r600_cs_track { ...@@ -45,6 +45,7 @@ struct r600_cs_track {
u32 nbanks; u32 nbanks;
u32 npipes; u32 npipes;
/* value we track */ /* value we track */
u32 sq_config;
u32 nsamples; u32 nsamples;
u32 cb_color_base_last[8]; u32 cb_color_base_last[8];
struct radeon_bo *cb_color_bo[8]; struct radeon_bo *cb_color_bo[8];
...@@ -141,6 +142,8 @@ static void r600_cs_track_init(struct r600_cs_track *track) ...@@ -141,6 +142,8 @@ static void r600_cs_track_init(struct r600_cs_track *track)
{ {
int i; int i;
/* assume DX9 mode */
track->sq_config = DX9_CONSTS;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
track->cb_color_base_last[i] = 0; track->cb_color_base_last[i] = 0;
track->cb_color_size[i] = 0; track->cb_color_size[i] = 0;
...@@ -715,6 +718,9 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx ...@@ -715,6 +718,9 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
tmp =radeon_get_ib_value(p, idx); tmp =radeon_get_ib_value(p, idx);
ib[idx] = 0; ib[idx] = 0;
break; break;
case SQ_CONFIG:
track->sq_config = radeon_get_ib_value(p, idx);
break;
case R_028800_DB_DEPTH_CONTROL: case R_028800_DB_DEPTH_CONTROL:
track->db_depth_control = radeon_get_ib_value(p, idx); track->db_depth_control = radeon_get_ib_value(p, idx);
break; break;
...@@ -869,6 +875,54 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx ...@@ -869,6 +875,54 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx
case SQ_PGM_START_VS: case SQ_PGM_START_VS:
case SQ_PGM_START_GS: case SQ_PGM_START_GS:
case SQ_PGM_START_PS: case SQ_PGM_START_PS:
case SQ_ALU_CONST_CACHE_GS_0:
case SQ_ALU_CONST_CACHE_GS_1:
case SQ_ALU_CONST_CACHE_GS_2:
case SQ_ALU_CONST_CACHE_GS_3:
case SQ_ALU_CONST_CACHE_GS_4:
case SQ_ALU_CONST_CACHE_GS_5:
case SQ_ALU_CONST_CACHE_GS_6:
case SQ_ALU_CONST_CACHE_GS_7:
case SQ_ALU_CONST_CACHE_GS_8:
case SQ_ALU_CONST_CACHE_GS_9:
case SQ_ALU_CONST_CACHE_GS_10:
case SQ_ALU_CONST_CACHE_GS_11:
case SQ_ALU_CONST_CACHE_GS_12:
case SQ_ALU_CONST_CACHE_GS_13:
case SQ_ALU_CONST_CACHE_GS_14:
case SQ_ALU_CONST_CACHE_GS_15:
case SQ_ALU_CONST_CACHE_PS_0:
case SQ_ALU_CONST_CACHE_PS_1:
case SQ_ALU_CONST_CACHE_PS_2:
case SQ_ALU_CONST_CACHE_PS_3:
case SQ_ALU_CONST_CACHE_PS_4:
case SQ_ALU_CONST_CACHE_PS_5:
case SQ_ALU_CONST_CACHE_PS_6:
case SQ_ALU_CONST_CACHE_PS_7:
case SQ_ALU_CONST_CACHE_PS_8:
case SQ_ALU_CONST_CACHE_PS_9:
case SQ_ALU_CONST_CACHE_PS_10:
case SQ_ALU_CONST_CACHE_PS_11:
case SQ_ALU_CONST_CACHE_PS_12:
case SQ_ALU_CONST_CACHE_PS_13:
case SQ_ALU_CONST_CACHE_PS_14:
case SQ_ALU_CONST_CACHE_PS_15:
case SQ_ALU_CONST_CACHE_VS_0:
case SQ_ALU_CONST_CACHE_VS_1:
case SQ_ALU_CONST_CACHE_VS_2:
case SQ_ALU_CONST_CACHE_VS_3:
case SQ_ALU_CONST_CACHE_VS_4:
case SQ_ALU_CONST_CACHE_VS_5:
case SQ_ALU_CONST_CACHE_VS_6:
case SQ_ALU_CONST_CACHE_VS_7:
case SQ_ALU_CONST_CACHE_VS_8:
case SQ_ALU_CONST_CACHE_VS_9:
case SQ_ALU_CONST_CACHE_VS_10:
case SQ_ALU_CONST_CACHE_VS_11:
case SQ_ALU_CONST_CACHE_VS_12:
case SQ_ALU_CONST_CACHE_VS_13:
case SQ_ALU_CONST_CACHE_VS_14:
case SQ_ALU_CONST_CACHE_VS_15:
r = r600_cs_packet_next_reloc(p, &reloc); r = r600_cs_packet_next_reloc(p, &reloc);
if (r) { if (r) {
dev_warn(p->dev, "bad SET_CONTEXT_REG " dev_warn(p->dev, "bad SET_CONTEXT_REG "
...@@ -1226,13 +1280,15 @@ static int r600_packet3_check(struct radeon_cs_parser *p, ...@@ -1226,13 +1280,15 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
} }
break; break;
case PACKET3_SET_ALU_CONST: case PACKET3_SET_ALU_CONST:
start_reg = (idx_value << 2) + PACKET3_SET_ALU_CONST_OFFSET; if (track->sq_config & DX9_CONSTS) {
end_reg = 4 * pkt->count + start_reg - 4; start_reg = (idx_value << 2) + PACKET3_SET_ALU_CONST_OFFSET;
if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) || end_reg = 4 * pkt->count + start_reg - 4;
(start_reg >= PACKET3_SET_ALU_CONST_END) || if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) ||
(end_reg >= PACKET3_SET_ALU_CONST_END)) { (start_reg >= PACKET3_SET_ALU_CONST_END) ||
DRM_ERROR("bad SET_ALU_CONST\n"); (end_reg >= PACKET3_SET_ALU_CONST_END)) {
return -EINVAL; DRM_ERROR("bad SET_ALU_CONST\n");
return -EINVAL;
}
} }
break; break;
case PACKET3_SET_BOOL_CONST: case PACKET3_SET_BOOL_CONST:
......
...@@ -42,13 +42,13 @@ enum r600_hdmi_color_format { ...@@ -42,13 +42,13 @@ enum r600_hdmi_color_format {
*/ */
enum r600_hdmi_iec_status_bits { enum r600_hdmi_iec_status_bits {
AUDIO_STATUS_DIG_ENABLE = 0x01, AUDIO_STATUS_DIG_ENABLE = 0x01,
AUDIO_STATUS_V = 0x02, AUDIO_STATUS_V = 0x02,
AUDIO_STATUS_VCFG = 0x04, AUDIO_STATUS_VCFG = 0x04,
AUDIO_STATUS_EMPHASIS = 0x08, AUDIO_STATUS_EMPHASIS = 0x08,
AUDIO_STATUS_COPYRIGHT = 0x10, AUDIO_STATUS_COPYRIGHT = 0x10,
AUDIO_STATUS_NONAUDIO = 0x20, AUDIO_STATUS_NONAUDIO = 0x20,
AUDIO_STATUS_PROFESSIONAL = 0x40, AUDIO_STATUS_PROFESSIONAL = 0x40,
AUDIO_STATUS_LEVEL = 0x80 AUDIO_STATUS_LEVEL = 0x80
}; };
struct { struct {
...@@ -85,7 +85,7 @@ struct { ...@@ -85,7 +85,7 @@ struct {
static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq) static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq)
{ {
if (*CTS == 0) if (*CTS == 0)
*CTS = clock*N/(128*freq)*1000; *CTS = clock * N / (128 * freq) * 1000;
DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n", DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n",
N, *CTS, freq); N, *CTS, freq);
} }
...@@ -131,11 +131,11 @@ static void r600_hdmi_infoframe_checksum(uint8_t packetType, ...@@ -131,11 +131,11 @@ static void r600_hdmi_infoframe_checksum(uint8_t packetType,
uint8_t length, uint8_t length,
uint8_t *frame) uint8_t *frame)
{ {
int i; int i;
frame[0] = packetType + versionNumber + length; frame[0] = packetType + versionNumber + length;
for (i = 1; i <= length; i++) for (i = 1; i <= length; i++)
frame[0] += frame[i]; frame[0] += frame[i];
frame[0] = 0x100 - frame[0]; frame[0] = 0x100 - frame[0];
} }
/* /*
...@@ -417,90 +417,141 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder, ...@@ -417,90 +417,141 @@ void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000); WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000);
} }
/* static int r600_hdmi_find_free_block(struct drm_device *dev)
* enable/disable the HDMI engine {
*/ struct radeon_device *rdev = dev->dev_private;
void r600_hdmi_enable(struct drm_encoder *encoder, int enable) struct drm_encoder *encoder;
struct radeon_encoder *radeon_encoder;
bool free_blocks[3] = { true, true, true };
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
radeon_encoder = to_radeon_encoder(encoder);
switch (radeon_encoder->hdmi_offset) {
case R600_HDMI_BLOCK1:
free_blocks[0] = false;
break;
case R600_HDMI_BLOCK2:
free_blocks[1] = false;
break;
case R600_HDMI_BLOCK3:
free_blocks[2] = false;
break;
}
}
if (rdev->family == CHIP_RS600 || rdev->family == CHIP_RS690) {
return free_blocks[0] ? R600_HDMI_BLOCK1 : 0;
} else if (rdev->family >= CHIP_R600) {
if (free_blocks[0])
return R600_HDMI_BLOCK1;
else if (free_blocks[1])
return R600_HDMI_BLOCK2;
}
return 0;
}
static void r600_hdmi_assign_block(struct drm_encoder *encoder)
{ {
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset; struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
if (!offset) if (!dig) {
dev_err(rdev->dev, "Enabling HDMI on non-dig encoder\n");
return; return;
}
DRM_DEBUG("%s HDMI interface @ 0x%04X\n", enable ? "Enabling" : "Disabling", offset); if (ASIC_IS_DCE4(rdev)) {
/* TODO */
/* some version of atombios ignore the enable HDMI flag } else if (ASIC_IS_DCE3(rdev)) {
* so enabling/disabling HDMI was moved here for TMDS1+2 */ radeon_encoder->hdmi_offset = dig->dig_encoder ?
switch (radeon_encoder->encoder_id) { R600_HDMI_BLOCK3 : R600_HDMI_BLOCK1;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: if (ASIC_IS_DCE32(rdev))
WREG32_P(AVIVO_TMDSA_CNTL, enable ? 0x4 : 0x0, ~0x4); radeon_encoder->hdmi_config_offset = dig->dig_encoder ?
WREG32(offset+R600_HDMI_ENABLE, enable ? 0x101 : 0x0); R600_HDMI_CONFIG2 : R600_HDMI_CONFIG1;
break; } else if (rdev->family >= CHIP_R600) {
radeon_encoder->hdmi_offset = r600_hdmi_find_free_block(dev);
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
WREG32_P(AVIVO_LVTMA_CNTL, enable ? 0x4 : 0x0, ~0x4);
WREG32(offset+R600_HDMI_ENABLE, enable ? 0x105 : 0x0);
break;
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:
/* This part is doubtfull in my opinion */
WREG32(offset+R600_HDMI_ENABLE, enable ? 0x110 : 0x0);
break;
default:
DRM_ERROR("unknown HDMI output type\n");
break;
} }
} }
/* /*
* determin at which register offset the HDMI encoder is * enable the HDMI engine
*/ */
void r600_hdmi_init(struct drm_encoder *encoder) void r600_hdmi_enable(struct drm_encoder *encoder)
{ {
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
switch (radeon_encoder->encoder_id) { if (!radeon_encoder->hdmi_offset) {
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1: r600_hdmi_assign_block(encoder);
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: if (!radeon_encoder->hdmi_offset) {
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: dev_warn(rdev->dev, "Could not find HDMI block for "
radeon_encoder->hdmi_offset = R600_HDMI_TMDS1; "0x%x encoder\n", radeon_encoder->encoder_id);
break; return;
}
case ENCODER_OBJECT_ID_INTERNAL_LVTM1: }
switch (r600_audio_tmds_index(encoder)) {
case 0: if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) {
radeon_encoder->hdmi_offset = R600_HDMI_TMDS1; WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0x1, ~0x1);
} else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
int offset = radeon_encoder->hdmi_offset;
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
WREG32_P(AVIVO_TMDSA_CNTL, 0x4, ~0x4);
WREG32(offset + R600_HDMI_ENABLE, 0x101);
break; break;
case 1: case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
radeon_encoder->hdmi_offset = R600_HDMI_TMDS2; WREG32_P(AVIVO_LVTMA_CNTL, 0x4, ~0x4);
WREG32(offset + R600_HDMI_ENABLE, 0x105);
break; break;
default: default:
radeon_encoder->hdmi_offset = 0; dev_err(rdev->dev, "Unknown HDMI output type\n");
break; break;
} }
case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: }
radeon_encoder->hdmi_offset = R600_HDMI_TMDS2;
break;
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: DRM_DEBUG("Enabling HDMI interface @ 0x%04X for encoder 0x%x\n",
radeon_encoder->hdmi_offset = R600_HDMI_DIG; radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
break; }
default: /*
radeon_encoder->hdmi_offset = 0; * disable the HDMI engine
break; */
void r600_hdmi_disable(struct drm_encoder *encoder)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
if (!radeon_encoder->hdmi_offset) {
dev_err(rdev->dev, "Disabling not enabled HDMI\n");
return;
} }
DRM_DEBUG("using HDMI engine at offset 0x%04X for encoder 0x%x\n", DRM_DEBUG("Disabling HDMI interface @ 0x%04X for encoder 0x%x\n",
radeon_encoder->hdmi_offset, radeon_encoder->encoder_id); radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);
if (ASIC_IS_DCE32(rdev) && !ASIC_IS_DCE4(rdev)) {
WREG32_P(radeon_encoder->hdmi_config_offset + 0x4, 0, ~0x1);
} else if (rdev->family >= CHIP_R600 && !ASIC_IS_DCE3(rdev)) {
int offset = radeon_encoder->hdmi_offset;
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
WREG32_P(AVIVO_TMDSA_CNTL, 0, ~0x4);
WREG32(offset + R600_HDMI_ENABLE, 0);
break;
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
WREG32_P(AVIVO_LVTMA_CNTL, 0, ~0x4);
WREG32(offset + R600_HDMI_ENABLE, 0);
break;
default:
dev_err(rdev->dev, "Unknown HDMI output type\n");
break;
}
}
/* TODO: make this configureable */ radeon_encoder->hdmi_offset = 0;
radeon_encoder->hdmi_audio_workaround = 0; radeon_encoder->hdmi_config_offset = 0;
} }
...@@ -152,9 +152,9 @@ ...@@ -152,9 +152,9 @@
#define R600_AUDIO_STATUS_BITS 0x73d8 #define R600_AUDIO_STATUS_BITS 0x73d8
/* HDMI base register addresses */ /* HDMI base register addresses */
#define R600_HDMI_TMDS1 0x7400 #define R600_HDMI_BLOCK1 0x7400
#define R600_HDMI_TMDS2 0x7700 #define R600_HDMI_BLOCK2 0x7700
#define R600_HDMI_DIG 0x7800 #define R600_HDMI_BLOCK3 0x7800
/* HDMI registers */ /* HDMI registers */
#define R600_HDMI_ENABLE 0x00 #define R600_HDMI_ENABLE 0x00
...@@ -185,4 +185,8 @@ ...@@ -185,4 +185,8 @@
#define R600_HDMI_AUDIO_DEBUG_2 0xe8 #define R600_HDMI_AUDIO_DEBUG_2 0xe8
#define R600_HDMI_AUDIO_DEBUG_3 0xec #define R600_HDMI_AUDIO_DEBUG_3 0xec
/* HDMI additional config base register addresses */
#define R600_HDMI_CONFIG1 0x7600
#define R600_HDMI_CONFIG2 0x7a00
#endif #endif
...@@ -77,6 +77,55 @@ ...@@ -77,6 +77,55 @@
#define CB_COLOR0_FRAG 0x280e0 #define CB_COLOR0_FRAG 0x280e0
#define CB_COLOR0_MASK 0x28100 #define CB_COLOR0_MASK 0x28100
#define SQ_ALU_CONST_CACHE_PS_0 0x28940
#define SQ_ALU_CONST_CACHE_PS_1 0x28944
#define SQ_ALU_CONST_CACHE_PS_2 0x28948
#define SQ_ALU_CONST_CACHE_PS_3 0x2894c
#define SQ_ALU_CONST_CACHE_PS_4 0x28950
#define SQ_ALU_CONST_CACHE_PS_5 0x28954
#define SQ_ALU_CONST_CACHE_PS_6 0x28958
#define SQ_ALU_CONST_CACHE_PS_7 0x2895c
#define SQ_ALU_CONST_CACHE_PS_8 0x28960
#define SQ_ALU_CONST_CACHE_PS_9 0x28964
#define SQ_ALU_CONST_CACHE_PS_10 0x28968
#define SQ_ALU_CONST_CACHE_PS_11 0x2896c
#define SQ_ALU_CONST_CACHE_PS_12 0x28970
#define SQ_ALU_CONST_CACHE_PS_13 0x28974
#define SQ_ALU_CONST_CACHE_PS_14 0x28978
#define SQ_ALU_CONST_CACHE_PS_15 0x2897c
#define SQ_ALU_CONST_CACHE_VS_0 0x28980
#define SQ_ALU_CONST_CACHE_VS_1 0x28984
#define SQ_ALU_CONST_CACHE_VS_2 0x28988
#define SQ_ALU_CONST_CACHE_VS_3 0x2898c
#define SQ_ALU_CONST_CACHE_VS_4 0x28990
#define SQ_ALU_CONST_CACHE_VS_5 0x28994
#define SQ_ALU_CONST_CACHE_VS_6 0x28998
#define SQ_ALU_CONST_CACHE_VS_7 0x2899c
#define SQ_ALU_CONST_CACHE_VS_8 0x289a0
#define SQ_ALU_CONST_CACHE_VS_9 0x289a4
#define SQ_ALU_CONST_CACHE_VS_10 0x289a8
#define SQ_ALU_CONST_CACHE_VS_11 0x289ac
#define SQ_ALU_CONST_CACHE_VS_12 0x289b0
#define SQ_ALU_CONST_CACHE_VS_13 0x289b4
#define SQ_ALU_CONST_CACHE_VS_14 0x289b8
#define SQ_ALU_CONST_CACHE_VS_15 0x289bc
#define SQ_ALU_CONST_CACHE_GS_0 0x289c0
#define SQ_ALU_CONST_CACHE_GS_1 0x289c4
#define SQ_ALU_CONST_CACHE_GS_2 0x289c8
#define SQ_ALU_CONST_CACHE_GS_3 0x289cc
#define SQ_ALU_CONST_CACHE_GS_4 0x289d0
#define SQ_ALU_CONST_CACHE_GS_5 0x289d4
#define SQ_ALU_CONST_CACHE_GS_6 0x289d8
#define SQ_ALU_CONST_CACHE_GS_7 0x289dc
#define SQ_ALU_CONST_CACHE_GS_8 0x289e0
#define SQ_ALU_CONST_CACHE_GS_9 0x289e4
#define SQ_ALU_CONST_CACHE_GS_10 0x289e8
#define SQ_ALU_CONST_CACHE_GS_11 0x289ec
#define SQ_ALU_CONST_CACHE_GS_12 0x289f0
#define SQ_ALU_CONST_CACHE_GS_13 0x289f4
#define SQ_ALU_CONST_CACHE_GS_14 0x289f8
#define SQ_ALU_CONST_CACHE_GS_15 0x289fc
#define CONFIG_MEMSIZE 0x5428 #define CONFIG_MEMSIZE 0x5428
#define CONFIG_CNTL 0x5424 #define CONFIG_CNTL 0x5424
#define CP_STAT 0x8680 #define CP_STAT 0x8680
......
...@@ -91,6 +91,8 @@ extern int radeon_tv; ...@@ -91,6 +91,8 @@ extern int radeon_tv;
extern int radeon_new_pll; extern int radeon_new_pll;
extern int radeon_dynpm; extern int radeon_dynpm;
extern int radeon_audio; extern int radeon_audio;
extern int radeon_disp_priority;
extern int radeon_hw_i2c;
/* /*
* Copy from radeon_drv.h so we don't have to include both and have conflicting * Copy from radeon_drv.h so we don't have to include both and have conflicting
...@@ -168,6 +170,7 @@ struct radeon_clock { ...@@ -168,6 +170,7 @@ struct radeon_clock {
* Power management * Power management
*/ */
int radeon_pm_init(struct radeon_device *rdev); int radeon_pm_init(struct radeon_device *rdev);
void radeon_pm_fini(struct radeon_device *rdev);
void radeon_pm_compute_clocks(struct radeon_device *rdev); void radeon_pm_compute_clocks(struct radeon_device *rdev);
void radeon_combios_get_power_modes(struct radeon_device *rdev); void radeon_combios_get_power_modes(struct radeon_device *rdev);
void radeon_atombios_get_power_modes(struct radeon_device *rdev); void radeon_atombios_get_power_modes(struct radeon_device *rdev);
...@@ -687,6 +690,7 @@ struct radeon_pm { ...@@ -687,6 +690,7 @@ struct radeon_pm {
bool downclocked; bool downclocked;
int active_crtcs; int active_crtcs;
int req_vblank; int req_vblank;
bool vblank_sync;
fixed20_12 max_bandwidth; fixed20_12 max_bandwidth;
fixed20_12 igp_sideport_mclk; fixed20_12 igp_sideport_mclk;
fixed20_12 igp_system_mclk; fixed20_12 igp_system_mclk;
...@@ -697,6 +701,7 @@ struct radeon_pm { ...@@ -697,6 +701,7 @@ struct radeon_pm {
fixed20_12 ht_bandwidth; fixed20_12 ht_bandwidth;
fixed20_12 core_bandwidth; fixed20_12 core_bandwidth;
fixed20_12 sclk; fixed20_12 sclk;
fixed20_12 mclk;
fixed20_12 needed_bandwidth; fixed20_12 needed_bandwidth;
/* XXX: use a define for num power modes */ /* XXX: use a define for num power modes */
struct radeon_power_state power_state[8]; struct radeon_power_state power_state[8];
...@@ -707,6 +712,7 @@ struct radeon_pm { ...@@ -707,6 +712,7 @@ struct radeon_pm {
struct radeon_power_state *requested_power_state; struct radeon_power_state *requested_power_state;
struct radeon_pm_clock_info *requested_clock_mode; struct radeon_pm_clock_info *requested_clock_mode;
struct radeon_power_state *default_power_state; struct radeon_power_state *default_power_state;
struct radeon_i2c_chan *i2c_bus;
}; };
...@@ -729,8 +735,6 @@ int radeon_debugfs_add_files(struct radeon_device *rdev, ...@@ -729,8 +735,6 @@ int radeon_debugfs_add_files(struct radeon_device *rdev,
struct drm_info_list *files, struct drm_info_list *files,
unsigned nfiles); unsigned nfiles);
int radeon_debugfs_fence_init(struct radeon_device *rdev); int radeon_debugfs_fence_init(struct radeon_device *rdev);
int r100_debugfs_rbbm_init(struct radeon_device *rdev);
int r100_debugfs_cp_init(struct radeon_device *rdev);
/* /*
...@@ -782,7 +786,7 @@ struct radeon_asic { ...@@ -782,7 +786,7 @@ struct radeon_asic {
int (*set_surface_reg)(struct radeon_device *rdev, int reg, int (*set_surface_reg)(struct radeon_device *rdev, int reg,
uint32_t tiling_flags, uint32_t pitch, uint32_t tiling_flags, uint32_t pitch,
uint32_t offset, uint32_t obj_size); uint32_t offset, uint32_t obj_size);
int (*clear_surface_reg)(struct radeon_device *rdev, int reg); void (*clear_surface_reg)(struct radeon_device *rdev, int reg);
void (*bandwidth_update)(struct radeon_device *rdev); void (*bandwidth_update)(struct radeon_device *rdev);
void (*hpd_init)(struct radeon_device *rdev); void (*hpd_init)(struct radeon_device *rdev);
void (*hpd_fini)(struct radeon_device *rdev); void (*hpd_fini)(struct radeon_device *rdev);
...@@ -862,6 +866,12 @@ union radeon_asic_config { ...@@ -862,6 +866,12 @@ union radeon_asic_config {
struct rv770_asic rv770; struct rv770_asic rv770;
}; };
/*
* asic initizalization from radeon_asic.c
*/
void radeon_agp_disable(struct radeon_device *rdev);
int radeon_asic_init(struct radeon_device *rdev);
/* /*
* IOCTL. * IOCTL.
...@@ -1172,6 +1182,8 @@ extern void radeon_gart_restore(struct radeon_device *rdev); ...@@ -1172,6 +1182,8 @@ extern void radeon_gart_restore(struct radeon_device *rdev);
extern int radeon_modeset_init(struct radeon_device *rdev); extern int radeon_modeset_init(struct radeon_device *rdev);
extern void radeon_modeset_fini(struct radeon_device *rdev); extern void radeon_modeset_fini(struct radeon_device *rdev);
extern bool radeon_card_posted(struct radeon_device *rdev); extern bool radeon_card_posted(struct radeon_device *rdev);
extern void radeon_update_bandwidth_info(struct radeon_device *rdev);
extern void radeon_update_display_priority(struct radeon_device *rdev);
extern bool radeon_boot_test_post_card(struct radeon_device *rdev); extern bool radeon_boot_test_post_card(struct radeon_device *rdev);
extern int radeon_clocks_init(struct radeon_device *rdev); extern int radeon_clocks_init(struct radeon_device *rdev);
extern void radeon_clocks_fini(struct radeon_device *rdev); extern void radeon_clocks_fini(struct radeon_device *rdev);
...@@ -1188,51 +1200,6 @@ extern int radeon_resume_kms(struct drm_device *dev); ...@@ -1188,51 +1200,6 @@ extern int radeon_resume_kms(struct drm_device *dev);
extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state); extern int radeon_suspend_kms(struct drm_device *dev, pm_message_t state);
/* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */ /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
struct r100_mc_save {
u32 GENMO_WT;
u32 CRTC_EXT_CNTL;
u32 CRTC_GEN_CNTL;
u32 CRTC2_GEN_CNTL;
u32 CUR_OFFSET;
u32 CUR2_OFFSET;
};
extern void r100_cp_disable(struct radeon_device *rdev);
extern int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
extern void r100_cp_fini(struct radeon_device *rdev);
extern void r100_pci_gart_tlb_flush(struct radeon_device *rdev);
extern int r100_pci_gart_init(struct radeon_device *rdev);
extern void r100_pci_gart_fini(struct radeon_device *rdev);
extern int r100_pci_gart_enable(struct radeon_device *rdev);
extern void r100_pci_gart_disable(struct radeon_device *rdev);
extern int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr);
extern int r100_debugfs_mc_info_init(struct radeon_device *rdev);
extern int r100_gui_wait_for_idle(struct radeon_device *rdev);
extern void r100_ib_fini(struct radeon_device *rdev);
extern int r100_ib_init(struct radeon_device *rdev);
extern void r100_irq_disable(struct radeon_device *rdev);
extern int r100_irq_set(struct radeon_device *rdev);
extern void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save);
extern void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save);
extern void r100_vram_init_sizes(struct radeon_device *rdev);
extern void r100_wb_disable(struct radeon_device *rdev);
extern void r100_wb_fini(struct radeon_device *rdev);
extern int r100_wb_init(struct radeon_device *rdev);
extern void r100_hdp_reset(struct radeon_device *rdev);
extern int r100_rb2d_reset(struct radeon_device *rdev);
extern int r100_cp_reset(struct radeon_device *rdev);
extern void r100_vga_render_disable(struct radeon_device *rdev);
extern int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt,
struct radeon_bo *robj);
extern int r100_cs_parse_packet0(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt,
const unsigned *auth, unsigned n,
radeon_packet0_check_t check);
extern int r100_cs_packet_parse(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt,
unsigned idx);
extern void r100_enable_bm(struct radeon_device *rdev);
extern void r100_set_common_regs(struct radeon_device *rdev);
/* rv200,rv250,rv280 */ /* rv200,rv250,rv280 */
extern void r200_set_safe_registers(struct radeon_device *rdev); extern void r200_set_safe_registers(struct radeon_device *rdev);
...@@ -1322,7 +1289,8 @@ extern int r600_audio_tmds_index(struct drm_encoder *encoder); ...@@ -1322,7 +1289,8 @@ extern int r600_audio_tmds_index(struct drm_encoder *encoder);
extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock); extern void r600_audio_set_clock(struct drm_encoder *encoder, int clock);
extern void r600_audio_fini(struct radeon_device *rdev); extern void r600_audio_fini(struct radeon_device *rdev);
extern void r600_hdmi_init(struct drm_encoder *encoder); extern void r600_hdmi_init(struct drm_encoder *encoder);
extern void r600_hdmi_enable(struct drm_encoder *encoder, int enable); extern void r600_hdmi_enable(struct drm_encoder *encoder);
extern void r600_hdmi_disable(struct drm_encoder *encoder);
extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode); extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode);
extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder);
extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder, extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
......
此差异已折叠。
...@@ -531,10 +531,7 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde ...@@ -531,10 +531,7 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde
case CHIP_RS300: case CHIP_RS300:
switch (ddc_line) { switch (ddc_line) {
case RADEON_GPIO_DVI_DDC: case RADEON_GPIO_DVI_DDC:
/* in theory this should be hw capable, i2c.hw_capable = true;
* but it doesn't seem to work
*/
i2c.hw_capable = false;
break; break;
default: default:
i2c.hw_capable = false; i2c.hw_capable = false;
...@@ -633,6 +630,8 @@ bool radeon_combios_get_clock_info(struct drm_device *dev) ...@@ -633,6 +630,8 @@ bool radeon_combios_get_clock_info(struct drm_device *dev)
p1pll->reference_div = RBIOS16(pll_info + 0x10); p1pll->reference_div = RBIOS16(pll_info + 0x10);
p1pll->pll_out_min = RBIOS32(pll_info + 0x12); p1pll->pll_out_min = RBIOS32(pll_info + 0x12);
p1pll->pll_out_max = RBIOS32(pll_info + 0x16); p1pll->pll_out_max = RBIOS32(pll_info + 0x16);
p1pll->lcd_pll_out_min = p1pll->pll_out_min;
p1pll->lcd_pll_out_max = p1pll->pll_out_max;
if (rev > 9) { if (rev > 9) {
p1pll->pll_in_min = RBIOS32(pll_info + 0x36); p1pll->pll_in_min = RBIOS32(pll_info + 0x36);
......
...@@ -940,7 +940,7 @@ static void radeon_dp_connector_destroy(struct drm_connector *connector) ...@@ -940,7 +940,7 @@ static void radeon_dp_connector_destroy(struct drm_connector *connector)
if (radeon_connector->edid) if (radeon_connector->edid)
kfree(radeon_connector->edid); kfree(radeon_connector->edid);
if (radeon_dig_connector->dp_i2c_bus) if (radeon_dig_connector->dp_i2c_bus)
radeon_i2c_destroy_dp(radeon_dig_connector->dp_i2c_bus); radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus);
kfree(radeon_connector->con_priv); kfree(radeon_connector->con_priv);
drm_sysfs_connector_remove(connector); drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector); drm_connector_cleanup(connector);
......
...@@ -193,9 +193,11 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) ...@@ -193,9 +193,11 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)
radeon_bo_list_fence(&parser->validated, parser->ib->fence); radeon_bo_list_fence(&parser->validated, parser->ib->fence);
} }
radeon_bo_list_unreserve(&parser->validated); radeon_bo_list_unreserve(&parser->validated);
for (i = 0; i < parser->nrelocs; i++) { if (parser->relocs != NULL) {
if (parser->relocs[i].gobj) for (i = 0; i < parser->nrelocs; i++) {
drm_gem_object_unreference_unlocked(parser->relocs[i].gobj); if (parser->relocs[i].gobj)
drm_gem_object_unreference_unlocked(parser->relocs[i].gobj);
}
} }
kfree(parser->track); kfree(parser->track);
kfree(parser->relocs); kfree(parser->relocs);
...@@ -243,7 +245,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) ...@@ -243,7 +245,8 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
} }
r = radeon_cs_parser_relocs(&parser); r = radeon_cs_parser_relocs(&parser);
if (r) { if (r) {
DRM_ERROR("Failed to parse relocation !\n"); if (r != -ERESTARTSYS)
DRM_ERROR("Failed to parse relocation %d!\n", r);
radeon_cs_parser_fini(&parser, r); radeon_cs_parser_fini(&parser, r);
mutex_unlock(&rdev->cs_mutex); mutex_unlock(&rdev->cs_mutex);
return r; return r;
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include <linux/vga_switcheroo.h> #include <linux/vga_switcheroo.h>
#include "radeon_reg.h" #include "radeon_reg.h"
#include "radeon.h" #include "radeon.h"
#include "radeon_asic.h"
#include "atom.h" #include "atom.h"
/* /*
...@@ -242,6 +241,36 @@ bool radeon_card_posted(struct radeon_device *rdev) ...@@ -242,6 +241,36 @@ bool radeon_card_posted(struct radeon_device *rdev)
} }
void radeon_update_bandwidth_info(struct radeon_device *rdev)
{
fixed20_12 a;
u32 sclk, mclk;
if (rdev->flags & RADEON_IS_IGP) {
sclk = radeon_get_engine_clock(rdev);
mclk = rdev->clock.default_mclk;
a.full = rfixed_const(100);
rdev->pm.sclk.full = rfixed_const(sclk);
rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
rdev->pm.mclk.full = rfixed_const(mclk);
rdev->pm.mclk.full = rfixed_div(rdev->pm.mclk, a);
a.full = rfixed_const(16);
/* core_bandwidth = sclk(Mhz) * 16 */
rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a);
} else {
sclk = radeon_get_engine_clock(rdev);
mclk = radeon_get_memory_clock(rdev);
a.full = rfixed_const(100);
rdev->pm.sclk.full = rfixed_const(sclk);
rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
rdev->pm.mclk.full = rfixed_const(mclk);
rdev->pm.mclk.full = rfixed_div(rdev->pm.mclk, a);
}
}
bool radeon_boot_test_post_card(struct radeon_device *rdev) bool radeon_boot_test_post_card(struct radeon_device *rdev)
{ {
if (radeon_card_posted(rdev)) if (radeon_card_posted(rdev))
...@@ -288,181 +317,6 @@ void radeon_dummy_page_fini(struct radeon_device *rdev) ...@@ -288,181 +317,6 @@ void radeon_dummy_page_fini(struct radeon_device *rdev)
} }
/*
* Registers accessors functions.
*/
uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg)
{
DRM_ERROR("Invalid callback to read register 0x%04X\n", reg);
BUG_ON(1);
return 0;
}
void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
{
DRM_ERROR("Invalid callback to write register 0x%04X with 0x%08X\n",
reg, v);
BUG_ON(1);
}
void radeon_register_accessor_init(struct radeon_device *rdev)
{
rdev->mc_rreg = &radeon_invalid_rreg;
rdev->mc_wreg = &radeon_invalid_wreg;
rdev->pll_rreg = &radeon_invalid_rreg;
rdev->pll_wreg = &radeon_invalid_wreg;
rdev->pciep_rreg = &radeon_invalid_rreg;
rdev->pciep_wreg = &radeon_invalid_wreg;
/* Don't change order as we are overridding accessor. */
if (rdev->family < CHIP_RV515) {
rdev->pcie_reg_mask = 0xff;
} else {
rdev->pcie_reg_mask = 0x7ff;
}
/* FIXME: not sure here */
if (rdev->family <= CHIP_R580) {
rdev->pll_rreg = &r100_pll_rreg;
rdev->pll_wreg = &r100_pll_wreg;
}
if (rdev->family >= CHIP_R420) {
rdev->mc_rreg = &r420_mc_rreg;
rdev->mc_wreg = &r420_mc_wreg;
}
if (rdev->family >= CHIP_RV515) {
rdev->mc_rreg = &rv515_mc_rreg;
rdev->mc_wreg = &rv515_mc_wreg;
}
if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) {
rdev->mc_rreg = &rs400_mc_rreg;
rdev->mc_wreg = &rs400_mc_wreg;
}
if (rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) {
rdev->mc_rreg = &rs690_mc_rreg;
rdev->mc_wreg = &rs690_mc_wreg;
}
if (rdev->family == CHIP_RS600) {
rdev->mc_rreg = &rs600_mc_rreg;
rdev->mc_wreg = &rs600_mc_wreg;
}
if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_RV740)) {
rdev->pciep_rreg = &r600_pciep_rreg;
rdev->pciep_wreg = &r600_pciep_wreg;
}
}
/*
* ASIC
*/
int radeon_asic_init(struct radeon_device *rdev)
{
radeon_register_accessor_init(rdev);
switch (rdev->family) {
case CHIP_R100:
case CHIP_RV100:
case CHIP_RS100:
case CHIP_RV200:
case CHIP_RS200:
rdev->asic = &r100_asic;
break;
case CHIP_R200:
case CHIP_RV250:
case CHIP_RS300:
case CHIP_RV280:
rdev->asic = &r200_asic;
break;
case CHIP_R300:
case CHIP_R350:
case CHIP_RV350:
case CHIP_RV380:
if (rdev->flags & RADEON_IS_PCIE)
rdev->asic = &r300_asic_pcie;
else
rdev->asic = &r300_asic;
break;
case CHIP_R420:
case CHIP_R423:
case CHIP_RV410:
rdev->asic = &r420_asic;
break;
case CHIP_RS400:
case CHIP_RS480:
rdev->asic = &rs400_asic;
break;
case CHIP_RS600:
rdev->asic = &rs600_asic;
break;
case CHIP_RS690:
case CHIP_RS740:
rdev->asic = &rs690_asic;
break;
case CHIP_RV515:
rdev->asic = &rv515_asic;
break;
case CHIP_R520:
case CHIP_RV530:
case CHIP_RV560:
case CHIP_RV570:
case CHIP_R580:
rdev->asic = &r520_asic;
break;
case CHIP_R600:
case CHIP_RV610:
case CHIP_RV630:
case CHIP_RV620:
case CHIP_RV635:
case CHIP_RV670:
case CHIP_RS780:
case CHIP_RS880:
rdev->asic = &r600_asic;
break;
case CHIP_RV770:
case CHIP_RV730:
case CHIP_RV710:
case CHIP_RV740:
rdev->asic = &rv770_asic;
break;
case CHIP_CEDAR:
case CHIP_REDWOOD:
case CHIP_JUNIPER:
case CHIP_CYPRESS:
case CHIP_HEMLOCK:
rdev->asic = &evergreen_asic;
break;
default:
/* FIXME: not supported yet */
return -EINVAL;
}
if (rdev->flags & RADEON_IS_IGP) {
rdev->asic->get_memory_clock = NULL;
rdev->asic->set_memory_clock = NULL;
}
return 0;
}
/*
* Wrapper around modesetting bits.
*/
int radeon_clocks_init(struct radeon_device *rdev)
{
int r;
r = radeon_static_clocks_init(rdev->ddev);
if (r) {
return r;
}
DRM_INFO("Clocks initialized !\n");
return 0;
}
void radeon_clocks_fini(struct radeon_device *rdev)
{
}
/* ATOM accessor methods */ /* ATOM accessor methods */
static uint32_t cail_pll_read(struct card_info *info, uint32_t reg) static uint32_t cail_pll_read(struct card_info *info, uint32_t reg)
{ {
...@@ -567,29 +421,6 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state) ...@@ -567,29 +421,6 @@ static unsigned int radeon_vga_set_decode(void *cookie, bool state)
return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM; return VGA_RSRC_NORMAL_IO | VGA_RSRC_NORMAL_MEM;
} }
void radeon_agp_disable(struct radeon_device *rdev)
{
rdev->flags &= ~RADEON_IS_AGP;
if (rdev->family >= CHIP_R600) {
DRM_INFO("Forcing AGP to PCIE mode\n");
rdev->flags |= RADEON_IS_PCIE;
} else if (rdev->family >= CHIP_RV515 ||
rdev->family == CHIP_RV380 ||
rdev->family == CHIP_RV410 ||
rdev->family == CHIP_R423) {
DRM_INFO("Forcing AGP to PCIE mode\n");
rdev->flags |= RADEON_IS_PCIE;
rdev->asic->gart_tlb_flush = &rv370_pcie_gart_tlb_flush;
rdev->asic->gart_set_page = &rv370_pcie_gart_set_page;
} else {
DRM_INFO("Forcing AGP to PCI mode\n");
rdev->flags |= RADEON_IS_PCI;
rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush;
rdev->asic->gart_set_page = &r100_pci_gart_set_page;
}
rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
}
void radeon_check_arguments(struct radeon_device *rdev) void radeon_check_arguments(struct radeon_device *rdev)
{ {
/* vramlimit must be a power of two */ /* vramlimit must be a power of two */
...@@ -731,6 +562,14 @@ int radeon_device_init(struct radeon_device *rdev, ...@@ -731,6 +562,14 @@ int radeon_device_init(struct radeon_device *rdev,
return r; return r;
radeon_check_arguments(rdev); radeon_check_arguments(rdev);
/* all of the newer IGP chips have an internal gart
* However some rs4xx report as AGP, so remove that here.
*/
if ((rdev->family >= CHIP_RS400) &&
(rdev->flags & RADEON_IS_IGP)) {
rdev->flags &= ~RADEON_IS_AGP;
}
if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) { if (rdev->flags & RADEON_IS_AGP && radeon_agpmode == -1) {
radeon_agp_disable(rdev); radeon_agp_disable(rdev);
} }
......
...@@ -368,10 +368,9 @@ static bool radeon_setup_enc_conn(struct drm_device *dev) ...@@ -368,10 +368,9 @@ static bool radeon_setup_enc_conn(struct drm_device *dev)
if (rdev->bios) { if (rdev->bios) {
if (rdev->is_atom_bios) { if (rdev->is_atom_bios) {
if (rdev->family >= CHIP_R600) ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);
if (ret == false)
ret = radeon_get_atom_connector_info_from_object_table(dev); ret = radeon_get_atom_connector_info_from_object_table(dev);
else
ret = radeon_get_atom_connector_info_from_supported_devices_table(dev);
} else { } else {
ret = radeon_get_legacy_connector_info_from_bios(dev); ret = radeon_get_legacy_connector_info_from_bios(dev);
if (ret == false) if (ret == false)
...@@ -469,10 +468,19 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll, ...@@ -469,10 +468,19 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll,
uint32_t best_error = 0xffffffff; uint32_t best_error = 0xffffffff;
uint32_t best_vco_diff = 1; uint32_t best_vco_diff = 1;
uint32_t post_div; uint32_t post_div;
u32 pll_out_min, pll_out_max;
DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div); DRM_DEBUG("PLL freq %llu %u %u\n", freq, pll->min_ref_div, pll->max_ref_div);
freq = freq * 1000; freq = freq * 1000;
if (pll->flags & RADEON_PLL_IS_LCD) {
pll_out_min = pll->lcd_pll_out_min;
pll_out_max = pll->lcd_pll_out_max;
} else {
pll_out_min = pll->pll_out_min;
pll_out_max = pll->pll_out_max;
}
if (pll->flags & RADEON_PLL_USE_REF_DIV) if (pll->flags & RADEON_PLL_USE_REF_DIV)
min_ref_div = max_ref_div = pll->reference_div; min_ref_div = max_ref_div = pll->reference_div;
else { else {
...@@ -536,10 +544,10 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll, ...@@ -536,10 +544,10 @@ static void radeon_compute_pll_legacy(struct radeon_pll *pll,
tmp = (uint64_t)pll->reference_freq * feedback_div; tmp = (uint64_t)pll->reference_freq * feedback_div;
vco = radeon_div(tmp, ref_div); vco = radeon_div(tmp, ref_div);
if (vco < pll->pll_out_min) { if (vco < pll_out_min) {
min_feed_div = feedback_div + 1; min_feed_div = feedback_div + 1;
continue; continue;
} else if (vco > pll->pll_out_max) { } else if (vco > pll_out_max) {
max_feed_div = feedback_div; max_feed_div = feedback_div;
continue; continue;
} }
...@@ -675,6 +683,15 @@ calc_fb_ref_div(struct radeon_pll *pll, ...@@ -675,6 +683,15 @@ calc_fb_ref_div(struct radeon_pll *pll,
{ {
fixed20_12 ffreq, max_error, error, pll_out, a; fixed20_12 ffreq, max_error, error, pll_out, a;
u32 vco; u32 vco;
u32 pll_out_min, pll_out_max;
if (pll->flags & RADEON_PLL_IS_LCD) {
pll_out_min = pll->lcd_pll_out_min;
pll_out_max = pll->lcd_pll_out_max;
} else {
pll_out_min = pll->pll_out_min;
pll_out_max = pll->pll_out_max;
}
ffreq.full = rfixed_const(freq); ffreq.full = rfixed_const(freq);
/* max_error = ffreq * 0.0025; */ /* max_error = ffreq * 0.0025; */
...@@ -686,7 +703,7 @@ calc_fb_ref_div(struct radeon_pll *pll, ...@@ -686,7 +703,7 @@ calc_fb_ref_div(struct radeon_pll *pll,
vco = pll->reference_freq * (((*fb_div) * 10) + (*fb_div_frac)); vco = pll->reference_freq * (((*fb_div) * 10) + (*fb_div_frac));
vco = vco / ((*ref_div) * 10); vco = vco / ((*ref_div) * 10);
if ((vco < pll->pll_out_min) || (vco > pll->pll_out_max)) if ((vco < pll_out_min) || (vco > pll_out_max))
continue; continue;
/* pll_out = vco / post_div; */ /* pll_out = vco / post_div; */
...@@ -714,6 +731,15 @@ static void radeon_compute_pll_new(struct radeon_pll *pll, ...@@ -714,6 +731,15 @@ static void radeon_compute_pll_new(struct radeon_pll *pll,
{ {
u32 fb_div = 0, fb_div_frac = 0, post_div = 0, ref_div = 0; u32 fb_div = 0, fb_div_frac = 0, post_div = 0, ref_div = 0;
u32 best_freq = 0, vco_frequency; u32 best_freq = 0, vco_frequency;
u32 pll_out_min, pll_out_max;
if (pll->flags & RADEON_PLL_IS_LCD) {
pll_out_min = pll->lcd_pll_out_min;
pll_out_max = pll->lcd_pll_out_max;
} else {
pll_out_min = pll->pll_out_min;
pll_out_max = pll->pll_out_max;
}
/* freq = freq / 10; */ /* freq = freq / 10; */
do_div(freq, 10); do_div(freq, 10);
...@@ -724,7 +750,7 @@ static void radeon_compute_pll_new(struct radeon_pll *pll, ...@@ -724,7 +750,7 @@ static void radeon_compute_pll_new(struct radeon_pll *pll,
goto done; goto done;
vco_frequency = freq * post_div; vco_frequency = freq * post_div;
if ((vco_frequency < pll->pll_out_min) || (vco_frequency > pll->pll_out_max)) if ((vco_frequency < pll_out_min) || (vco_frequency > pll_out_max))
goto done; goto done;
if (pll->flags & RADEON_PLL_USE_REF_DIV) { if (pll->flags & RADEON_PLL_USE_REF_DIV) {
...@@ -749,7 +775,7 @@ static void radeon_compute_pll_new(struct radeon_pll *pll, ...@@ -749,7 +775,7 @@ static void radeon_compute_pll_new(struct radeon_pll *pll,
continue; continue;
vco_frequency = freq * post_div; vco_frequency = freq * post_div;
if ((vco_frequency < pll->pll_out_min) || (vco_frequency > pll->pll_out_max)) if ((vco_frequency < pll_out_min) || (vco_frequency > pll_out_max))
continue; continue;
if (pll->flags & RADEON_PLL_USE_REF_DIV) { if (pll->flags & RADEON_PLL_USE_REF_DIV) {
ref_div = pll->reference_div; ref_div = pll->reference_div;
...@@ -945,6 +971,23 @@ static int radeon_modeset_create_props(struct radeon_device *rdev) ...@@ -945,6 +971,23 @@ static int radeon_modeset_create_props(struct radeon_device *rdev)
return 0; return 0;
} }
void radeon_update_display_priority(struct radeon_device *rdev)
{
/* adjustment options for the display watermarks */
if ((radeon_disp_priority == 0) || (radeon_disp_priority > 2)) {
/* set display priority to high for r3xx, rv515 chips
* this avoids flickering due to underflow to the
* display controllers during heavy acceleration.
*/
if (ASIC_IS_R300(rdev) || (rdev->family == CHIP_RV515))
rdev->disp_priority = 2;
else
rdev->disp_priority = 0;
} else
rdev->disp_priority = radeon_disp_priority;
}
int radeon_modeset_init(struct radeon_device *rdev) int radeon_modeset_init(struct radeon_device *rdev)
{ {
int i; int i;
...@@ -976,15 +1019,6 @@ int radeon_modeset_init(struct radeon_device *rdev) ...@@ -976,15 +1019,6 @@ int radeon_modeset_init(struct radeon_device *rdev)
radeon_combios_check_hardcoded_edid(rdev); radeon_combios_check_hardcoded_edid(rdev);
} }
if (rdev->flags & RADEON_SINGLE_CRTC)
rdev->num_crtc = 1;
else {
if (ASIC_IS_DCE4(rdev))
rdev->num_crtc = 6;
else
rdev->num_crtc = 2;
}
/* allocate crtcs */ /* allocate crtcs */
for (i = 0; i < rdev->num_crtc; i++) { for (i = 0; i < rdev->num_crtc; i++) {
radeon_crtc_init(rdev->ddev, i); radeon_crtc_init(rdev->ddev, i);
......
...@@ -42,9 +42,10 @@ ...@@ -42,9 +42,10 @@
* KMS wrapper. * KMS wrapper.
* - 2.0.0 - initial interface * - 2.0.0 - initial interface
* - 2.1.0 - add square tiling interface * - 2.1.0 - add square tiling interface
* - 2.2.0 - add r6xx/r7xx const buffer support
*/ */
#define KMS_DRIVER_MAJOR 2 #define KMS_DRIVER_MAJOR 2
#define KMS_DRIVER_MINOR 1 #define KMS_DRIVER_MINOR 2
#define KMS_DRIVER_PATCHLEVEL 0 #define KMS_DRIVER_PATCHLEVEL 0
int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
int radeon_driver_unload_kms(struct drm_device *dev); int radeon_driver_unload_kms(struct drm_device *dev);
...@@ -91,6 +92,8 @@ int radeon_tv = 1; ...@@ -91,6 +92,8 @@ int radeon_tv = 1;
int radeon_new_pll = -1; int radeon_new_pll = -1;
int radeon_dynpm = -1; int radeon_dynpm = -1;
int radeon_audio = 1; int radeon_audio = 1;
int radeon_disp_priority = 0;
int radeon_hw_i2c = 0;
MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers"); MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
module_param_named(no_wb, radeon_no_wb, int, 0444); module_param_named(no_wb, radeon_no_wb, int, 0444);
...@@ -134,6 +137,12 @@ module_param_named(dynpm, radeon_dynpm, int, 0444); ...@@ -134,6 +137,12 @@ module_param_named(dynpm, radeon_dynpm, int, 0444);
MODULE_PARM_DESC(audio, "Audio enable (0 = disable)"); MODULE_PARM_DESC(audio, "Audio enable (0 = disable)");
module_param_named(audio, radeon_audio, int, 0444); module_param_named(audio, radeon_audio, int, 0444);
MODULE_PARM_DESC(disp_priority, "Display Priority (0 = auto, 1 = normal, 2 = high)");
module_param_named(disp_priority, radeon_disp_priority, int, 0444);
MODULE_PARM_DESC(hw_i2c, "hw i2c engine enable (0 = disable)");
module_param_named(hw_i2c, radeon_hw_i2c, int, 0444);
static int radeon_suspend(struct drm_device *dev, pm_message_t state) static int radeon_suspend(struct drm_device *dev, pm_message_t state)
{ {
drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_private_t *dev_priv = dev->dev_private;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -346,6 +346,7 @@ ...@@ -346,6 +346,7 @@
# define RADEON_TVPLL_PWRMGT_OFF (1 << 30) # define RADEON_TVPLL_PWRMGT_OFF (1 << 30)
# define RADEON_TVCLK_TURNOFF (1 << 31) # define RADEON_TVCLK_TURNOFF (1 << 31)
#define RADEON_PLL_PWRMGT_CNTL 0x0015 /* PLL */ #define RADEON_PLL_PWRMGT_CNTL 0x0015 /* PLL */
# define RADEON_PM_MODE_SEL (1 << 13)
# define RADEON_TCL_BYPASS_DISABLE (1 << 20) # define RADEON_TCL_BYPASS_DISABLE (1 << 20)
#define RADEON_CLR_CMP_CLR_3D 0x1a24 #define RADEON_CLR_CMP_CLR_3D 0x1a24
#define RADEON_CLR_CMP_CLR_DST 0x15c8 #define RADEON_CLR_CMP_CLR_DST 0x15c8
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册