Commit dcd6dfcf authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-linus' into drm-core-next

parents cbc8cc04 d785d78b
...@@ -30,11 +30,12 @@ config DRM_NOUVEAU_DEBUG ...@@ -30,11 +30,12 @@ config DRM_NOUVEAU_DEBUG
via debugfs. via debugfs.
menu "I2C encoder or helper chips" menu "I2C encoder or helper chips"
depends on DRM depends on DRM && I2C
config DRM_I2C_CH7006 config DRM_I2C_CH7006
tristate "Chrontel ch7006 TV encoder" tristate "Chrontel ch7006 TV encoder"
default m if DRM_NOUVEAU depends on DRM_NOUVEAU
default m
help help
Support for Chrontel ch7006 and similar TV encoders, found Support for Chrontel ch7006 and similar TV encoders, found
on some nVidia video cards. on some nVidia video cards.
......
...@@ -311,8 +311,10 @@ nouveau_bo_create_ttm_backend_entry(struct ttm_bo_device *bdev) ...@@ -311,8 +311,10 @@ nouveau_bo_create_ttm_backend_entry(struct ttm_bo_device *bdev)
struct drm_device *dev = dev_priv->dev; struct drm_device *dev = dev_priv->dev;
switch (dev_priv->gart_info.type) { switch (dev_priv->gart_info.type) {
#if __OS_HAS_AGP
case NOUVEAU_GART_AGP: case NOUVEAU_GART_AGP:
return ttm_agp_backend_init(bdev, dev->agp->bridge); return ttm_agp_backend_init(bdev, dev->agp->bridge);
#endif
case NOUVEAU_GART_SGDMA: case NOUVEAU_GART_SGDMA:
return nouveau_sgdma_init_ttm(dev); return nouveau_sgdma_init_ttm(dev);
default: default:
......
...@@ -205,7 +205,7 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) ...@@ -205,7 +205,7 @@ nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr)
schedule_timeout(1); schedule_timeout(1);
if (intr && signal_pending(current)) { if (intr && signal_pending(current)) {
ret = -ERESTART; ret = -ERESTARTSYS;
break; break;
} }
} }
......
...@@ -342,8 +342,6 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, ...@@ -342,8 +342,6 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv,
} }
ret = ttm_bo_wait_cpu(&nvbo->bo, false); ret = ttm_bo_wait_cpu(&nvbo->bo, false);
if (ret == -ERESTART)
ret = -EAGAIN;
if (ret) if (ret)
return ret; return ret;
goto retry; goto retry;
...@@ -915,8 +913,6 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, ...@@ -915,8 +913,6 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
goto out; goto out;
ret = ttm_bo_wait_cpu(&nvbo->bo, no_wait); ret = ttm_bo_wait_cpu(&nvbo->bo, no_wait);
if (ret == -ERESTART)
ret = -EAGAIN;
if (ret) if (ret)
goto out; goto out;
} }
...@@ -925,9 +921,6 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, ...@@ -925,9 +921,6 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
ret = ttm_bo_wait(&nvbo->bo, false, false, no_wait); ret = ttm_bo_wait(&nvbo->bo, false, false, no_wait);
} else { } else {
ret = ttm_bo_synccpu_write_grab(&nvbo->bo, no_wait); ret = ttm_bo_synccpu_write_grab(&nvbo->bo, no_wait);
if (ret == -ERESTART)
ret = -EAGAIN;
else
if (ret == 0) if (ret == 0)
nvbo->cpu_filp = file_priv; nvbo->cpu_filp = file_priv;
} }
......
...@@ -407,6 +407,7 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev) ...@@ -407,6 +407,7 @@ uint64_t nouveau_mem_fb_amount(struct drm_device *dev)
return 0; return 0;
} }
#if __OS_HAS_AGP
static void nouveau_mem_reset_agp(struct drm_device *dev) static void nouveau_mem_reset_agp(struct drm_device *dev)
{ {
uint32_t saved_pci_nv_1, saved_pci_nv_19, pmc_enable; uint32_t saved_pci_nv_1, saved_pci_nv_19, pmc_enable;
...@@ -432,10 +433,12 @@ static void nouveau_mem_reset_agp(struct drm_device *dev) ...@@ -432,10 +433,12 @@ static void nouveau_mem_reset_agp(struct drm_device *dev)
nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19); nv_wr32(dev, NV04_PBUS_PCI_NV_19, saved_pci_nv_19);
nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1); nv_wr32(dev, NV04_PBUS_PCI_NV_1, saved_pci_nv_1);
} }
#endif
int int
nouveau_mem_init_agp(struct drm_device *dev) nouveau_mem_init_agp(struct drm_device *dev)
{ {
#if __OS_HAS_AGP
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct drm_agp_info info; struct drm_agp_info info;
struct drm_agp_mode mode; struct drm_agp_mode mode;
...@@ -471,6 +474,7 @@ nouveau_mem_init_agp(struct drm_device *dev) ...@@ -471,6 +474,7 @@ nouveau_mem_init_agp(struct drm_device *dev)
dev_priv->gart_info.type = NOUVEAU_GART_AGP; dev_priv->gart_info.type = NOUVEAU_GART_AGP;
dev_priv->gart_info.aper_base = info.aperture_base; dev_priv->gart_info.aper_base = info.aperture_base;
dev_priv->gart_info.aper_size = info.aperture_size; dev_priv->gart_info.aper_size = info.aperture_size;
#endif
return 0; return 0;
} }
......
...@@ -252,8 +252,9 @@ nv40_grctx_init(struct drm_device *dev) ...@@ -252,8 +252,9 @@ nv40_grctx_init(struct drm_device *dev)
memcpy(pgraph->ctxprog, fw->data, fw->size); memcpy(pgraph->ctxprog, fw->data, fw->size);
cp = pgraph->ctxprog; cp = pgraph->ctxprog;
if (cp->signature != 0x5043564e || cp->version != 0 || if (le32_to_cpu(cp->signature) != 0x5043564e ||
cp->length != ((fw->size - 7) / 4)) { cp->version != 0 ||
le16_to_cpu(cp->length) != ((fw->size - 7) / 4)) {
NV_ERROR(dev, "ctxprog invalid\n"); NV_ERROR(dev, "ctxprog invalid\n");
release_firmware(fw); release_firmware(fw);
nv40_grctx_fini(dev); nv40_grctx_fini(dev);
...@@ -281,8 +282,9 @@ nv40_grctx_init(struct drm_device *dev) ...@@ -281,8 +282,9 @@ nv40_grctx_init(struct drm_device *dev)
memcpy(pgraph->ctxvals, fw->data, fw->size); memcpy(pgraph->ctxvals, fw->data, fw->size);
cv = (void *)pgraph->ctxvals; cv = (void *)pgraph->ctxvals;
if (cv->signature != 0x5643564e || cv->version != 0 || if (le32_to_cpu(cv->signature) != 0x5643564e ||
cv->length != ((fw->size - 9) / 8)) { cv->version != 0 ||
le32_to_cpu(cv->length) != ((fw->size - 9) / 8)) {
NV_ERROR(dev, "ctxvals invalid\n"); NV_ERROR(dev, "ctxvals invalid\n");
release_firmware(fw); release_firmware(fw);
nv40_grctx_fini(dev); nv40_grctx_fini(dev);
...@@ -294,8 +296,9 @@ nv40_grctx_init(struct drm_device *dev) ...@@ -294,8 +296,9 @@ nv40_grctx_init(struct drm_device *dev)
cp = pgraph->ctxprog; cp = pgraph->ctxprog;
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
for (i = 0; i < cp->length; i++) for (i = 0; i < le16_to_cpu(cp->length); i++)
nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp->data[i]); nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA,
le32_to_cpu(cp->data[i]));
pgraph->accel_blocked = false; pgraph->accel_blocked = false;
return 0; return 0;
...@@ -329,8 +332,9 @@ nv40_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx) ...@@ -329,8 +332,9 @@ nv40_grctx_vals_load(struct drm_device *dev, struct nouveau_gpuobj *ctx)
if (!cv) if (!cv)
return; return;
for (i = 0; i < cv->length; i++) for (i = 0; i < le32_to_cpu(cv->length); i++)
nv_wo32(dev, ctx, cv->data[i].offset, cv->data[i].value); nv_wo32(dev, ctx, le32_to_cpu(cv->data[i].offset),
le32_to_cpu(cv->data[i].value));
} }
/* /*
......
...@@ -49,7 +49,7 @@ radeon-y += radeon_device.o radeon_kms.o \ ...@@ -49,7 +49,7 @@ radeon-y += radeon_device.o radeon_kms.o \
radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \ radeon_cs.o radeon_bios.o radeon_benchmark.o r100.o r300.o r420.o \
rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \
r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \
r600_blit_kms.o radeon_pm.o atombios_dp.o r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o
radeon-$(CONFIG_COMPAT) += radeon_ioc32.o radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
......
...@@ -1374,7 +1374,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p, ...@@ -1374,7 +1374,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
case RADEON_TXFORMAT_ARGB4444: case RADEON_TXFORMAT_ARGB4444:
case RADEON_TXFORMAT_VYUY422: case RADEON_TXFORMAT_VYUY422:
case RADEON_TXFORMAT_YVYU422: case RADEON_TXFORMAT_YVYU422:
case RADEON_TXFORMAT_DXT1:
case RADEON_TXFORMAT_SHADOW16: case RADEON_TXFORMAT_SHADOW16:
case RADEON_TXFORMAT_LDUDV655: case RADEON_TXFORMAT_LDUDV655:
case RADEON_TXFORMAT_DUDV88: case RADEON_TXFORMAT_DUDV88:
...@@ -1382,12 +1381,19 @@ static int r100_packet0_check(struct radeon_cs_parser *p, ...@@ -1382,12 +1381,19 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
break; break;
case RADEON_TXFORMAT_ARGB8888: case RADEON_TXFORMAT_ARGB8888:
case RADEON_TXFORMAT_RGBA8888: case RADEON_TXFORMAT_RGBA8888:
case RADEON_TXFORMAT_DXT23:
case RADEON_TXFORMAT_DXT45:
case RADEON_TXFORMAT_SHADOW32: case RADEON_TXFORMAT_SHADOW32:
case RADEON_TXFORMAT_LDUDUV8888: case RADEON_TXFORMAT_LDUDUV8888:
track->textures[i].cpp = 4; track->textures[i].cpp = 4;
break; break;
case RADEON_TXFORMAT_DXT1:
track->textures[i].cpp = 1;
track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
break;
case RADEON_TXFORMAT_DXT23:
case RADEON_TXFORMAT_DXT45:
track->textures[i].cpp = 1;
track->textures[i].compress_format = R100_TRACK_COMP_DXT35;
break;
} }
track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf);
track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf);
...@@ -2731,6 +2737,7 @@ static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t) ...@@ -2731,6 +2737,7 @@ static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t)
DRM_ERROR("coordinate type %d\n", t->tex_coord_type); DRM_ERROR("coordinate type %d\n", t->tex_coord_type);
DRM_ERROR("width round to power of 2 %d\n", t->roundup_w); DRM_ERROR("width round to power of 2 %d\n", t->roundup_w);
DRM_ERROR("height round to power of 2 %d\n", t->roundup_h); DRM_ERROR("height round to power of 2 %d\n", t->roundup_h);
DRM_ERROR("compress format %d\n", t->compress_format);
} }
static int r100_cs_track_cube(struct radeon_device *rdev, static int r100_cs_track_cube(struct radeon_device *rdev,
...@@ -2760,6 +2767,36 @@ static int r100_cs_track_cube(struct radeon_device *rdev, ...@@ -2760,6 +2767,36 @@ static int r100_cs_track_cube(struct radeon_device *rdev,
return 0; return 0;
} }
static int r100_track_compress_size(int compress_format, int w, int h)
{
int block_width, block_height, block_bytes;
int wblocks, hblocks;
int min_wblocks;
int sz;
block_width = 4;
block_height = 4;
switch (compress_format) {
case R100_TRACK_COMP_DXT1:
block_bytes = 8;
min_wblocks = 4;
break;
default:
case R100_TRACK_COMP_DXT35:
block_bytes = 16;
min_wblocks = 2;
break;
}
hblocks = (h + block_height - 1) / block_height;
wblocks = (w + block_width - 1) / block_width;
if (wblocks < min_wblocks)
wblocks = min_wblocks;
sz = wblocks * hblocks * block_bytes;
return sz;
}
static int r100_cs_track_texture_check(struct radeon_device *rdev, static int r100_cs_track_texture_check(struct radeon_device *rdev,
struct r100_cs_track *track) struct r100_cs_track *track)
{ {
...@@ -2797,9 +2834,15 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev, ...@@ -2797,9 +2834,15 @@ static int r100_cs_track_texture_check(struct radeon_device *rdev,
h = h / (1 << i); h = h / (1 << i);
if (track->textures[u].roundup_h) if (track->textures[u].roundup_h)
h = roundup_pow_of_two(h); h = roundup_pow_of_two(h);
if (track->textures[u].compress_format) {
size += r100_track_compress_size(track->textures[u].compress_format, w, h);
/* compressed textures are block based */
} else
size += w * h; size += w * h;
} }
size *= track->textures[u].cpp; size *= track->textures[u].cpp;
switch (track->textures[u].tex_coord_type) { switch (track->textures[u].tex_coord_type) {
case 0: case 0:
break; break;
...@@ -2967,6 +3010,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track ...@@ -2967,6 +3010,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track
track->arrays[i].esize = 0x7F; track->arrays[i].esize = 0x7F;
} }
for (i = 0; i < track->num_texture; i++) { for (i = 0; i < track->num_texture; i++) {
track->textures[i].compress_format = R100_TRACK_COMP_NONE;
track->textures[i].pitch = 16536; track->textures[i].pitch = 16536;
track->textures[i].width = 16536; track->textures[i].width = 16536;
track->textures[i].height = 16536; track->textures[i].height = 16536;
...@@ -3399,6 +3443,8 @@ int r100_init(struct radeon_device *rdev) ...@@ -3399,6 +3443,8 @@ int r100_init(struct radeon_device *rdev)
r100_errata(rdev); r100_errata(rdev);
/* Initialize clocks */ /* Initialize clocks */
radeon_get_clock_info(rdev->ddev); radeon_get_clock_info(rdev->ddev);
/* Initialize power management */
radeon_pm_init(rdev);
/* Get vram informations */ /* Get vram informations */
r100_vram_info(rdev); r100_vram_info(rdev);
/* Initialize memory controller (also test AGP) */ /* Initialize memory controller (also test AGP) */
......
...@@ -28,6 +28,10 @@ struct r100_cs_cube_info { ...@@ -28,6 +28,10 @@ struct r100_cs_cube_info {
unsigned height; unsigned height;
}; };
#define R100_TRACK_COMP_NONE 0
#define R100_TRACK_COMP_DXT1 1
#define R100_TRACK_COMP_DXT35 2
struct r100_cs_track_texture { struct r100_cs_track_texture {
struct radeon_bo *robj; struct radeon_bo *robj;
struct r100_cs_cube_info cube_info[5]; /* info for 5 non-primary faces */ struct r100_cs_cube_info cube_info[5]; /* info for 5 non-primary faces */
...@@ -44,6 +48,7 @@ struct r100_cs_track_texture { ...@@ -44,6 +48,7 @@ struct r100_cs_track_texture {
bool enabled; bool enabled;
bool roundup_w; bool roundup_w;
bool roundup_h; bool roundup_h;
unsigned compress_format;
}; };
struct r100_cs_track_limits { struct r100_cs_track_limits {
......
...@@ -401,7 +401,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, ...@@ -401,7 +401,6 @@ int r200_packet0_check(struct radeon_cs_parser *p,
case R200_TXFORMAT_Y8: case R200_TXFORMAT_Y8:
track->textures[i].cpp = 1; track->textures[i].cpp = 1;
break; break;
case R200_TXFORMAT_DXT1:
case R200_TXFORMAT_AI88: case R200_TXFORMAT_AI88:
case R200_TXFORMAT_ARGB1555: case R200_TXFORMAT_ARGB1555:
case R200_TXFORMAT_RGB565: case R200_TXFORMAT_RGB565:
...@@ -418,9 +417,16 @@ int r200_packet0_check(struct radeon_cs_parser *p, ...@@ -418,9 +417,16 @@ int r200_packet0_check(struct radeon_cs_parser *p,
case R200_TXFORMAT_ABGR8888: case R200_TXFORMAT_ABGR8888:
case R200_TXFORMAT_BGR111110: case R200_TXFORMAT_BGR111110:
case R200_TXFORMAT_LDVDU8888: case R200_TXFORMAT_LDVDU8888:
track->textures[i].cpp = 4;
break;
case R200_TXFORMAT_DXT1:
track->textures[i].cpp = 1;
track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
break;
case R200_TXFORMAT_DXT23: case R200_TXFORMAT_DXT23:
case R200_TXFORMAT_DXT45: case R200_TXFORMAT_DXT45:
track->textures[i].cpp = 4; track->textures[i].cpp = 1;
track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
break; break;
} }
track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf);
......
...@@ -686,7 +686,15 @@ static int r300_packet0_check(struct radeon_cs_parser *p, ...@@ -686,7 +686,15 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
r100_cs_dump_packet(p, pkt); r100_cs_dump_packet(p, pkt);
return r; return r;
} }
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
tile_flags |= R300_TXO_MACRO_TILE;
if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
tile_flags |= R300_TXO_MICRO_TILE;
tmp = idx_value + ((u32)reloc->lobj.gpu_offset);
tmp |= tile_flags;
ib[idx] = tmp;
track->textures[i].robj = reloc->robj; track->textures[i].robj = reloc->robj;
break; break;
/* Tracked registers */ /* Tracked registers */
...@@ -852,7 +860,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, ...@@ -852,7 +860,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
case R300_TX_FORMAT_Z6Y5X5: case R300_TX_FORMAT_Z6Y5X5:
case R300_TX_FORMAT_W4Z4Y4X4: case R300_TX_FORMAT_W4Z4Y4X4:
case R300_TX_FORMAT_W1Z5Y5X5: case R300_TX_FORMAT_W1Z5Y5X5:
case R300_TX_FORMAT_DXT1:
case R300_TX_FORMAT_D3DMFT_CxV8U8: case R300_TX_FORMAT_D3DMFT_CxV8U8:
case R300_TX_FORMAT_B8G8_B8G8: case R300_TX_FORMAT_B8G8_B8G8:
case R300_TX_FORMAT_G8R8_G8B8: case R300_TX_FORMAT_G8R8_G8B8:
...@@ -866,8 +873,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p, ...@@ -866,8 +873,6 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
case 0x17: case 0x17:
case R300_TX_FORMAT_FL_I32: case R300_TX_FORMAT_FL_I32:
case 0x1e: case 0x1e:
case R300_TX_FORMAT_DXT3:
case R300_TX_FORMAT_DXT5:
track->textures[i].cpp = 4; track->textures[i].cpp = 4;
break; break;
case R300_TX_FORMAT_W16Z16Y16X16: case R300_TX_FORMAT_W16Z16Y16X16:
...@@ -878,6 +883,15 @@ static int r300_packet0_check(struct radeon_cs_parser *p, ...@@ -878,6 +883,15 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
case R300_TX_FORMAT_FL_R32G32B32A32: case R300_TX_FORMAT_FL_R32G32B32A32:
track->textures[i].cpp = 16; track->textures[i].cpp = 16;
break; break;
case R300_TX_FORMAT_DXT1:
track->textures[i].cpp = 1;
track->textures[i].compress_format = R100_TRACK_COMP_DXT1;
break;
case R300_TX_FORMAT_DXT3:
case R300_TX_FORMAT_DXT5:
track->textures[i].cpp = 1;
track->textures[i].compress_format = R100_TRACK_COMP_DXT35;
break;
default: default:
DRM_ERROR("Invalid texture format %u\n", DRM_ERROR("Invalid texture format %u\n",
(idx_value & 0x1F)); (idx_value & 0x1F));
...@@ -1324,6 +1338,8 @@ int r300_init(struct radeon_device *rdev) ...@@ -1324,6 +1338,8 @@ int r300_init(struct radeon_device *rdev)
r300_errata(rdev); r300_errata(rdev);
/* Initialize clocks */ /* Initialize clocks */
radeon_get_clock_info(rdev->ddev); radeon_get_clock_info(rdev->ddev);
/* Initialize power management */
radeon_pm_init(rdev);
/* Get vram informations */ /* Get vram informations */
r300_vram_info(rdev); r300_vram_info(rdev);
/* Initialize memory controller (also test AGP) */ /* Initialize memory controller (also test AGP) */
......
...@@ -1863,6 +1863,14 @@ int r600_startup(struct radeon_device *rdev) ...@@ -1863,6 +1863,14 @@ int r600_startup(struct radeon_device *rdev)
} }
r600_gpu_init(rdev); r600_gpu_init(rdev);
if (!rdev->r600_blit.shader_obj) {
r = r600_blit_init(rdev);
if (r) {
DRM_ERROR("radeon: failed blitter (%d).\n", r);
return r;
}
}
r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
if (unlikely(r != 0)) if (unlikely(r != 0))
return r; return r;
...@@ -2038,12 +2046,6 @@ int r600_init(struct radeon_device *rdev) ...@@ -2038,12 +2046,6 @@ int r600_init(struct radeon_device *rdev)
if (r) if (r)
return r; return r;
r = r600_blit_init(rdev);
if (r) {
DRM_ERROR("radeon: failed blitter (%d).\n", r);
return r;
}
rdev->accel_working = true; rdev->accel_working = true;
r = r600_startup(rdev); r = r600_startup(rdev);
if (r) { if (r) {
...@@ -2065,6 +2067,10 @@ int r600_init(struct radeon_device *rdev) ...@@ -2065,6 +2067,10 @@ int r600_init(struct radeon_device *rdev)
rdev->accel_working = false; rdev->accel_working = false;
} }
} }
r = r600_audio_init(rdev);
if (r)
return r; /* TODO error handling */
return 0; return 0;
} }
...@@ -2073,6 +2079,7 @@ void r600_fini(struct radeon_device *rdev) ...@@ -2073,6 +2079,7 @@ void r600_fini(struct radeon_device *rdev)
/* Suspend operations */ /* Suspend operations */
r600_suspend(rdev); r600_suspend(rdev);
r600_audio_fini(rdev);
r600_blit_fini(rdev); r600_blit_fini(rdev);
r600_irq_fini(rdev); r600_irq_fini(rdev);
radeon_irq_kms_fini(rdev); radeon_irq_kms_fini(rdev);
......
/*
* Copyright 2008 Advanced Micro Devices, Inc.
* Copyright 2008 Red Hat Inc.
* Copyright 2009 Christian König.
*
* 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 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) OR AUTHOR(S) 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: Christian König
*/
#include "drmP.h"
#include "radeon.h"
#include "radeon_reg.h"
#include "atom.h"
#define AUDIO_TIMER_INTERVALL 100 /* 1/10 sekund should be enough */
/*
* check if the chipset is supported
*/
static int r600_audio_chipset_supported(struct radeon_device *rdev)
{
return rdev->family >= CHIP_R600
|| rdev->family == CHIP_RS600
|| rdev->family == CHIP_RS690
|| rdev->family == CHIP_RS740;
}
/*
* current number of channels
*/
static int r600_audio_channels(struct radeon_device *rdev)
{
return (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0x7) + 1;
}
/*
* current bits per sample
*/
static int r600_audio_bits_per_sample(struct radeon_device *rdev)
{
uint32_t value = (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0xF0) >> 4;
switch (value) {
case 0x0: return 8;
case 0x1: return 16;
case 0x2: return 20;
case 0x3: return 24;
case 0x4: return 32;
}
DRM_ERROR("Unknown bits per sample 0x%x using 16 instead.\n", (int)value);
return 16;
}
/*
* current sampling rate in HZ
*/
static int r600_audio_rate(struct radeon_device *rdev)
{
uint32_t value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL);
uint32_t result;
if (value & 0x4000)
result = 44100;
else
result = 48000;
result *= ((value >> 11) & 0x7) + 1;
result /= ((value >> 8) & 0x7) + 1;
return result;
}
/*
* iec 60958 status bits
*/
static uint8_t r600_audio_status_bits(struct radeon_device *rdev)
{
return RREG32(R600_AUDIO_STATUS_BITS) & 0xff;
}
/*
* iec 60958 category code
*/
static uint8_t r600_audio_category_code(struct radeon_device *rdev)
{
return (RREG32(R600_AUDIO_STATUS_BITS) >> 8) & 0xff;
}
/*
* update all hdmi interfaces with current audio parameters
*/
static void r600_audio_update_hdmi(unsigned long param)
{
struct radeon_device *rdev = (struct radeon_device *)param;
struct drm_device *dev = rdev->ddev;
int channels = r600_audio_channels(rdev);
int rate = r600_audio_rate(rdev);
int bps = r600_audio_bits_per_sample(rdev);
uint8_t status_bits = r600_audio_status_bits(rdev);
uint8_t category_code = r600_audio_category_code(rdev);
struct drm_encoder *encoder;
int changes = 0;
changes |= channels != rdev->audio_channels;
changes |= rate != rdev->audio_rate;
changes |= bps != rdev->audio_bits_per_sample;
changes |= status_bits != rdev->audio_status_bits;
changes |= category_code != rdev->audio_category_code;
if (changes) {
rdev->audio_channels = channels;
rdev->audio_rate = rate;
rdev->audio_bits_per_sample = bps;
rdev->audio_status_bits = status_bits;
rdev->audio_category_code = category_code;
}
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
if (changes || r600_hdmi_buffer_status_changed(encoder))
r600_hdmi_update_audio_settings(
encoder, channels,
rate, bps, status_bits,
category_code);
}
mod_timer(&rdev->audio_timer,
jiffies + msecs_to_jiffies(AUDIO_TIMER_INTERVALL));
}
/*
* initialize the audio vars and register the update timer
*/
int r600_audio_init(struct radeon_device *rdev)
{
if (!r600_audio_chipset_supported(rdev))
return 0;
DRM_INFO("%s audio support", radeon_audio ? "Enabling" : "Disabling");
WREG32_P(R600_AUDIO_ENABLE, radeon_audio ? 0x81000000 : 0x0, ~0x81000000);
rdev->audio_channels = -1;
rdev->audio_rate = -1;
rdev->audio_bits_per_sample = -1;
rdev->audio_status_bits = 0;
rdev->audio_category_code = 0;
setup_timer(
&rdev->audio_timer,
r600_audio_update_hdmi,
(unsigned long)rdev);
mod_timer(&rdev->audio_timer, jiffies + 1);
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
*/
void r600_audio_set_clock(struct drm_encoder *encoder, int clock)
{
struct drm_device *dev = encoder->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
int base_rate = 48000;
switch (radeon_encoder->encoder_id) {
case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:
case ENCODER_OBJECT_ID_INTERNAL_LVTM1:
WREG32_P(R600_AUDIO_TIMING, 0, ~0x301);
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:
WREG32_P(R600_AUDIO_TIMING, 0x100, ~0x301);
break;
default:
DRM_ERROR("Unsupported encoder type 0x%02X\n",
radeon_encoder->encoder_id);
return;
}
switch (r600_audio_tmds_index(encoder)) {
case 0:
WREG32(R600_AUDIO_PLL1_MUL, base_rate*50);
WREG32(R600_AUDIO_PLL1_DIV, clock*100);
WREG32(R600_AUDIO_CLK_SRCSEL, 0);
break;
case 1:
WREG32(R600_AUDIO_PLL2_MUL, base_rate*50);
WREG32(R600_AUDIO_PLL2_DIV, clock*100);
WREG32(R600_AUDIO_CLK_SRCSEL, 1);
break;
}
}
/*
* release the audio timer
* TODO: How to do this correctly on SMP systems?
*/
void r600_audio_fini(struct radeon_device *rdev)
{
if (!r600_audio_chipset_supported(rdev))
return;
WREG32_P(R600_AUDIO_ENABLE, 0x0, ~0x81000000);
del_timer(&rdev->audio_timer);
}
This diff is collapsed.
...@@ -110,5 +110,79 @@ ...@@ -110,5 +110,79 @@
#define R600_BIOS_6_SCRATCH 0x173c #define R600_BIOS_6_SCRATCH 0x173c
#define R600_BIOS_7_SCRATCH 0x1740 #define R600_BIOS_7_SCRATCH 0x1740
/* Audio, these regs were reverse enginered,
* so the chance is high that the naming is wrong
* R6xx+ ??? */
/* Audio clocks */
#define R600_AUDIO_PLL1_MUL 0x0514
#define R600_AUDIO_PLL1_DIV 0x0518
#define R600_AUDIO_PLL2_MUL 0x0524
#define R600_AUDIO_PLL2_DIV 0x0528
#define R600_AUDIO_CLK_SRCSEL 0x0534
/* Audio general */
#define R600_AUDIO_ENABLE 0x7300
#define R600_AUDIO_TIMING 0x7344
/* Audio params */
#define R600_AUDIO_VENDOR_ID 0x7380
#define R600_AUDIO_REVISION_ID 0x7384
#define R600_AUDIO_ROOT_NODE_COUNT 0x7388
#define R600_AUDIO_NID1_NODE_COUNT 0x738c
#define R600_AUDIO_NID1_TYPE 0x7390
#define R600_AUDIO_SUPPORTED_SIZE_RATE 0x7394
#define R600_AUDIO_SUPPORTED_CODEC 0x7398
#define R600_AUDIO_SUPPORTED_POWER_STATES 0x739c
#define R600_AUDIO_NID2_CAPS 0x73a0
#define R600_AUDIO_NID3_CAPS 0x73a4
#define R600_AUDIO_NID3_PIN_CAPS 0x73a8
/* Audio conn list */
#define R600_AUDIO_CONN_LIST_LEN 0x73ac
#define R600_AUDIO_CONN_LIST 0x73b0
/* Audio verbs */
#define R600_AUDIO_RATE_BPS_CHANNEL 0x73c0
#define R600_AUDIO_PLAYING 0x73c4
#define R600_AUDIO_IMPLEMENTATION_ID 0x73c8
#define R600_AUDIO_CONFIG_DEFAULT 0x73cc
#define R600_AUDIO_PIN_SENSE 0x73d0
#define R600_AUDIO_PIN_WIDGET_CNTL 0x73d4
#define R600_AUDIO_STATUS_BITS 0x73d8
/* HDMI base register addresses */
#define R600_HDMI_TMDS1 0x7400
#define R600_HDMI_TMDS2 0x7700
#define R600_HDMI_DIG 0x7800
/* HDMI registers */
#define R600_HDMI_ENABLE 0x00
#define R600_HDMI_STATUS 0x04
#define R600_HDMI_CNTL 0x08
#define R600_HDMI_UNKNOWN_0 0x0C
#define R600_HDMI_AUDIOCNTL 0x10
#define R600_HDMI_VIDEOCNTL 0x14
#define R600_HDMI_VERSION 0x18
#define R600_HDMI_UNKNOWN_1 0x28
#define R600_HDMI_VIDEOINFOFRAME_0 0x54
#define R600_HDMI_VIDEOINFOFRAME_1 0x58
#define R600_HDMI_VIDEOINFOFRAME_2 0x5c
#define R600_HDMI_VIDEOINFOFRAME_3 0x60
#define R600_HDMI_32kHz_CTS 0xac
#define R600_HDMI_32kHz_N 0xb0
#define R600_HDMI_44_1kHz_CTS 0xb4
#define R600_HDMI_44_1kHz_N 0xb8
#define R600_HDMI_48kHz_CTS 0xbc
#define R600_HDMI_48kHz_N 0xc0
#define R600_HDMI_AUDIOINFOFRAME_0 0xcc
#define R600_HDMI_AUDIOINFOFRAME_1 0xd0
#define R600_HDMI_IEC60958_1 0xd4
#define R600_HDMI_IEC60958_2 0xd8
#define R600_HDMI_UNKNOWN_2 0xdc
#define R600_HDMI_AUDIO_DEBUG_0 0xe0
#define R600_HDMI_AUDIO_DEBUG_1 0xe4
#define R600_HDMI_AUDIO_DEBUG_2 0xe8
#define R600_HDMI_AUDIO_DEBUG_3 0xec
#endif #endif
...@@ -89,6 +89,7 @@ extern int radeon_testing; ...@@ -89,6 +89,7 @@ extern int radeon_testing;
extern int radeon_connector_table; extern int radeon_connector_table;
extern int radeon_tv; extern int radeon_tv;
extern int radeon_new_pll; extern int radeon_new_pll;
extern int radeon_audio;
/* /*
* 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
...@@ -814,6 +815,14 @@ struct radeon_device { ...@@ -814,6 +815,14 @@ struct radeon_device {
struct r600_ih ih; /* r6/700 interrupt ring */ struct r600_ih ih; /* r6/700 interrupt ring */
struct workqueue_struct *wq; struct workqueue_struct *wq;
struct work_struct hotplug_work; struct work_struct hotplug_work;
/* audio stuff */
struct timer_list audio_timer;
int audio_channels;
int audio_rate;
int audio_bits_per_sample;
uint8_t audio_status_bits;
uint8_t audio_category_code;
}; };
int radeon_device_init(struct radeon_device *rdev, int radeon_device_init(struct radeon_device *rdev,
...@@ -1016,6 +1025,7 @@ extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data); ...@@ -1016,6 +1025,7 @@ extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data);
extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable); extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enable);
extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain); extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain);
extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo);
/* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */ /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
struct r100_mc_save { struct r100_mc_save {
...@@ -1146,6 +1156,21 @@ extern void r600_irq_fini(struct radeon_device *rdev); ...@@ -1146,6 +1156,21 @@ extern void r600_irq_fini(struct radeon_device *rdev);
extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size); extern void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size);
extern int r600_irq_set(struct radeon_device *rdev); extern int r600_irq_set(struct radeon_device *rdev);
extern int r600_audio_init(struct radeon_device *rdev);
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_fini(struct radeon_device *rdev);
extern void r600_hdmi_init(struct drm_encoder *encoder);
extern void r600_hdmi_enable(struct drm_encoder *encoder, int enable);
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 void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,
int channels,
int rate,
int bps,
uint8_t status_bits,
uint8_t category_code);
#include "radeon_object.h" #include "radeon_object.h"
#endif #endif
...@@ -87,6 +87,7 @@ int radeon_testing = 0; ...@@ -87,6 +87,7 @@ int radeon_testing = 0;
int radeon_connector_table = 0; int radeon_connector_table = 0;
int radeon_tv = 1; int radeon_tv = 1;
int radeon_new_pll = 1; int radeon_new_pll = 1;
int radeon_audio = 1;
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);
...@@ -124,6 +125,9 @@ module_param_named(tv, radeon_tv, int, 0444); ...@@ -124,6 +125,9 @@ module_param_named(tv, radeon_tv, int, 0444);
MODULE_PARM_DESC(new_pll, "Select new PLL code for AVIVO chips"); MODULE_PARM_DESC(new_pll, "Select new PLL code for AVIVO chips");
module_param_named(new_pll, radeon_new_pll, int, 0444); module_param_named(new_pll, radeon_new_pll, int, 0444);
MODULE_PARM_DESC(audio, "Audio enable (0 = disable)");
module_param_named(audio, radeon_audio, 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;
......
...@@ -438,6 +438,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) ...@@ -438,6 +438,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
union lvds_encoder_control args; union lvds_encoder_control args;
int index = 0; int index = 0;
int hdmi_detected = 0;
uint8_t frev, crev; uint8_t frev, crev;
struct radeon_encoder_atom_dig *dig; struct radeon_encoder_atom_dig *dig;
struct drm_connector *connector; struct drm_connector *connector;
...@@ -458,6 +459,9 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) ...@@ -458,6 +459,9 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
if (!radeon_connector->con_priv) if (!radeon_connector->con_priv)
return; return;
if (drm_detect_hdmi_monitor(radeon_connector->edid))
hdmi_detected = 1;
dig_connector = radeon_connector->con_priv; dig_connector = radeon_connector->con_priv;
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
...@@ -487,7 +491,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) ...@@ -487,7 +491,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
case 1: case 1:
args.v1.ucMisc = 0; args.v1.ucMisc = 0;
args.v1.ucAction = action; args.v1.ucAction = action;
if (drm_detect_hdmi_monitor(radeon_connector->edid)) if (hdmi_detected)
args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; args.v1.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
...@@ -512,7 +516,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) ...@@ -512,7 +516,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
if (dig->coherent_mode) if (dig->coherent_mode)
args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT; args.v2.ucMisc |= PANEL_ENCODER_MISC_COHERENT;
} }
if (drm_detect_hdmi_monitor(radeon_connector->edid)) if (hdmi_detected)
args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE; args.v2.ucMisc |= PANEL_ENCODER_MISC_HDMI_TYPE;
args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); args.v2.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
args.v2.ucTruncate = 0; args.v2.ucTruncate = 0;
...@@ -552,7 +556,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) ...@@ -552,7 +556,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action)
} }
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
r600_hdmi_enable(encoder, hdmi_detected);
} }
int int
...@@ -893,7 +897,6 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t ...@@ -893,7 +897,6 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
} }
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 static void
...@@ -1162,7 +1165,6 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder) ...@@ -1162,7 +1165,6 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
} }
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 static void
...@@ -1265,6 +1267,8 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, ...@@ -1265,6 +1267,8 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
break; break;
} }
atombios_apply_encoder_quirks(encoder, adjusted_mode); atombios_apply_encoder_quirks(encoder, adjusted_mode);
r600_hdmi_setmode(encoder, adjusted_mode);
} }
static bool static bool
...@@ -1510,4 +1514,6 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su ...@@ -1510,4 +1514,6 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su
drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs); drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
break; break;
} }
r600_hdmi_init(encoder);
} }
...@@ -66,8 +66,9 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size, ...@@ -66,8 +66,9 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size,
} }
r = radeon_bo_create(rdev, gobj, size, kernel, initial_domain, &robj); r = radeon_bo_create(rdev, gobj, size, kernel, initial_domain, &robj);
if (r) { if (r) {
DRM_ERROR("Failed to allocate GEM object (%d, %d, %u)\n", if (r != -ERESTARTSYS)
size, initial_domain, alignment); DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n",
size, initial_domain, alignment, r);
mutex_lock(&rdev->ddev->struct_mutex); mutex_lock(&rdev->ddev->struct_mutex);
drm_gem_object_unreference(gobj); drm_gem_object_unreference(gobj);
mutex_unlock(&rdev->ddev->struct_mutex); mutex_unlock(&rdev->ddev->struct_mutex);
...@@ -350,9 +351,10 @@ int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, ...@@ -350,9 +351,10 @@ int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data,
rbo = gobj->driver_private; rbo = gobj->driver_private;
r = radeon_bo_reserve(rbo, false); r = radeon_bo_reserve(rbo, false);
if (unlikely(r != 0)) if (unlikely(r != 0))
return r; goto out;
radeon_bo_get_tiling_flags(rbo, &args->tiling_flags, &args->pitch); radeon_bo_get_tiling_flags(rbo, &args->tiling_flags, &args->pitch);
radeon_bo_unreserve(rbo); radeon_bo_unreserve(rbo);
out:
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
drm_gem_object_unreference(gobj); drm_gem_object_unreference(gobj);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
......
...@@ -334,6 +334,9 @@ struct radeon_encoder { ...@@ -334,6 +334,9 @@ struct radeon_encoder {
enum radeon_rmx_type rmx_type; enum radeon_rmx_type rmx_type;
struct drm_display_mode native_mode; struct drm_display_mode native_mode;
void *enc_priv; void *enc_priv;
int hdmi_offset;
int hdmi_audio_workaround;
int hdmi_buffer_status;
}; };
struct radeon_connector_atom_dig { struct radeon_connector_atom_dig {
......
...@@ -56,6 +56,13 @@ static void radeon_ttm_bo_destroy(struct ttm_buffer_object *tbo) ...@@ -56,6 +56,13 @@ static void radeon_ttm_bo_destroy(struct ttm_buffer_object *tbo)
kfree(bo); kfree(bo);
} }
bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo)
{
if (bo->destroy == &radeon_ttm_bo_destroy)
return true;
return false;
}
void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
{ {
u32 c = 0; u32 c = 0;
...@@ -71,6 +78,8 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) ...@@ -71,6 +78,8 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain)
rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT; rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_TT;
if (domain & RADEON_GEM_DOMAIN_CPU) if (domain & RADEON_GEM_DOMAIN_CPU)
rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
if (!c)
rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
rbo->placement.num_placement = c; rbo->placement.num_placement = c;
rbo->placement.num_busy_placement = c; rbo->placement.num_busy_placement = c;
} }
...@@ -483,12 +492,18 @@ int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved, ...@@ -483,12 +492,18 @@ int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved,
void radeon_bo_move_notify(struct ttm_buffer_object *bo, void radeon_bo_move_notify(struct ttm_buffer_object *bo,
struct ttm_mem_reg *mem) struct ttm_mem_reg *mem)
{ {
struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo); struct radeon_bo *rbo;
if (!radeon_ttm_bo_is_radeon_bo(bo))
return;
rbo = container_of(bo, struct radeon_bo, tbo);
radeon_bo_check_tiling(rbo, 0, 1); radeon_bo_check_tiling(rbo, 0, 1);
} }
void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo) void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
{ {
struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo); struct radeon_bo *rbo;
if (!radeon_ttm_bo_is_radeon_bo(bo))
return;
rbo = container_of(bo, struct radeon_bo, tbo);
radeon_bo_check_tiling(rbo, 0, 0); radeon_bo_check_tiling(rbo, 0, 0);
} }
...@@ -59,18 +59,16 @@ static inline unsigned radeon_mem_type_to_domain(u32 mem_type) ...@@ -59,18 +59,16 @@ static inline unsigned radeon_mem_type_to_domain(u32 mem_type)
* *
* Returns: * Returns:
* -EBUSY: buffer is busy and @no_wait is true * -EBUSY: buffer is busy and @no_wait is true
* -ERESTART: A wait for the buffer to become unreserved was interrupted by * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by
* a signal. Release all buffer reservations and return to user-space. * a signal. Release all buffer reservations and return to user-space.
*/ */
static inline int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait) static inline int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait)
{ {
int r; int r;
retry:
r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0); r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0);
if (unlikely(r != 0)) { if (unlikely(r != 0)) {
if (r == -ERESTART) if (r != -ERESTARTSYS)
goto retry;
dev_err(bo->rdev->dev, "%p reserve failed\n", bo); dev_err(bo->rdev->dev, "%p reserve failed\n", bo);
return r; return r;
} }
...@@ -125,11 +123,9 @@ static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, ...@@ -125,11 +123,9 @@ static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type,
{ {
int r; int r;
retry:
r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0); r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0);
if (unlikely(r != 0)) { if (unlikely(r != 0)) {
if (r == -ERESTART) if (r != -ERESTARTSYS)
goto retry;
dev_err(bo->rdev->dev, "%p reserve failed for wait\n", bo); dev_err(bo->rdev->dev, "%p reserve failed for wait\n", bo);
return r; return r;
} }
...@@ -140,8 +136,6 @@ static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, ...@@ -140,8 +136,6 @@ static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type,
r = ttm_bo_wait(&bo->tbo, true, true, no_wait); r = ttm_bo_wait(&bo->tbo, true, true, no_wait);
spin_unlock(&bo->tbo.lock); spin_unlock(&bo->tbo.lock);
ttm_bo_unreserve(&bo->tbo); ttm_bo_unreserve(&bo->tbo);
if (unlikely(r == -ERESTART))
goto retry;
return r; return r;
} }
......
...@@ -44,8 +44,11 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data) ...@@ -44,8 +44,11 @@ static int radeon_debugfs_pm_info(struct seq_file *m, void *data)
struct drm_device *dev = node->minor->dev; struct drm_device *dev = node->minor->dev;
struct radeon_device *rdev = dev->dev_private; struct radeon_device *rdev = dev->dev_private;
seq_printf(m, "engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev)); seq_printf(m, "default engine clock: %u0 kHz\n", rdev->clock.default_sclk);
seq_printf(m, "memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev)); seq_printf(m, "current engine clock: %u0 kHz\n", radeon_get_engine_clock(rdev));
seq_printf(m, "default memory clock: %u0 kHz\n", rdev->clock.default_mclk);
if (rdev->asic->get_memory_clock)
seq_printf(m, "current memory clock: %u0 kHz\n", radeon_get_memory_clock(rdev));
return 0; return 0;
} }
......
...@@ -200,7 +200,19 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, ...@@ -200,7 +200,19 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
static void radeon_evict_flags(struct ttm_buffer_object *bo, static void radeon_evict_flags(struct ttm_buffer_object *bo,
struct ttm_placement *placement) struct ttm_placement *placement)
{ {
struct radeon_bo *rbo = container_of(bo, struct radeon_bo, tbo); struct radeon_bo *rbo;
static u32 placements = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
if (!radeon_ttm_bo_is_radeon_bo(bo)) {
placement->fpfn = 0;
placement->lpfn = 0;
placement->placement = &placements;
placement->busy_placement = &placements;
placement->num_placement = 1;
placement->num_busy_placement = 1;
return;
}
rbo = container_of(bo, struct radeon_bo, tbo);
switch (bo->mem.mem_type) { switch (bo->mem.mem_type) {
case TTM_PL_VRAM: case TTM_PL_VRAM:
radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT); radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT);
......
...@@ -497,6 +497,8 @@ int rs400_init(struct radeon_device *rdev) ...@@ -497,6 +497,8 @@ int rs400_init(struct radeon_device *rdev)
/* Initialize clocks */ /* Initialize clocks */
radeon_get_clock_info(rdev->ddev); radeon_get_clock_info(rdev->ddev);
/* Initialize power management */
radeon_pm_init(rdev);
/* Get vram informations */ /* Get vram informations */
rs400_vram_info(rdev); rs400_vram_info(rdev);
/* Initialize memory controller (also test AGP) */ /* Initialize memory controller (also test AGP) */
......
...@@ -892,6 +892,14 @@ static int rv770_startup(struct radeon_device *rdev) ...@@ -892,6 +892,14 @@ static int rv770_startup(struct radeon_device *rdev)
} }
rv770_gpu_init(rdev); rv770_gpu_init(rdev);
if (!rdev->r600_blit.shader_obj) {
r = r600_blit_init(rdev);
if (r) {
DRM_ERROR("radeon: failed blitter (%d).\n", r);
return r;
}
}
r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false);
if (unlikely(r != 0)) if (unlikely(r != 0))
return r; return r;
...@@ -1051,12 +1059,6 @@ int rv770_init(struct radeon_device *rdev) ...@@ -1051,12 +1059,6 @@ int rv770_init(struct radeon_device *rdev)
if (r) if (r)
return r; return r;
r = r600_blit_init(rdev);
if (r) {
DRM_ERROR("radeon: failed blitter (%d).\n", r);
return r;
}
rdev->accel_working = true; rdev->accel_working = true;
r = rv770_startup(rdev); r = rv770_startup(rdev);
if (r) { if (r) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment