Merge branch 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (22 commits) Revert "i915: restore only the mode of this driver on lastclose" Revert "ttm: Utilize the DMA API for pages that have TTM_PAGE_FLAG_DMA32 set." i915: select VIDEO_OUTPUT_CONTROL for ACPI_VIDEO drm/radeon/kms: properly program vddci on evergreen+ drm/radeon/kms: add voltage type to atom set voltage function drm/radeon/kms: fix pcie_p callbacks on btc and cayman drm/radeon/kms: fix suspend on rv530 asics drm/radeon/kms: clean up gart dummy page handling drm/radeon/kms: make radeon i2c put/get bytes less noisy drm/radeon/kms: pll tweaks for rv6xx drm/radeon: Fix KMS legacy backlight support if CONFIG_BACKLIGHT_CLASS_DEVICE=m. radeon: Fix KMS CP writeback on big endian machines. i915: restore only the mode of this driver on lastclose drm/nvc0: improve vm flush function drm/nv50-nvc0: remove some code that doesn't belong here drm/nv50: use "nv86" tlb flush method on everything except 0x50/0xac drm/nouveau: quirk for XFX GT-240X-YA drm/nv50-nvc0: work around an evo channel hang that some people see drm/nouveau: implement init table opcode 0x5c drm/nouveau: fix oops on unload with disabled LVDS panel ...
This commit is contained in:
commit
1f4f8eeaec
@ -96,6 +96,7 @@ config DRM_I915
|
||||
# i915 depends on ACPI_VIDEO when ACPI is enabled
|
||||
# but for select to work, need to select ACPI_VIDEO's dependencies, ick
|
||||
select BACKLIGHT_CLASS_DEVICE if ACPI
|
||||
select VIDEO_OUTPUT_CONTROL if ACPI
|
||||
select INPUT if ACPI
|
||||
select ACPI_VIDEO if ACPI
|
||||
select ACPI_BUTTON if ACPI
|
||||
|
@ -269,7 +269,7 @@ struct init_tbl_entry {
|
||||
int (*handler)(struct nvbios *, uint16_t, struct init_exec *);
|
||||
};
|
||||
|
||||
static int parse_init_table(struct nvbios *, unsigned int, struct init_exec *);
|
||||
static int parse_init_table(struct nvbios *, uint16_t, struct init_exec *);
|
||||
|
||||
#define MACRO_INDEX_SIZE 2
|
||||
#define MACRO_SIZE 8
|
||||
@ -2010,6 +2010,27 @@ init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
|
||||
return 3;
|
||||
}
|
||||
|
||||
static int
|
||||
init_jump(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
|
||||
{
|
||||
/*
|
||||
* INIT_JUMP opcode: 0x5C ('\')
|
||||
*
|
||||
* offset (8 bit): opcode
|
||||
* offset + 1 (16 bit): offset (in bios)
|
||||
*
|
||||
* Continue execution of init table from 'offset'
|
||||
*/
|
||||
|
||||
uint16_t jmp_offset = ROM16(bios->data[offset + 1]);
|
||||
|
||||
if (!iexec->execute)
|
||||
return 3;
|
||||
|
||||
BIOSLOG(bios, "0x%04X: Jump to 0x%04X\n", offset, jmp_offset);
|
||||
return jmp_offset - offset;
|
||||
}
|
||||
|
||||
static int
|
||||
init_i2c_if(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
|
||||
{
|
||||
@ -3659,6 +3680,7 @@ static struct init_tbl_entry itbl_entry[] = {
|
||||
{ "INIT_ZM_REG_SEQUENCE" , 0x58, init_zm_reg_sequence },
|
||||
/* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */
|
||||
{ "INIT_SUB_DIRECT" , 0x5B, init_sub_direct },
|
||||
{ "INIT_JUMP" , 0x5C, init_jump },
|
||||
{ "INIT_I2C_IF" , 0x5E, init_i2c_if },
|
||||
{ "INIT_COPY_NV_REG" , 0x5F, init_copy_nv_reg },
|
||||
{ "INIT_ZM_INDEX_IO" , 0x62, init_zm_index_io },
|
||||
@ -3700,8 +3722,7 @@ static struct init_tbl_entry itbl_entry[] = {
|
||||
#define MAX_TABLE_OPS 1000
|
||||
|
||||
static int
|
||||
parse_init_table(struct nvbios *bios, unsigned int offset,
|
||||
struct init_exec *iexec)
|
||||
parse_init_table(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
|
||||
{
|
||||
/*
|
||||
* Parses all commands in an init table.
|
||||
@ -6333,6 +6354,32 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf)
|
||||
}
|
||||
}
|
||||
|
||||
/* XFX GT-240X-YA
|
||||
*
|
||||
* So many things wrong here, replace the entire encoder table..
|
||||
*/
|
||||
if (nv_match_device(dev, 0x0ca3, 0x1682, 0x3003)) {
|
||||
if (idx == 0) {
|
||||
*conn = 0x02001300; /* VGA, connector 1 */
|
||||
*conf = 0x00000028;
|
||||
} else
|
||||
if (idx == 1) {
|
||||
*conn = 0x01010312; /* DVI, connector 0 */
|
||||
*conf = 0x00020030;
|
||||
} else
|
||||
if (idx == 2) {
|
||||
*conn = 0x01010310; /* VGA, connector 0 */
|
||||
*conf = 0x00000028;
|
||||
} else
|
||||
if (idx == 3) {
|
||||
*conn = 0x02022362; /* HDMI, connector 2 */
|
||||
*conf = 0x00020010;
|
||||
} else {
|
||||
*conn = 0x0000000e; /* EOL */
|
||||
*conf = 0x00000000;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1190,7 +1190,7 @@ extern int nv50_graph_load_context(struct nouveau_channel *);
|
||||
extern int nv50_graph_unload_context(struct drm_device *);
|
||||
extern int nv50_grctx_init(struct nouveau_grctx *);
|
||||
extern void nv50_graph_tlb_flush(struct drm_device *dev);
|
||||
extern void nv86_graph_tlb_flush(struct drm_device *dev);
|
||||
extern void nv84_graph_tlb_flush(struct drm_device *dev);
|
||||
extern struct nouveau_enum nv50_data_error_names[];
|
||||
|
||||
/* nvc0_graph.c */
|
||||
|
@ -552,6 +552,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
||||
u8 tRC; /* Byte 9 */
|
||||
u8 tUNK_10, tUNK_11, tUNK_12, tUNK_13, tUNK_14;
|
||||
u8 tUNK_18, tUNK_19, tUNK_20, tUNK_21;
|
||||
u8 magic_number = 0; /* Yeah... sorry*/
|
||||
u8 *mem = NULL, *entry;
|
||||
int i, recordlen, entries;
|
||||
|
||||
@ -596,6 +597,12 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
||||
if (!memtimings->timing)
|
||||
return;
|
||||
|
||||
/* Get "some number" from the timing reg for NV_40
|
||||
* Used in calculations later */
|
||||
if(dev_priv->card_type == NV_40) {
|
||||
magic_number = (nv_rd32(dev,0x100228) & 0x0f000000) >> 24;
|
||||
}
|
||||
|
||||
entry = mem + mem[1];
|
||||
for (i = 0; i < entries; i++, entry += recordlen) {
|
||||
struct nouveau_pm_memtiming *timing = &pm->memtimings.timing[i];
|
||||
@ -635,36 +642,51 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
||||
|
||||
/* XXX: I don't trust the -1's and +1's... they must come
|
||||
* from somewhere! */
|
||||
timing->reg_100224 = ((tUNK_0 + tUNK_19 + 1) << 24 |
|
||||
timing->reg_100224 = (tUNK_0 + tUNK_19 + 1 + magic_number) << 24 |
|
||||
tUNK_18 << 16 |
|
||||
(tUNK_1 + tUNK_19 + 1) << 8 |
|
||||
(tUNK_2 - 1));
|
||||
(tUNK_1 + tUNK_19 + 1 + magic_number) << 8;
|
||||
if(dev_priv->chipset == 0xa8) {
|
||||
timing->reg_100224 |= (tUNK_2 - 1);
|
||||
} else {
|
||||
timing->reg_100224 |= (tUNK_2 + 2 - magic_number);
|
||||
}
|
||||
|
||||
timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10);
|
||||
if(recordlen > 19) {
|
||||
timing->reg_100228 += (tUNK_19 - 1) << 24;
|
||||
}/* I cannot back-up this else-statement right now
|
||||
else {
|
||||
timing->reg_100228 += tUNK_12 << 24;
|
||||
}*/
|
||||
if(dev_priv->chipset >= 0xa3 && dev_priv->chipset < 0xaa) {
|
||||
timing->reg_100228 |= (tUNK_19 - 1) << 24;
|
||||
}
|
||||
|
||||
/* XXX: reg_10022c */
|
||||
timing->reg_10022c = tUNK_2 - 1;
|
||||
if(dev_priv->card_type == NV_40) {
|
||||
/* NV40: don't know what the rest of the regs are..
|
||||
* And don't need to know either */
|
||||
timing->reg_100228 |= 0x20200000 | magic_number << 24;
|
||||
} else if(dev_priv->card_type >= NV_50) {
|
||||
/* XXX: reg_10022c */
|
||||
timing->reg_10022c = tUNK_2 - 1;
|
||||
|
||||
timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 |
|
||||
tUNK_13 << 8 | tUNK_13);
|
||||
timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 |
|
||||
tUNK_13 << 8 | tUNK_13);
|
||||
|
||||
/* XXX: +6? */
|
||||
timing->reg_100234 = (tRAS << 24 | (tUNK_19 + 6) << 8 | tRC);
|
||||
timing->reg_100234 += max(tUNK_10,tUNK_11) << 16;
|
||||
timing->reg_100234 = (tRAS << 24 | tRC);
|
||||
timing->reg_100234 += max(tUNK_10,tUNK_11) << 16;
|
||||
|
||||
/* XXX; reg_100238, reg_10023c
|
||||
* reg: 0x00??????
|
||||
* reg_10023c:
|
||||
* 0 for pre-NV50 cards
|
||||
* 0x????0202 for NV50+ cards (empirical evidence) */
|
||||
if(dev_priv->card_type >= NV_50) {
|
||||
if(dev_priv->chipset < 0xa3) {
|
||||
timing->reg_100234 |= (tUNK_2 + 2) << 8;
|
||||
} else {
|
||||
/* XXX: +6? */
|
||||
timing->reg_100234 |= (tUNK_19 + 6) << 8;
|
||||
}
|
||||
|
||||
/* XXX; reg_100238, reg_10023c
|
||||
* reg_100238: 0x00??????
|
||||
* reg_10023c: 0x!!??0202 for NV50+ cards (empirical evidence) */
|
||||
timing->reg_10023c = 0x202;
|
||||
if(dev_priv->chipset < 0xa3) {
|
||||
timing->reg_10023c |= 0x4000000 | (tUNK_2 - 1) << 16;
|
||||
} else {
|
||||
/* currently unknown
|
||||
* 10023c seen as 06xxxxxx, 0bxxxxxx or 0fxxxxxx */
|
||||
}
|
||||
}
|
||||
|
||||
NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i,
|
||||
@ -675,7 +697,7 @@ nouveau_mem_timing_init(struct drm_device *dev)
|
||||
timing->reg_100238, timing->reg_10023c);
|
||||
}
|
||||
|
||||
memtimings->nr_timing = entries;
|
||||
memtimings->nr_timing = entries;
|
||||
memtimings->supported = true;
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ nouveau_perf_init(struct drm_device *dev)
|
||||
case 0x13:
|
||||
case 0x15:
|
||||
perflvl->fanspeed = entry[55];
|
||||
perflvl->voltage = entry[56];
|
||||
perflvl->voltage = (recordlen > 56) ? entry[56] : 0;
|
||||
perflvl->core = ROM32(entry[1]) * 10;
|
||||
perflvl->memory = ROM32(entry[5]) * 20;
|
||||
break;
|
||||
|
@ -376,15 +376,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
|
||||
engine->graph.destroy_context = nv50_graph_destroy_context;
|
||||
engine->graph.load_context = nv50_graph_load_context;
|
||||
engine->graph.unload_context = nv50_graph_unload_context;
|
||||
if (dev_priv->chipset != 0x86)
|
||||
if (dev_priv->chipset == 0x50 ||
|
||||
dev_priv->chipset == 0xac)
|
||||
engine->graph.tlb_flush = nv50_graph_tlb_flush;
|
||||
else {
|
||||
/* from what i can see nvidia do this on every
|
||||
* pre-NVA3 board except NVAC, but, we've only
|
||||
* ever seen problems on NV86
|
||||
*/
|
||||
engine->graph.tlb_flush = nv86_graph_tlb_flush;
|
||||
}
|
||||
else
|
||||
engine->graph.tlb_flush = nv84_graph_tlb_flush;
|
||||
engine->fifo.channels = 128;
|
||||
engine->fifo.init = nv50_fifo_init;
|
||||
engine->fifo.takedown = nv50_fifo_takedown;
|
||||
|
@ -581,12 +581,13 @@ static void nv04_dfp_restore(struct drm_encoder *encoder)
|
||||
int head = nv_encoder->restore.head;
|
||||
|
||||
if (nv_encoder->dcb->type == OUTPUT_LVDS) {
|
||||
struct drm_display_mode *native_mode = nouveau_encoder_connector_get(nv_encoder)->native_mode;
|
||||
if (native_mode)
|
||||
call_lvds_script(dev, nv_encoder->dcb, head, LVDS_PANEL_ON,
|
||||
native_mode->clock);
|
||||
else
|
||||
NV_ERROR(dev, "Not restoring LVDS without native mode\n");
|
||||
struct nouveau_connector *connector =
|
||||
nouveau_encoder_connector_get(nv_encoder);
|
||||
|
||||
if (connector && connector->native_mode)
|
||||
call_lvds_script(dev, nv_encoder->dcb, head,
|
||||
LVDS_PANEL_ON,
|
||||
connector->native_mode->clock);
|
||||
|
||||
} else if (nv_encoder->dcb->type == OUTPUT_TMDS) {
|
||||
int clock = nouveau_hw_pllvals_to_clk
|
||||
|
@ -469,9 +469,6 @@ nv50_crtc_wait_complete(struct drm_crtc *crtc)
|
||||
|
||||
start = ptimer->read(dev);
|
||||
do {
|
||||
nv_wr32(dev, 0x61002c, 0x370);
|
||||
nv_wr32(dev, 0x000140, 1);
|
||||
|
||||
if (nv_ro32(disp->ntfy, 0x000))
|
||||
return 0;
|
||||
} while (ptimer->read(dev) - start < 2000000000ULL);
|
||||
|
@ -186,6 +186,7 @@ nv50_evo_channel_init(struct nouveau_channel *evo)
|
||||
nv_mask(dev, 0x610028, 0x00000000, 0x00010001 << id);
|
||||
|
||||
evo->dma.max = (4096/4) - 2;
|
||||
evo->dma.max &= ~7;
|
||||
evo->dma.put = 0;
|
||||
evo->dma.cur = evo->dma.put;
|
||||
evo->dma.free = evo->dma.max - evo->dma.cur;
|
||||
|
@ -503,7 +503,7 @@ nv50_graph_tlb_flush(struct drm_device *dev)
|
||||
}
|
||||
|
||||
void
|
||||
nv86_graph_tlb_flush(struct drm_device *dev)
|
||||
nv84_graph_tlb_flush(struct drm_device *dev)
|
||||
{
|
||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||
struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
|
||||
|
@ -104,20 +104,26 @@ nvc0_vm_flush(struct nouveau_vm *vm)
|
||||
struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
|
||||
struct drm_device *dev = vm->dev;
|
||||
struct nouveau_vm_pgd *vpgd;
|
||||
u32 r100c80, engine;
|
||||
u32 engine = (dev_priv->chan_vm == vm) ? 1 : 5;
|
||||
|
||||
pinstmem->flush(vm->dev);
|
||||
|
||||
if (vm == dev_priv->chan_vm)
|
||||
engine = 1;
|
||||
else
|
||||
engine = 5;
|
||||
|
||||
spin_lock(&dev_priv->ramin_lock);
|
||||
list_for_each_entry(vpgd, &vm->pgd_list, head) {
|
||||
r100c80 = nv_rd32(dev, 0x100c80);
|
||||
/* looks like maybe a "free flush slots" counter, the
|
||||
* faster you write to 0x100cbc to more it decreases
|
||||
*/
|
||||
if (!nv_wait_ne(dev, 0x100c80, 0x00ff0000, 0x00000000)) {
|
||||
NV_ERROR(dev, "vm timeout 0: 0x%08x %d\n",
|
||||
nv_rd32(dev, 0x100c80), engine);
|
||||
}
|
||||
nv_wr32(dev, 0x100cb8, vpgd->obj->vinst >> 8);
|
||||
nv_wr32(dev, 0x100cbc, 0x80000000 | engine);
|
||||
if (!nv_wait(dev, 0x100c80, 0xffffffff, r100c80))
|
||||
NV_ERROR(dev, "vm flush timeout eng %d\n", engine);
|
||||
/* wait for flush to be queued? */
|
||||
if (!nv_wait(dev, 0x100c80, 0x00008000, 0x00008000)) {
|
||||
NV_ERROR(dev, "vm timeout 1: 0x%08x %d\n",
|
||||
nv_rd32(dev, 0x100c80), engine);
|
||||
}
|
||||
}
|
||||
spin_unlock(&dev_priv->ramin_lock);
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "atom.h"
|
||||
#include "atom-names.h"
|
||||
#include "atom-bits.h"
|
||||
#include "radeon.h"
|
||||
|
||||
#define ATOM_COND_ABOVE 0
|
||||
#define ATOM_COND_ABOVEOREQUAL 1
|
||||
@ -101,7 +102,9 @@ static void debug_print_spaces(int n)
|
||||
static uint32_t atom_iio_execute(struct atom_context *ctx, int base,
|
||||
uint32_t index, uint32_t data)
|
||||
{
|
||||
struct radeon_device *rdev = ctx->card->dev->dev_private;
|
||||
uint32_t temp = 0xCDCDCDCD;
|
||||
|
||||
while (1)
|
||||
switch (CU8(base)) {
|
||||
case ATOM_IIO_NOP:
|
||||
@ -112,7 +115,8 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base,
|
||||
base += 3;
|
||||
break;
|
||||
case ATOM_IIO_WRITE:
|
||||
(void)ctx->card->ioreg_read(ctx->card, CU16(base + 1));
|
||||
if (rdev->family == CHIP_RV515)
|
||||
(void)ctx->card->ioreg_read(ctx->card, CU16(base + 1));
|
||||
ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp);
|
||||
base += 3;
|
||||
break;
|
||||
|
@ -531,6 +531,12 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
|
||||
pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV;
|
||||
else
|
||||
pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV;
|
||||
|
||||
if ((rdev->family == CHIP_R600) ||
|
||||
(rdev->family == CHIP_RV610) ||
|
||||
(rdev->family == CHIP_RV630) ||
|
||||
(rdev->family == CHIP_RV670))
|
||||
pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP;
|
||||
} else {
|
||||
pll->flags |= RADEON_PLL_LEGACY;
|
||||
|
||||
|
@ -120,11 +120,16 @@ void evergreen_pm_misc(struct radeon_device *rdev)
|
||||
struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx];
|
||||
struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
|
||||
|
||||
if ((voltage->type == VOLTAGE_SW) && voltage->voltage) {
|
||||
if (voltage->voltage != rdev->pm.current_vddc) {
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage);
|
||||
if (voltage->type == VOLTAGE_SW) {
|
||||
if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) {
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
rdev->pm.current_vddc = voltage->voltage;
|
||||
DRM_DEBUG("Setting: v: %d\n", voltage->voltage);
|
||||
DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage);
|
||||
}
|
||||
if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) {
|
||||
radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI);
|
||||
rdev->pm.current_vddci = voltage->vddci;
|
||||
DRM_DEBUG("Setting: vddci: %d\n", voltage->vddci);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3036,9 +3041,6 @@ int evergreen_init(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = radeon_dummy_page_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
/* This don't do much */
|
||||
r = radeon_gem_init(rdev);
|
||||
if (r)
|
||||
@ -3150,7 +3152,6 @@ void evergreen_fini(struct radeon_device *rdev)
|
||||
radeon_atombios_fini(rdev);
|
||||
kfree(rdev->bios);
|
||||
rdev->bios = NULL;
|
||||
radeon_dummy_page_fini(rdev);
|
||||
}
|
||||
|
||||
static void evergreen_pcie_gen2_enable(struct radeon_device *rdev)
|
||||
|
@ -587,7 +587,7 @@ void r600_pm_misc(struct radeon_device *rdev)
|
||||
|
||||
if ((voltage->type == VOLTAGE_SW) && voltage->voltage) {
|
||||
if (voltage->voltage != rdev->pm.current_vddc) {
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage);
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
rdev->pm.current_vddc = voltage->voltage;
|
||||
DRM_DEBUG_DRIVER("Setting: v: %d\n", voltage->voltage);
|
||||
}
|
||||
@ -2509,9 +2509,6 @@ int r600_init(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = radeon_dummy_page_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
if (r600_debugfs_mc_info_init(rdev)) {
|
||||
DRM_ERROR("Failed to register debugfs file for mc !\n");
|
||||
}
|
||||
@ -2625,7 +2622,6 @@ void r600_fini(struct radeon_device *rdev)
|
||||
radeon_atombios_fini(rdev);
|
||||
kfree(rdev->bios);
|
||||
rdev->bios = NULL;
|
||||
radeon_dummy_page_fini(rdev);
|
||||
}
|
||||
|
||||
|
||||
|
@ -177,7 +177,7 @@ void radeon_pm_suspend(struct radeon_device *rdev);
|
||||
void radeon_pm_resume(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_atom_set_voltage(struct radeon_device *rdev, u16 level);
|
||||
void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type);
|
||||
void rs690_pm_info(struct radeon_device *rdev);
|
||||
extern int rv6xx_get_temp(struct radeon_device *rdev);
|
||||
extern int rv770_get_temp(struct radeon_device *rdev);
|
||||
@ -767,7 +767,9 @@ struct radeon_voltage {
|
||||
u8 vddci_id; /* index into vddci voltage table */
|
||||
bool vddci_enabled;
|
||||
/* r6xx+ sw */
|
||||
u32 voltage;
|
||||
u16 voltage;
|
||||
/* evergreen+ vddci */
|
||||
u16 vddci;
|
||||
};
|
||||
|
||||
/* clock mode flags */
|
||||
@ -835,10 +837,12 @@ struct radeon_pm {
|
||||
int default_power_state_index;
|
||||
u32 current_sclk;
|
||||
u32 current_mclk;
|
||||
u32 current_vddc;
|
||||
u16 current_vddc;
|
||||
u16 current_vddci;
|
||||
u32 default_sclk;
|
||||
u32 default_mclk;
|
||||
u32 default_vddc;
|
||||
u16 default_vddc;
|
||||
u16 default_vddci;
|
||||
struct radeon_i2c_chan *i2c_bus;
|
||||
/* selected pm method */
|
||||
enum radeon_pm_method pm_method;
|
||||
|
@ -94,7 +94,7 @@ static void radeon_register_accessor_init(struct radeon_device *rdev)
|
||||
rdev->mc_rreg = &rs600_mc_rreg;
|
||||
rdev->mc_wreg = &rs600_mc_wreg;
|
||||
}
|
||||
if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_HEMLOCK)) {
|
||||
if (rdev->family >= CHIP_R600) {
|
||||
rdev->pciep_rreg = &r600_pciep_rreg;
|
||||
rdev->pciep_wreg = &r600_pciep_wreg;
|
||||
}
|
||||
|
@ -2176,24 +2176,27 @@ static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r
|
||||
}
|
||||
}
|
||||
|
||||
static u16 radeon_atombios_get_default_vddc(struct radeon_device *rdev)
|
||||
static void radeon_atombios_get_default_voltages(struct radeon_device *rdev,
|
||||
u16 *vddc, u16 *vddci)
|
||||
{
|
||||
struct radeon_mode_info *mode_info = &rdev->mode_info;
|
||||
int index = GetIndexIntoMasterTable(DATA, FirmwareInfo);
|
||||
u8 frev, crev;
|
||||
u16 data_offset;
|
||||
union firmware_info *firmware_info;
|
||||
u16 vddc = 0;
|
||||
|
||||
*vddc = 0;
|
||||
*vddci = 0;
|
||||
|
||||
if (atom_parse_data_header(mode_info->atom_context, index, NULL,
|
||||
&frev, &crev, &data_offset)) {
|
||||
firmware_info =
|
||||
(union firmware_info *)(mode_info->atom_context->bios +
|
||||
data_offset);
|
||||
vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage);
|
||||
*vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage);
|
||||
if ((frev == 2) && (crev >= 2))
|
||||
*vddci = le16_to_cpu(firmware_info->info_22.usBootUpVDDCIVoltage);
|
||||
}
|
||||
|
||||
return vddc;
|
||||
}
|
||||
|
||||
static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev,
|
||||
@ -2203,7 +2206,9 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde
|
||||
int j;
|
||||
u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings);
|
||||
u32 misc2 = le16_to_cpu(non_clock_info->usClassification);
|
||||
u16 vddc = radeon_atombios_get_default_vddc(rdev);
|
||||
u16 vddc, vddci;
|
||||
|
||||
radeon_atombios_get_default_voltages(rdev, &vddc, &vddci);
|
||||
|
||||
rdev->pm.power_state[state_index].misc = misc;
|
||||
rdev->pm.power_state[state_index].misc2 = misc2;
|
||||
@ -2244,6 +2249,7 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde
|
||||
rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk;
|
||||
rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk;
|
||||
rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage;
|
||||
rdev->pm.default_vddci = rdev->pm.power_state[state_index].clock_info[0].voltage.vddci;
|
||||
} else {
|
||||
/* patch the table values with the default slck/mclk from firmware info */
|
||||
for (j = 0; j < mode_index; j++) {
|
||||
@ -2286,6 +2292,8 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev,
|
||||
VOLTAGE_SW;
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage =
|
||||
le16_to_cpu(clock_info->evergreen.usVDDC);
|
||||
rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci =
|
||||
le16_to_cpu(clock_info->evergreen.usVDDCI);
|
||||
} else {
|
||||
sclk = le16_to_cpu(clock_info->r600.usEngineClockLow);
|
||||
sclk |= clock_info->r600.ucEngineClockHigh << 16;
|
||||
@ -2577,25 +2585,25 @@ union set_voltage {
|
||||
struct _SET_VOLTAGE_PARAMETERS_V2 v2;
|
||||
};
|
||||
|
||||
void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level)
|
||||
void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type)
|
||||
{
|
||||
union set_voltage args;
|
||||
int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
|
||||
u8 frev, crev, volt_index = level;
|
||||
u8 frev, crev, volt_index = voltage_level;
|
||||
|
||||
if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
|
||||
return;
|
||||
|
||||
switch (crev) {
|
||||
case 1:
|
||||
args.v1.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC;
|
||||
args.v1.ucVoltageType = voltage_type;
|
||||
args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE;
|
||||
args.v1.ucVoltageIndex = volt_index;
|
||||
break;
|
||||
case 2:
|
||||
args.v2.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC;
|
||||
args.v2.ucVoltageType = voltage_type;
|
||||
args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE;
|
||||
args.v2.usVoltageLevel = cpu_to_le16(level);
|
||||
args.v2.usVoltageLevel = cpu_to_le16(voltage_level);
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
|
||||
|
@ -79,7 +79,7 @@ static bool radeon_fence_poll_locked(struct radeon_device *rdev)
|
||||
scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
|
||||
else
|
||||
scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
|
||||
seq = rdev->wb.wb[scratch_index/4];
|
||||
seq = le32_to_cpu(rdev->wb.wb[scratch_index/4]);
|
||||
} else
|
||||
seq = RREG32(rdev->fence_drv.scratch_reg);
|
||||
if (seq != rdev->fence_drv.last_seq) {
|
||||
|
@ -285,4 +285,6 @@ void radeon_gart_fini(struct radeon_device *rdev)
|
||||
rdev->gart.pages = NULL;
|
||||
rdev->gart.pages_addr = NULL;
|
||||
rdev->gart.ttm_alloced = NULL;
|
||||
|
||||
radeon_dummy_page_fini(rdev);
|
||||
}
|
||||
|
@ -1062,7 +1062,7 @@ void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus,
|
||||
*val = in_buf[0];
|
||||
DRM_DEBUG("val = 0x%02x\n", *val);
|
||||
} else {
|
||||
DRM_ERROR("i2c 0x%02x 0x%02x read failed\n",
|
||||
DRM_DEBUG("i2c 0x%02x 0x%02x read failed\n",
|
||||
addr, *val);
|
||||
}
|
||||
}
|
||||
@ -1084,7 +1084,7 @@ void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c_bus,
|
||||
out_buf[1] = val;
|
||||
|
||||
if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1)
|
||||
DRM_ERROR("i2c 0x%02x 0x%02x write failed\n",
|
||||
DRM_DEBUG("i2c 0x%02x 0x%02x write failed\n",
|
||||
addr, val);
|
||||
}
|
||||
|
||||
|
@ -269,7 +269,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = {
|
||||
.disable = radeon_legacy_encoder_disable,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
|
||||
#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE)
|
||||
|
||||
#define MAX_RADEON_LEVEL 0xFF
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "drmP.h"
|
||||
#include "radeon.h"
|
||||
#include "avivod.h"
|
||||
#include "atom.h"
|
||||
#ifdef CONFIG_ACPI
|
||||
#include <linux/acpi.h>
|
||||
#endif
|
||||
@ -535,7 +536,11 @@ void radeon_pm_resume(struct radeon_device *rdev)
|
||||
/* set up the default clocks if the MC ucode is loaded */
|
||||
if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) {
|
||||
if (rdev->pm.default_vddc)
|
||||
radeon_atom_set_voltage(rdev, rdev->pm.default_vddc);
|
||||
radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
|
||||
SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
if (rdev->pm.default_vddci)
|
||||
radeon_atom_set_voltage(rdev, rdev->pm.default_vddci,
|
||||
SET_VOLTAGE_TYPE_ASIC_VDDCI);
|
||||
if (rdev->pm.default_sclk)
|
||||
radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
|
||||
if (rdev->pm.default_mclk)
|
||||
@ -548,6 +553,7 @@ void radeon_pm_resume(struct radeon_device *rdev)
|
||||
rdev->pm.current_sclk = rdev->pm.default_sclk;
|
||||
rdev->pm.current_mclk = rdev->pm.default_mclk;
|
||||
rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage;
|
||||
rdev->pm.current_vddci = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.vddci;
|
||||
if (rdev->pm.pm_method == PM_METHOD_DYNPM
|
||||
&& rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) {
|
||||
rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE;
|
||||
@ -585,7 +591,8 @@ int radeon_pm_init(struct radeon_device *rdev)
|
||||
/* set up the default clocks if the MC ucode is loaded */
|
||||
if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) {
|
||||
if (rdev->pm.default_vddc)
|
||||
radeon_atom_set_voltage(rdev, rdev->pm.default_vddc);
|
||||
radeon_atom_set_voltage(rdev, rdev->pm.default_vddc,
|
||||
SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
if (rdev->pm.default_sclk)
|
||||
radeon_set_engine_clock(rdev, rdev->pm.default_sclk);
|
||||
if (rdev->pm.default_mclk)
|
||||
|
@ -248,7 +248,7 @@ void radeon_ib_pool_fini(struct radeon_device *rdev)
|
||||
void radeon_ring_free_size(struct radeon_device *rdev)
|
||||
{
|
||||
if (rdev->wb.enabled)
|
||||
rdev->cp.rptr = rdev->wb.wb[RADEON_WB_CP_RPTR_OFFSET/4];
|
||||
rdev->cp.rptr = le32_to_cpu(rdev->wb.wb[RADEON_WB_CP_RPTR_OFFSET/4]);
|
||||
else {
|
||||
if (rdev->family >= CHIP_R600)
|
||||
rdev->cp.rptr = RREG32(R600_CP_RB_RPTR);
|
||||
|
@ -114,7 +114,7 @@ void rs600_pm_misc(struct radeon_device *rdev)
|
||||
udelay(voltage->delay);
|
||||
}
|
||||
} else if (voltage->type == VOLTAGE_VDDC)
|
||||
radeon_atom_set_voltage(rdev, voltage->vddc_id);
|
||||
radeon_atom_set_voltage(rdev, voltage->vddc_id, SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
|
||||
dyn_pwrmgt_sclk_length = RREG32_PLL(DYN_PWRMGT_SCLK_LENGTH);
|
||||
dyn_pwrmgt_sclk_length &= ~REDUCED_POWER_SCLK_HILEN(0xf);
|
||||
|
@ -106,7 +106,7 @@ void rv770_pm_misc(struct radeon_device *rdev)
|
||||
|
||||
if ((voltage->type == VOLTAGE_SW) && voltage->voltage) {
|
||||
if (voltage->voltage != rdev->pm.current_vddc) {
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage);
|
||||
radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
|
||||
rdev->pm.current_vddc = voltage->voltage;
|
||||
DRM_DEBUG("Setting: v: %d\n", voltage->voltage);
|
||||
}
|
||||
@ -1255,9 +1255,6 @@ int rv770_init(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = radeon_dummy_page_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
/* This don't do much */
|
||||
r = radeon_gem_init(rdev);
|
||||
if (r)
|
||||
@ -1372,7 +1369,6 @@ void rv770_fini(struct radeon_device *rdev)
|
||||
radeon_atombios_fini(rdev);
|
||||
kfree(rdev->bios);
|
||||
rdev->bios = NULL;
|
||||
radeon_dummy_page_fini(rdev);
|
||||
}
|
||||
|
||||
static void rv770_pcie_gen2_enable(struct radeon_device *rdev)
|
||||
|
@ -683,22 +683,14 @@ int ttm_get_pages(struct list_head *pages, int flags,
|
||||
gfp_flags |= GFP_HIGHUSER;
|
||||
|
||||
for (r = 0; r < count; ++r) {
|
||||
if ((flags & TTM_PAGE_FLAG_DMA32) && dma_address) {
|
||||
void *addr;
|
||||
addr = dma_alloc_coherent(NULL, PAGE_SIZE,
|
||||
&dma_address[r],
|
||||
gfp_flags);
|
||||
if (addr == NULL)
|
||||
return -ENOMEM;
|
||||
p = virt_to_page(addr);
|
||||
} else
|
||||
p = alloc_page(gfp_flags);
|
||||
p = alloc_page(gfp_flags);
|
||||
if (!p) {
|
||||
|
||||
printk(KERN_ERR TTM_PFX
|
||||
"Unable to allocate page.");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
list_add(&p->lru, pages);
|
||||
}
|
||||
return 0;
|
||||
@ -746,24 +738,12 @@ void ttm_put_pages(struct list_head *pages, unsigned page_count, int flags,
|
||||
unsigned long irq_flags;
|
||||
struct ttm_page_pool *pool = ttm_get_pool(flags, cstate);
|
||||
struct page *p, *tmp;
|
||||
unsigned r;
|
||||
|
||||
if (pool == NULL) {
|
||||
/* No pool for this memory type so free the pages */
|
||||
|
||||
r = page_count-1;
|
||||
list_for_each_entry_safe(p, tmp, pages, lru) {
|
||||
if ((flags & TTM_PAGE_FLAG_DMA32) && dma_address) {
|
||||
void *addr = page_address(p);
|
||||
WARN_ON(!addr || !dma_address[r]);
|
||||
if (addr)
|
||||
dma_free_coherent(NULL, PAGE_SIZE,
|
||||
addr,
|
||||
dma_address[r]);
|
||||
dma_address[r] = 0;
|
||||
} else
|
||||
__free_page(p);
|
||||
r--;
|
||||
__free_page(p);
|
||||
}
|
||||
/* Make the pages list empty */
|
||||
INIT_LIST_HEAD(pages);
|
||||
|
@ -5,6 +5,7 @@ config STUB_POULSBO
|
||||
# Poulsbo stub depends on ACPI_VIDEO when ACPI is enabled
|
||||
# but for select to work, need to select ACPI_VIDEO's dependencies, ick
|
||||
select BACKLIGHT_CLASS_DEVICE if ACPI
|
||||
select VIDEO_OUTPUT_CONTROL if ACPI
|
||||
select INPUT if ACPI
|
||||
select ACPI_VIDEO if ACPI
|
||||
select THERMAL if ACPI
|
||||
|
Loading…
Reference in New Issue
Block a user