aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c11
-rw-r--r--drivers/gpu/drm/radeon/r100.c79
-rw-r--r--drivers/gpu/drm/radeon/r300.c51
-rw-r--r--drivers/gpu/drm/radeon/r300_reg.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon.h32
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h19
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c12
-rw-r--r--drivers/gpu/drm/radeon/radeon_gem.c41
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c15
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c130
-rw-r--r--drivers/gpu/drm/radeon/radeon_ttm.c2
13 files changed, 383 insertions, 17 deletions
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c
index e64a199b5ee1..eac26cdb5dae 100644
--- a/drivers/gpu/drm/radeon/atombios_crtc.c
+++ b/drivers/gpu/drm/radeon/atombios_crtc.c
@@ -327,7 +327,7 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
327 struct drm_gem_object *obj; 327 struct drm_gem_object *obj;
328 struct drm_radeon_gem_object *obj_priv; 328 struct drm_radeon_gem_object *obj_priv;
329 uint64_t fb_location; 329 uint64_t fb_location;
330 uint32_t fb_format, fb_pitch_pixels; 330 uint32_t fb_format, fb_pitch_pixels, tiling_flags;
331 331
332 if (!crtc->fb) 332 if (!crtc->fb)
333 return -EINVAL; 333 return -EINVAL;
@@ -364,7 +364,14 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
364 return -EINVAL; 364 return -EINVAL;
365 } 365 }
366 366
367 /* TODO tiling */ 367 radeon_object_get_tiling_flags(obj->driver_private,
368 &tiling_flags, NULL);
369 if (tiling_flags & RADEON_TILING_MACRO)
370 fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;
371
372 if (tiling_flags & RADEON_TILING_MICRO)
373 fb_format |= AVIVO_D1GRPH_TILED;
374
368 if (radeon_crtc->crtc_id == 0) 375 if (radeon_crtc->crtc_id == 0)
369 WREG32(AVIVO_D1VGA_CONTROL, 0); 376 WREG32(AVIVO_D1VGA_CONTROL, 0);
370 else 377 else
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 0d05909f03f6..69bd7cb59972 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -909,6 +909,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
909 unsigned idx; 909 unsigned idx;
910 bool onereg; 910 bool onereg;
911 int r; 911 int r;
912 u32 tile_flags = 0;
912 913
913 ib = p->ib->ptr; 914 ib = p->ib->ptr;
914 ib_chunk = &p->chunks[p->chunk_ib_idx]; 915 ib_chunk = &p->chunks[p->chunk_ib_idx];
@@ -942,7 +943,20 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
942 } 943 }
943 tmp = ib_chunk->kdata[idx] & 0x003fffff; 944 tmp = ib_chunk->kdata[idx] & 0x003fffff;
944 tmp += (((u32)reloc->lobj.gpu_offset) >> 10); 945 tmp += (((u32)reloc->lobj.gpu_offset) >> 10);
945 ib[idx] = (ib_chunk->kdata[idx] & 0xffc00000) | tmp; 946
947 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
948 tile_flags |= RADEON_DST_TILE_MACRO;
949 if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
950 if (reg == RADEON_SRC_PITCH_OFFSET) {
951 DRM_ERROR("Cannot src blit from microtiled surface\n");
952 r100_cs_dump_packet(p, pkt);
953 return -EINVAL;
954 }
955 tile_flags |= RADEON_DST_TILE_MICRO;
956 }
957
958 tmp |= tile_flags;
959 ib[idx] = (ib_chunk->kdata[idx] & 0x3fc00000) | tmp;
946 break; 960 break;
947 case RADEON_RB3D_DEPTHOFFSET: 961 case RADEON_RB3D_DEPTHOFFSET:
948 case RADEON_RB3D_COLOROFFSET: 962 case RADEON_RB3D_COLOROFFSET:
@@ -987,6 +1001,25 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
987 } 1001 }
988 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); 1002 ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
989 break; 1003 break;
1004 case R300_RB3D_COLORPITCH0:
1005 case RADEON_RB3D_COLORPITCH:
1006 r = r100_cs_packet_next_reloc(p, &reloc);
1007 if (r) {
1008 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1009 idx, reg);
1010 r100_cs_dump_packet(p, pkt);
1011 return r;
1012 }
1013
1014 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
1015 tile_flags |= RADEON_COLOR_TILE_ENABLE;
1016 if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
1017 tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
1018
1019 tmp = ib_chunk->kdata[idx] & ~(0x7 << 16);
1020 tmp |= tile_flags;
1021 ib[idx] = tmp;
1022 break;
990 default: 1023 default:
991 /* FIXME: we don't want to allow anyothers packet */ 1024 /* FIXME: we don't want to allow anyothers packet */
992 break; 1025 break;
@@ -1707,3 +1740,47 @@ int r100_debugfs_mc_info_init(struct radeon_device *rdev)
1707 return 0; 1740 return 0;
1708#endif 1741#endif
1709} 1742}
1743
1744int r100_set_surface_reg(struct radeon_device *rdev, int reg,
1745 uint32_t tiling_flags, uint32_t pitch,
1746 uint32_t offset, uint32_t obj_size)
1747{
1748 int surf_index = reg * 16;
1749 int flags = 0;
1750
1751 /* r100/r200 divide by 16 */
1752 if (rdev->family < CHIP_R300)
1753 flags = pitch / 16;
1754 else
1755 flags = pitch / 8;
1756
1757 if (rdev->family <= CHIP_RS200) {
1758 if ((tiling_flags & (RADEON_TILING_MACRO|RADEON_TILING_MICRO))
1759 == (RADEON_TILING_MACRO|RADEON_TILING_MICRO))
1760 flags |= RADEON_SURF_TILE_COLOR_BOTH;
1761 if (tiling_flags & RADEON_TILING_MACRO)
1762 flags |= RADEON_SURF_TILE_COLOR_MACRO;
1763 } else if (rdev->family <= CHIP_RV280) {
1764 if (tiling_flags & (RADEON_TILING_MACRO))
1765 flags |= R200_SURF_TILE_COLOR_MACRO;
1766 if (tiling_flags & RADEON_TILING_MICRO)
1767 flags |= R200_SURF_TILE_COLOR_MICRO;
1768 } else {
1769 if (tiling_flags & RADEON_TILING_MACRO)
1770 flags |= R300_SURF_TILE_MACRO;
1771 if (tiling_flags & RADEON_TILING_MICRO)
1772 flags |= R300_SURF_TILE_MICRO;
1773 }
1774
1775 DRM_DEBUG("writing surface %d %d %x %x\n", reg, flags, offset, offset+obj_size-1);
1776 WREG32(RADEON_SURFACE0_INFO + surf_index, flags);
1777 WREG32(RADEON_SURFACE0_LOWER_BOUND + surf_index, offset);
1778 WREG32(RADEON_SURFACE0_UPPER_BOUND + surf_index, offset + obj_size - 1);
1779 return 0;
1780}
1781
1782void r100_clear_surface_reg(struct radeon_device *rdev, int reg)
1783{
1784 int surf_index = reg * 16;
1785 WREG32(RADEON_SURFACE0_INFO + surf_index, 0);
1786}
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 0e0e094da503..28e5777658be 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -30,6 +30,7 @@
30#include "drm.h" 30#include "drm.h"
31#include "radeon_reg.h" 31#include "radeon_reg.h"
32#include "radeon.h" 32#include "radeon.h"
33#include "radeon_drm.h"
33 34
34/* r300,r350,rv350,rv370,rv380 depends on : */ 35/* r300,r350,rv350,rv370,rv380 depends on : */
35void r100_hdp_reset(struct radeon_device *rdev); 36void r100_hdp_reset(struct radeon_device *rdev);
@@ -1023,7 +1024,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
1023 struct radeon_cs_reloc *reloc; 1024 struct radeon_cs_reloc *reloc;
1024 struct r300_cs_track *track; 1025 struct r300_cs_track *track;
1025 volatile uint32_t *ib; 1026 volatile uint32_t *ib;
1026 uint32_t tmp; 1027 uint32_t tmp, tile_flags = 0;
1027 unsigned i; 1028 unsigned i;
1028 int r; 1029 int r;
1029 1030
@@ -1052,7 +1053,19 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
1052 } 1053 }
1053 tmp = ib_chunk->kdata[idx] & 0x003fffff; 1054 tmp = ib_chunk->kdata[idx] & 0x003fffff;
1054 tmp += (((u32)reloc->lobj.gpu_offset) >> 10); 1055 tmp += (((u32)reloc->lobj.gpu_offset) >> 10);
1055 ib[idx] = (ib_chunk->kdata[idx] & 0xffc00000) | tmp; 1056
1057 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
1058 tile_flags |= RADEON_DST_TILE_MACRO;
1059 if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
1060 if (reg == RADEON_SRC_PITCH_OFFSET) {
1061 DRM_ERROR("Cannot src blit from microtiled surface\n");
1062 r100_cs_dump_packet(p, pkt);
1063 return -EINVAL;
1064 }
1065 tile_flags |= RADEON_DST_TILE_MICRO;
1066 }
1067 tmp |= tile_flags;
1068 ib[idx] = (ib_chunk->kdata[idx] & 0x3fc00000) | tmp;
1056 break; 1069 break;
1057 case R300_RB3D_COLOROFFSET0: 1070 case R300_RB3D_COLOROFFSET0:
1058 case R300_RB3D_COLOROFFSET1: 1071 case R300_RB3D_COLOROFFSET1:
@@ -1141,6 +1154,23 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
1141 /* RB3D_COLORPITCH1 */ 1154 /* RB3D_COLORPITCH1 */
1142 /* RB3D_COLORPITCH2 */ 1155 /* RB3D_COLORPITCH2 */
1143 /* RB3D_COLORPITCH3 */ 1156 /* RB3D_COLORPITCH3 */
1157 r = r100_cs_packet_next_reloc(p, &reloc);
1158 if (r) {
1159 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1160 idx, reg);
1161 r100_cs_dump_packet(p, pkt);
1162 return r;
1163 }
1164
1165 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
1166 tile_flags |= R300_COLOR_TILE_ENABLE;
1167 if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
1168 tile_flags |= R300_COLOR_MICROTILE_ENABLE;
1169
1170 tmp = ib_chunk->kdata[idx] & ~(0x7 << 16);
1171 tmp |= tile_flags;
1172 ib[idx] = tmp;
1173
1144 i = (reg - 0x4E38) >> 2; 1174 i = (reg - 0x4E38) >> 2;
1145 track->cb[i].pitch = ib_chunk->kdata[idx] & 0x3FFE; 1175 track->cb[i].pitch = ib_chunk->kdata[idx] & 0x3FFE;
1146 switch (((ib_chunk->kdata[idx] >> 21) & 0xF)) { 1176 switch (((ib_chunk->kdata[idx] >> 21) & 0xF)) {
@@ -1196,6 +1226,23 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
1196 break; 1226 break;
1197 case 0x4F24: 1227 case 0x4F24:
1198 /* ZB_DEPTHPITCH */ 1228 /* ZB_DEPTHPITCH */
1229 r = r100_cs_packet_next_reloc(p, &reloc);
1230 if (r) {
1231 DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
1232 idx, reg);
1233 r100_cs_dump_packet(p, pkt);
1234 return r;
1235 }
1236
1237 if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
1238 tile_flags |= R300_DEPTHMACROTILE_ENABLE;
1239 if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
1240 tile_flags |= R300_DEPTHMICROTILE_TILED;;
1241
1242 tmp = ib_chunk->kdata[idx] & ~(0x7 << 16);
1243 tmp |= tile_flags;
1244 ib[idx] = tmp;
1245
1199 track->zb.pitch = ib_chunk->kdata[idx] & 0x3FFC; 1246 track->zb.pitch = ib_chunk->kdata[idx] & 0x3FFC;
1200 break; 1247 break;
1201 case 0x4104: 1248 case 0x4104:
diff --git a/drivers/gpu/drm/radeon/r300_reg.h b/drivers/gpu/drm/radeon/r300_reg.h
index 70f48609515e..4b7afef35a65 100644
--- a/drivers/gpu/drm/radeon/r300_reg.h
+++ b/drivers/gpu/drm/radeon/r300_reg.h
@@ -27,7 +27,9 @@
27#ifndef _R300_REG_H_ 27#ifndef _R300_REG_H_
28#define _R300_REG_H_ 28#define _R300_REG_H_
29 29
30 30#define R300_SURF_TILE_MACRO (1<<16)
31#define R300_SURF_TILE_MICRO (2<<16)
32#define R300_SURF_TILE_BOTH (3<<16)
31 33
32 34
33#define R300_MC_INIT_MISC_LAT_TIMER 0x180 35#define R300_MC_INIT_MISC_LAT_TIMER 0x180
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 7f007185e7f7..af12a2fe3221 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -201,6 +201,14 @@ int radeon_fence_wait_last(struct radeon_device *rdev);
201struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence); 201struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence);
202void radeon_fence_unref(struct radeon_fence **fence); 202void radeon_fence_unref(struct radeon_fence **fence);
203 203
204/*
205 * Tiling registers
206 */
207struct radeon_surface_reg {
208 struct radeon_object *robj;
209};
210
211#define RADEON_GEM_MAX_SURFACES 8
204 212
205/* 213/*
206 * Radeon buffer. 214 * Radeon buffer.
@@ -213,6 +221,7 @@ struct radeon_object_list {
213 uint64_t gpu_offset; 221 uint64_t gpu_offset;
214 unsigned rdomain; 222 unsigned rdomain;
215 unsigned wdomain; 223 unsigned wdomain;
224 uint32_t tiling_flags;
216}; 225};
217 226
218int radeon_object_init(struct radeon_device *rdev); 227int radeon_object_init(struct radeon_device *rdev);
@@ -242,8 +251,15 @@ void radeon_object_list_clean(struct list_head *head);
242int radeon_object_fbdev_mmap(struct radeon_object *robj, 251int radeon_object_fbdev_mmap(struct radeon_object *robj,
243 struct vm_area_struct *vma); 252 struct vm_area_struct *vma);
244unsigned long radeon_object_size(struct radeon_object *robj); 253unsigned long radeon_object_size(struct radeon_object *robj);
245 254void radeon_object_clear_surface_reg(struct radeon_object *robj);
246 255int radeon_object_check_tiling(struct radeon_object *robj, bool has_moved,
256 bool force_drop);
257void radeon_object_set_tiling_flags(struct radeon_object *robj,
258 uint32_t tiling_flags, uint32_t pitch);
259void radeon_object_get_tiling_flags(struct radeon_object *robj, uint32_t *tiling_flags, uint32_t *pitch);
260void radeon_bo_move_notify(struct ttm_buffer_object *bo,
261 struct ttm_mem_reg *mem);
262void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
247/* 263/*
248 * GEM objects. 264 * GEM objects.
249 */ 265 */
@@ -535,6 +551,11 @@ struct radeon_asic {
535 void (*set_memory_clock)(struct radeon_device *rdev, uint32_t mem_clock); 551 void (*set_memory_clock)(struct radeon_device *rdev, uint32_t mem_clock);
536 void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes); 552 void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes);
537 void (*set_clock_gating)(struct radeon_device *rdev, int enable); 553 void (*set_clock_gating)(struct radeon_device *rdev, int enable);
554
555 int (*set_surface_reg)(struct radeon_device *rdev, int reg,
556 uint32_t tiling_flags, uint32_t pitch,
557 uint32_t offset, uint32_t obj_size);
558 int (*clear_surface_reg)(struct radeon_device *rdev, int reg);
538}; 559};
539 560
540union radeon_asic_config { 561union radeon_asic_config {
@@ -568,6 +589,10 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
568int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, 589int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
569 struct drm_file *filp); 590 struct drm_file *filp);
570int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); 591int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
592int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data,
593 struct drm_file *filp);
594int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data,
595 struct drm_file *filp);
571 596
572 597
573/* 598/*
@@ -627,6 +652,7 @@ struct radeon_device {
627 bool shutdown; 652 bool shutdown;
628 bool suspend; 653 bool suspend;
629 bool need_dma32; 654 bool need_dma32;
655 struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES];
630}; 656};
631 657
632int radeon_device_init(struct radeon_device *rdev, 658int radeon_device_init(struct radeon_device *rdev,
@@ -801,5 +827,7 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v)
801#define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e)) 827#define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e))
802#define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->set_pcie_lanes((rdev), (l)) 828#define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->set_pcie_lanes((rdev), (l))
803#define radeon_set_clock_gating(rdev, e) (rdev)->asic->set_clock_gating((rdev), (e)) 829#define radeon_set_clock_gating(rdev, e) (rdev)->asic->set_clock_gating((rdev), (e))
830#define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->set_surface_reg((rdev), (r), (f), (p), (o), (s)))
831#define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r)))
804 832
805#endif 833#endif
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index e2e567395df8..dd903d329406 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -71,6 +71,10 @@ int r100_copy_blit(struct radeon_device *rdev,
71 uint64_t dst_offset, 71 uint64_t dst_offset,
72 unsigned num_pages, 72 unsigned num_pages,
73 struct radeon_fence *fence); 73 struct radeon_fence *fence);
74int r100_set_surface_reg(struct radeon_device *rdev, int reg,
75 uint32_t tiling_flags, uint32_t pitch,
76 uint32_t offset, uint32_t obj_size);
77int r100_clear_surface_reg(struct radeon_device *rdev, int reg);
74 78
75static struct radeon_asic r100_asic = { 79static struct radeon_asic r100_asic = {
76 .init = &r100_init, 80 .init = &r100_init,
@@ -100,6 +104,8 @@ static struct radeon_asic r100_asic = {
100 .set_memory_clock = NULL, 104 .set_memory_clock = NULL,
101 .set_pcie_lanes = NULL, 105 .set_pcie_lanes = NULL,
102 .set_clock_gating = &radeon_legacy_set_clock_gating, 106 .set_clock_gating = &radeon_legacy_set_clock_gating,
107 .set_surface_reg = r100_set_surface_reg,
108 .clear_surface_reg = r100_clear_surface_reg,
103}; 109};
104 110
105 111
@@ -128,6 +134,7 @@ int r300_copy_dma(struct radeon_device *rdev,
128 uint64_t dst_offset, 134 uint64_t dst_offset,
129 unsigned num_pages, 135 unsigned num_pages,
130 struct radeon_fence *fence); 136 struct radeon_fence *fence);
137
131static struct radeon_asic r300_asic = { 138static struct radeon_asic r300_asic = {
132 .init = &r300_init, 139 .init = &r300_init,
133 .errata = &r300_errata, 140 .errata = &r300_errata,
@@ -156,6 +163,8 @@ static struct radeon_asic r300_asic = {
156 .set_memory_clock = NULL, 163 .set_memory_clock = NULL,
157 .set_pcie_lanes = &rv370_set_pcie_lanes, 164 .set_pcie_lanes = &rv370_set_pcie_lanes,
158 .set_clock_gating = &radeon_legacy_set_clock_gating, 165 .set_clock_gating = &radeon_legacy_set_clock_gating,
166 .set_surface_reg = r100_set_surface_reg,
167 .clear_surface_reg = r100_clear_surface_reg,
159}; 168};
160 169
161/* 170/*
@@ -193,6 +202,8 @@ static struct radeon_asic r420_asic = {
193 .set_memory_clock = &radeon_atom_set_memory_clock, 202 .set_memory_clock = &radeon_atom_set_memory_clock,
194 .set_pcie_lanes = &rv370_set_pcie_lanes, 203 .set_pcie_lanes = &rv370_set_pcie_lanes,
195 .set_clock_gating = &radeon_atom_set_clock_gating, 204 .set_clock_gating = &radeon_atom_set_clock_gating,
205 .set_surface_reg = r100_set_surface_reg,
206 .clear_surface_reg = r100_clear_surface_reg,
196}; 207};
197 208
198 209
@@ -237,6 +248,8 @@ static struct radeon_asic rs400_asic = {
237 .set_memory_clock = NULL, 248 .set_memory_clock = NULL,
238 .set_pcie_lanes = NULL, 249 .set_pcie_lanes = NULL,
239 .set_clock_gating = &radeon_legacy_set_clock_gating, 250 .set_clock_gating = &radeon_legacy_set_clock_gating,
251 .set_surface_reg = r100_set_surface_reg,
252 .clear_surface_reg = r100_clear_surface_reg,
240}; 253};
241 254
242 255
@@ -322,6 +335,8 @@ static struct radeon_asic rs690_asic = {
322 .set_memory_clock = &radeon_atom_set_memory_clock, 335 .set_memory_clock = &radeon_atom_set_memory_clock,
323 .set_pcie_lanes = NULL, 336 .set_pcie_lanes = NULL,
324 .set_clock_gating = &radeon_atom_set_clock_gating, 337 .set_clock_gating = &radeon_atom_set_clock_gating,
338 .set_surface_reg = r100_set_surface_reg,
339 .clear_surface_reg = r100_clear_surface_reg,
325}; 340};
326 341
327 342
@@ -367,6 +382,8 @@ static struct radeon_asic rv515_asic = {
367 .set_memory_clock = &radeon_atom_set_memory_clock, 382 .set_memory_clock = &radeon_atom_set_memory_clock,
368 .set_pcie_lanes = &rv370_set_pcie_lanes, 383 .set_pcie_lanes = &rv370_set_pcie_lanes,
369 .set_clock_gating = &radeon_atom_set_clock_gating, 384 .set_clock_gating = &radeon_atom_set_clock_gating,
385 .set_surface_reg = r100_set_surface_reg,
386 .clear_surface_reg = r100_clear_surface_reg,
370}; 387};
371 388
372 389
@@ -405,6 +422,8 @@ static struct radeon_asic r520_asic = {
405 .set_memory_clock = &radeon_atom_set_memory_clock, 422 .set_memory_clock = &radeon_atom_set_memory_clock,
406 .set_pcie_lanes = &rv370_set_pcie_lanes, 423 .set_pcie_lanes = &rv370_set_pcie_lanes,
407 .set_clock_gating = &radeon_atom_set_clock_gating, 424 .set_clock_gating = &radeon_atom_set_clock_gating,
425 .set_surface_reg = r100_set_surface_reg,
426 .clear_surface_reg = r100_clear_surface_reg,
408}; 427};
409 428
410/* 429/*
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index cdef6eb01baf..f23083bbba3f 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -48,6 +48,8 @@ static void radeon_surface_init(struct radeon_device *rdev)
48 i * (RADEON_SURFACE1_INFO - RADEON_SURFACE0_INFO), 48 i * (RADEON_SURFACE1_INFO - RADEON_SURFACE0_INFO),
49 0); 49 0);
50 } 50 }
51 /* enable surfaces */
52 WREG32(RADEON_SURFACE_CNTL, 0);
51 } 53 }
52} 54}
53 55
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c
index 260870a29d83..36d2f5588f20 100644
--- a/drivers/gpu/drm/radeon/radeon_fb.c
+++ b/drivers/gpu/drm/radeon/radeon_fb.c
@@ -471,10 +471,10 @@ static struct notifier_block paniced = {
471 .notifier_call = radeonfb_panic, 471 .notifier_call = radeonfb_panic,
472}; 472};
473 473
474static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp) 474static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled)
475{ 475{
476 int aligned = width; 476 int aligned = width;
477 int align_large = (ASIC_IS_AVIVO(rdev)); 477 int align_large = (ASIC_IS_AVIVO(rdev)) || tiled;
478 int pitch_mask = 0; 478 int pitch_mask = 0;
479 479
480 switch (bpp / 8) { 480 switch (bpp / 8) {
@@ -512,12 +512,13 @@ int radeonfb_create(struct radeon_device *rdev,
512 u64 fb_gpuaddr; 512 u64 fb_gpuaddr;
513 void *fbptr = NULL; 513 void *fbptr = NULL;
514 unsigned long tmp; 514 unsigned long tmp;
515 bool fb_tiled = false; /* useful for testing */
515 516
516 mode_cmd.width = surface_width; 517 mode_cmd.width = surface_width;
517 mode_cmd.height = surface_height; 518 mode_cmd.height = surface_height;
518 mode_cmd.bpp = 32; 519 mode_cmd.bpp = 32;
519 /* need to align pitch with crtc limits */ 520 /* need to align pitch with crtc limits */
520 mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp) * ((mode_cmd.bpp + 1) / 8); 521 mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp, fb_tiled) * ((mode_cmd.bpp + 1) / 8);
521 mode_cmd.depth = 24; 522 mode_cmd.depth = 24;
522 523
523 size = mode_cmd.pitch * mode_cmd.height; 524 size = mode_cmd.pitch * mode_cmd.height;
@@ -535,6 +536,8 @@ int radeonfb_create(struct radeon_device *rdev,
535 } 536 }
536 robj = gobj->driver_private; 537 robj = gobj->driver_private;
537 538
539 if (fb_tiled)
540 radeon_object_set_tiling_flags(robj, RADEON_TILING_MACRO|RADEON_TILING_SURFACE, mode_cmd.pitch);
538 mutex_lock(&rdev->ddev->struct_mutex); 541 mutex_lock(&rdev->ddev->struct_mutex);
539 fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj); 542 fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj);
540 if (fb == NULL) { 543 if (fb == NULL) {
@@ -563,6 +566,9 @@ int radeonfb_create(struct radeon_device *rdev,
563 } 566 }
564 rfbdev = info->par; 567 rfbdev = info->par;
565 568
569 if (fb_tiled)
570 radeon_object_check_tiling(robj, 0, 0);
571
566 ret = radeon_object_kmap(robj, &fbptr); 572 ret = radeon_object_kmap(robj, &fbptr);
567 if (ret) { 573 if (ret) {
568 goto out_unref; 574 goto out_unref;
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c
index eb516034235d..12542087b298 100644
--- a/drivers/gpu/drm/radeon/radeon_gem.c
+++ b/drivers/gpu/drm/radeon/radeon_gem.c
@@ -285,3 +285,44 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
285 mutex_unlock(&dev->struct_mutex); 285 mutex_unlock(&dev->struct_mutex);
286 return r; 286 return r;
287} 287}
288
289int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data,
290 struct drm_file *filp)
291{
292 struct drm_radeon_gem_set_tiling *args = data;
293 struct drm_gem_object *gobj;
294 struct radeon_object *robj;
295 int r = 0;
296
297 DRM_DEBUG("%d \n", args->handle);
298 gobj = drm_gem_object_lookup(dev, filp, args->handle);
299 if (gobj == NULL)
300 return -EINVAL;
301 robj = gobj->driver_private;
302 radeon_object_set_tiling_flags(robj, args->tiling_flags, args->pitch);
303 mutex_lock(&dev->struct_mutex);
304 drm_gem_object_unreference(gobj);
305 mutex_unlock(&dev->struct_mutex);
306 return r;
307}
308
309int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data,
310 struct drm_file *filp)
311{
312 struct drm_radeon_gem_get_tiling *args = data;
313 struct drm_gem_object *gobj;
314 struct radeon_object *robj;
315 int r = 0;
316
317 DRM_DEBUG("\n");
318 gobj = drm_gem_object_lookup(dev, filp, args->handle);
319 if (gobj == NULL)
320 return -EINVAL;
321 robj = gobj->driver_private;
322 radeon_object_get_tiling_flags(robj, &args->tiling_flags,
323 &args->pitch);
324 mutex_lock(&dev->struct_mutex);
325 drm_gem_object_unreference(gobj);
326 mutex_unlock(&dev->struct_mutex);
327 return r;
328}
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 4612a7c146d1..937a2f1cdb46 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -291,5 +291,7 @@ struct drm_ioctl_desc radeon_ioctls_kms[] = {
291 DRM_IOCTL_DEF(DRM_RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH), 291 DRM_IOCTL_DEF(DRM_RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH),
292 DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH), 292 DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH),
293 DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH), 293 DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH),
294 DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH),
295 DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH),
294}; 296};
295int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms); 297int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms);
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
index 14c1a5107fc9..0613790e2a5b 100644
--- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
+++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c
@@ -235,6 +235,7 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
235 uint64_t base; 235 uint64_t base;
236 uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0; 236 uint32_t crtc_offset, crtc_offset_cntl, crtc_tile_x0_y0 = 0;
237 uint32_t crtc_pitch, pitch_pixels; 237 uint32_t crtc_pitch, pitch_pixels;
238 uint32_t tiling_flags;
238 239
239 DRM_DEBUG("\n"); 240 DRM_DEBUG("\n");
240 241
@@ -258,8 +259,12 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
258 (crtc->fb->bits_per_pixel * 8)); 259 (crtc->fb->bits_per_pixel * 8));
259 crtc_pitch |= crtc_pitch << 16; 260 crtc_pitch |= crtc_pitch << 16;
260 261
261 /* TODO tiling */ 262 radeon_object_get_tiling_flags(obj->driver_private,
262 if (0) { 263 &tiling_flags, NULL);
264 if (tiling_flags & RADEON_TILING_MICRO)
265 DRM_ERROR("trying to scanout microtiled buffer\n");
266
267 if (tiling_flags & RADEON_TILING_MACRO) {
263 if (ASIC_IS_R300(rdev)) 268 if (ASIC_IS_R300(rdev))
264 crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN | 269 crtc_offset_cntl |= (R300_CRTC_X_Y_MODE_EN |
265 R300_CRTC_MICRO_TILE_BUFFER_DIS | 270 R300_CRTC_MICRO_TILE_BUFFER_DIS |
@@ -275,15 +280,13 @@ int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
275 crtc_offset_cntl &= ~RADEON_CRTC_TILE_EN; 280 crtc_offset_cntl &= ~RADEON_CRTC_TILE_EN;
276 } 281 }
277 282
278 283 if (tiling_flags & RADEON_TILING_MACRO) {
279 /* TODO more tiling */
280 if (0) {
281 if (ASIC_IS_R300(rdev)) { 284 if (ASIC_IS_R300(rdev)) {
282 crtc_tile_x0_y0 = x | (y << 16); 285 crtc_tile_x0_y0 = x | (y << 16);
283 base &= ~0x7ff; 286 base &= ~0x7ff;
284 } else { 287 } else {
285 int byteshift = crtc->fb->bits_per_pixel >> 4; 288 int byteshift = crtc->fb->bits_per_pixel >> 4;
286 int tile_addr = (((y >> 3) * crtc->fb->width + x) >> (8 - byteshift)) << 11; 289 int tile_addr = (((y >> 3) * pitch_pixels + x) >> (8 - byteshift)) << 11;
287 base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8); 290 base += tile_addr + ((x << byteshift) % 256) + ((y % 8) << 8);
288 crtc_offset_cntl |= (y % 16); 291 crtc_offset_cntl |= (y % 16);
289 } 292 }
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index bac0d06c52ac..d5b1fd562d88 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -44,6 +44,9 @@ struct radeon_object {
44 uint64_t gpu_addr; 44 uint64_t gpu_addr;
45 void *kptr; 45 void *kptr;
46 bool is_iomem; 46 bool is_iomem;
47 uint32_t tiling_flags;
48 uint32_t pitch;
49 int surface_reg;
47}; 50};
48 51
49int radeon_ttm_init(struct radeon_device *rdev); 52int radeon_ttm_init(struct radeon_device *rdev);
@@ -70,6 +73,7 @@ static void radeon_ttm_object_object_destroy(struct ttm_buffer_object *tobj)
70 73
71 robj = container_of(tobj, struct radeon_object, tobj); 74 robj = container_of(tobj, struct radeon_object, tobj);
72 list_del_init(&robj->list); 75 list_del_init(&robj->list);
76 radeon_object_clear_surface_reg(robj);
73 kfree(robj); 77 kfree(robj);
74} 78}
75 79
@@ -141,6 +145,7 @@ int radeon_object_create(struct radeon_device *rdev,
141 } 145 }
142 robj->rdev = rdev; 146 robj->rdev = rdev;
143 robj->gobj = gobj; 147 robj->gobj = gobj;
148 robj->surface_reg = -1;
144 INIT_LIST_HEAD(&robj->list); 149 INIT_LIST_HEAD(&robj->list);
145 150
146 flags = radeon_object_flags_from_domain(domain); 151 flags = radeon_object_flags_from_domain(domain);
@@ -435,6 +440,7 @@ int radeon_object_list_validate(struct list_head *head, void *fence)
435 radeon_object_gpu_addr(robj); 440 radeon_object_gpu_addr(robj);
436 } 441 }
437 lobj->gpu_offset = robj->gpu_addr; 442 lobj->gpu_offset = robj->gpu_addr;
443 lobj->tiling_flags = robj->tiling_flags;
438 if (fence) { 444 if (fence) {
439 old_fence = (struct radeon_fence *)robj->tobj.sync_obj; 445 old_fence = (struct radeon_fence *)robj->tobj.sync_obj;
440 robj->tobj.sync_obj = radeon_fence_ref(fence); 446 robj->tobj.sync_obj = radeon_fence_ref(fence);
@@ -479,3 +485,127 @@ unsigned long radeon_object_size(struct radeon_object *robj)
479{ 485{
480 return robj->tobj.num_pages << PAGE_SHIFT; 486 return robj->tobj.num_pages << PAGE_SHIFT;
481} 487}
488
489int radeon_object_get_surface_reg(struct radeon_object *robj)
490{
491 struct radeon_device *rdev = robj->rdev;
492 struct radeon_surface_reg *reg;
493 struct radeon_object *old_object;
494 int steal;
495 int i;
496
497 if (!robj->tiling_flags)
498 return 0;
499
500 if (robj->surface_reg >= 0) {
501 reg = &rdev->surface_regs[robj->surface_reg];
502 i = robj->surface_reg;
503 goto out;
504 }
505
506 steal = -1;
507 for (i = 0; i < RADEON_GEM_MAX_SURFACES; i++) {
508
509 reg = &rdev->surface_regs[i];
510 if (!reg->robj)
511 break;
512
513 old_object = reg->robj;
514 if (old_object->pin_count == 0)
515 steal = i;
516 }
517
518 /* if we are all out */
519 if (i == RADEON_GEM_MAX_SURFACES) {
520 if (steal == -1)
521 return -ENOMEM;
522 /* find someone with a surface reg and nuke their BO */
523 reg = &rdev->surface_regs[steal];
524 old_object = reg->robj;
525 /* blow away the mapping */
526 DRM_DEBUG("stealing surface reg %d from %p\n", steal, old_object);
527 ttm_bo_unmap_virtual(&old_object->tobj);
528 old_object->surface_reg = -1;
529 i = steal;
530 }
531
532 robj->surface_reg = i;
533 reg->robj = robj;
534
535out:
536 radeon_set_surface_reg(rdev, i, robj->tiling_flags, robj->pitch,
537 robj->tobj.mem.mm_node->start << PAGE_SHIFT,
538 robj->tobj.num_pages << PAGE_SHIFT);
539 return 0;
540}
541
542void radeon_object_clear_surface_reg(struct radeon_object *robj)
543{
544 struct radeon_device *rdev = robj->rdev;
545 struct radeon_surface_reg *reg;
546
547 if (robj->surface_reg == -1)
548 return;
549
550 reg = &rdev->surface_regs[robj->surface_reg];
551 radeon_clear_surface_reg(rdev, robj->surface_reg);
552
553 reg->robj = NULL;
554 robj->surface_reg = -1;
555}
556
557void radeon_object_set_tiling_flags(struct radeon_object *robj,
558 uint32_t tiling_flags, uint32_t pitch)
559{
560 robj->tiling_flags = tiling_flags;
561 robj->pitch = pitch;
562}
563
564void radeon_object_get_tiling_flags(struct radeon_object *robj,
565 uint32_t *tiling_flags,
566 uint32_t *pitch)
567{
568 if (tiling_flags)
569 *tiling_flags = robj->tiling_flags;
570 if (pitch)
571 *pitch = robj->pitch;
572}
573
574int radeon_object_check_tiling(struct radeon_object *robj, bool has_moved,
575 bool force_drop)
576{
577 if (!(robj->tiling_flags & RADEON_TILING_SURFACE))
578 return 0;
579
580 if (force_drop) {
581 radeon_object_clear_surface_reg(robj);
582 return 0;
583 }
584
585 if (robj->tobj.mem.mem_type != TTM_PL_VRAM) {
586 if (!has_moved)
587 return 0;
588
589 if (robj->surface_reg >= 0)
590 radeon_object_clear_surface_reg(robj);
591 return 0;
592 }
593
594 if ((robj->surface_reg >= 0) && !has_moved)
595 return 0;
596
597 return radeon_object_get_surface_reg(robj);
598}
599
600void radeon_bo_move_notify(struct ttm_buffer_object *bo,
601 struct ttm_mem_reg *mem)
602{
603 struct radeon_object *robj = container_of(bo, struct radeon_object, tobj);
604 radeon_object_check_tiling(robj, 0, 1);
605}
606
607void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
608{
609 struct radeon_object *robj = container_of(bo, struct radeon_object, tobj);
610 radeon_object_check_tiling(robj, 0, 0);
611}
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
index 4ca9aa9203d0..37e1cbcce3a9 100644
--- a/drivers/gpu/drm/radeon/radeon_ttm.c
+++ b/drivers/gpu/drm/radeon/radeon_ttm.c
@@ -429,6 +429,8 @@ static struct ttm_bo_driver radeon_bo_driver = {
429 .sync_obj_flush = &radeon_sync_obj_flush, 429 .sync_obj_flush = &radeon_sync_obj_flush,
430 .sync_obj_unref = &radeon_sync_obj_unref, 430 .sync_obj_unref = &radeon_sync_obj_unref,
431 .sync_obj_ref = &radeon_sync_obj_ref, 431 .sync_obj_ref = &radeon_sync_obj_ref,
432 .move_notify = &radeon_bo_move_notify,
433 .fault_reserve_notify = &radeon_bo_fault_reserve_notify,
432}; 434};
433 435
434int radeon_ttm_init(struct radeon_device *rdev) 436int radeon_ttm_init(struct radeon_device *rdev)