diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon.h')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 151 |
1 files changed, 137 insertions, 14 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index c3f24cc5600..b519fb2fecb 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -51,7 +51,7 @@ #include "radeon_mode.h" #include "radeon_reg.h" - +#include "r300.h" /* * Modules parameters. @@ -64,6 +64,7 @@ extern int radeon_agpmode; extern int radeon_vram_limit; extern int radeon_gart_size; extern int radeon_benchmarking; +extern int radeon_testing; extern int radeon_connector_table; /* @@ -113,6 +114,7 @@ enum radeon_family { CHIP_RV770, CHIP_RV730, CHIP_RV710, + CHIP_RS880, CHIP_LAST, }; @@ -201,6 +203,14 @@ int radeon_fence_wait_last(struct radeon_device *rdev); struct radeon_fence *radeon_fence_ref(struct radeon_fence *fence); void radeon_fence_unref(struct radeon_fence **fence); +/* + * Tiling registers + */ +struct radeon_surface_reg { + struct radeon_object *robj; +}; + +#define RADEON_GEM_MAX_SURFACES 8 /* * Radeon buffer. @@ -213,6 +223,7 @@ struct radeon_object_list { uint64_t gpu_offset; unsigned rdomain; unsigned wdomain; + uint32_t tiling_flags; }; int radeon_object_init(struct radeon_device *rdev); @@ -231,6 +242,7 @@ int radeon_object_pin(struct radeon_object *robj, uint32_t domain, uint64_t *gpu_addr); void radeon_object_unpin(struct radeon_object *robj); int radeon_object_wait(struct radeon_object *robj); +int radeon_object_busy_domain(struct radeon_object *robj, uint32_t *cur_placement); int radeon_object_evict_vram(struct radeon_device *rdev); int radeon_object_mmap(struct radeon_object *robj, uint64_t *offset); void radeon_object_force_delete(struct radeon_device *rdev); @@ -242,8 +254,15 @@ void radeon_object_list_clean(struct list_head *head); int radeon_object_fbdev_mmap(struct radeon_object *robj, struct vm_area_struct *vma); unsigned long radeon_object_size(struct radeon_object *robj); - - +void radeon_object_clear_surface_reg(struct radeon_object *robj); +int radeon_object_check_tiling(struct radeon_object *robj, bool has_moved, + bool force_drop); +void radeon_object_set_tiling_flags(struct radeon_object *robj, + uint32_t tiling_flags, uint32_t pitch); +void radeon_object_get_tiling_flags(struct radeon_object *robj, uint32_t *tiling_flags, uint32_t *pitch); +void radeon_bo_move_notify(struct ttm_buffer_object *bo, + struct ttm_mem_reg *mem); +void radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo); /* * GEM objects. */ @@ -315,8 +334,11 @@ struct radeon_mc { unsigned gtt_location; unsigned gtt_size; unsigned vram_location; - unsigned vram_size; + /* for some chips with <= 32MB we need to lie + * about vram size near mc fb location */ + unsigned mc_vram_size; unsigned vram_width; + unsigned real_vram_size; int vram_mtrr; bool vram_is_ddr; }; @@ -474,6 +496,39 @@ struct radeon_wb { uint64_t gpu_addr; }; +/** + * struct radeon_pm - power management datas + * @max_bandwidth: maximum bandwidth the gpu has (MByte/s) + * @igp_sideport_mclk: sideport memory clock Mhz (rs690,rs740,rs780,rs880) + * @igp_system_mclk: system clock Mhz (rs690,rs740,rs780,rs880) + * @igp_ht_link_clk: ht link clock Mhz (rs690,rs740,rs780,rs880) + * @igp_ht_link_width: ht link width in bits (rs690,rs740,rs780,rs880) + * @k8_bandwidth: k8 bandwidth the gpu has (MByte/s) (IGP) + * @sideport_bandwidth: sideport bandwidth the gpu has (MByte/s) (IGP) + * @ht_bandwidth: ht bandwidth the gpu has (MByte/s) (IGP) + * @core_bandwidth: core GPU bandwidth the gpu has (MByte/s) (IGP) + * @sclk: GPU clock Mhz (core bandwith depends of this clock) + * @needed_bandwidth: current bandwidth needs + * + * It keeps track of various data needed to take powermanagement decision. + * Bandwith need is used to determine minimun clock of the GPU and memory. + * Equation between gpu/memory clock and available bandwidth is hw dependent + * (type of memory, bus size, efficiency, ...) + */ +struct radeon_pm { + fixed20_12 max_bandwidth; + fixed20_12 igp_sideport_mclk; + fixed20_12 igp_system_mclk; + fixed20_12 igp_ht_link_clk; + fixed20_12 igp_ht_link_width; + fixed20_12 k8_bandwidth; + fixed20_12 sideport_bandwidth; + fixed20_12 ht_bandwidth; + fixed20_12 core_bandwidth; + fixed20_12 sclk; + fixed20_12 needed_bandwidth; +}; + /* * Benchmarking @@ -482,6 +537,12 @@ void radeon_benchmark(struct radeon_device *rdev); /* + * Testing + */ +void radeon_test_moves(struct radeon_device *rdev); + + +/* * Debugfs */ int radeon_debugfs_add_files(struct radeon_device *rdev, @@ -496,6 +557,7 @@ int r100_debugfs_cp_init(struct radeon_device *rdev); * ASIC specific functions. */ struct radeon_asic { + int (*init)(struct radeon_device *rdev); void (*errata)(struct radeon_device *rdev); void (*vram_info)(struct radeon_device *rdev); int (*gpu_reset)(struct radeon_device *rdev); @@ -513,6 +575,7 @@ struct radeon_asic { void (*ring_start)(struct radeon_device *rdev); int (*irq_set)(struct radeon_device *rdev); int (*irq_process)(struct radeon_device *rdev); + u32 (*get_vblank_counter)(struct radeon_device *rdev, int crtc); void (*fence_ring_emit)(struct radeon_device *rdev, struct radeon_fence *fence); int (*cs_parse)(struct radeon_cs_parser *p); int (*copy_blit)(struct radeon_device *rdev, @@ -534,6 +597,15 @@ struct radeon_asic { void (*set_memory_clock)(struct radeon_device *rdev, uint32_t mem_clock); void (*set_pcie_lanes)(struct radeon_device *rdev, int lanes); void (*set_clock_gating)(struct radeon_device *rdev, int enable); + int (*set_surface_reg)(struct radeon_device *rdev, int reg, + uint32_t tiling_flags, uint32_t pitch, + uint32_t offset, uint32_t obj_size); + int (*clear_surface_reg)(struct radeon_device *rdev, int reg); + void (*bandwidth_update)(struct radeon_device *rdev); +}; + +union radeon_asic_config { + struct r300_asic r300; }; @@ -561,6 +633,10 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data, int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); +int radeon_gem_set_tiling_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp); +int radeon_gem_get_tiling_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp); /* @@ -573,11 +649,13 @@ struct radeon_device { struct drm_device *ddev; struct pci_dev *pdev; /* ASIC */ + union radeon_asic_config config; enum radeon_family family; unsigned long flags; int usec_timeout; enum radeon_pll_errata pll_errata; int num_gb_pipes; + int num_z_pipes; int disp_priority; /* BIOS */ uint8_t *bios; @@ -588,17 +666,14 @@ struct radeon_device { struct radeon_object *fbdev_robj; struct radeon_framebuffer *fbdev_rfb; /* Register mmio */ - unsigned long rmmio_base; - unsigned long rmmio_size; + resource_size_t rmmio_base; + resource_size_t rmmio_size; void *rmmio; - radeon_rreg_t mm_rreg; - radeon_wreg_t mm_wreg; radeon_rreg_t mc_rreg; radeon_wreg_t mc_wreg; radeon_rreg_t pll_rreg; radeon_wreg_t pll_wreg; - radeon_rreg_t pcie_rreg; - radeon_wreg_t pcie_wreg; + uint32_t pcie_reg_mask; radeon_rreg_t pciep_rreg; radeon_wreg_t pciep_wreg; struct radeon_clock clock; @@ -613,11 +688,14 @@ struct radeon_device { struct radeon_irq irq; struct radeon_asic *asic; struct radeon_gem gem; + struct radeon_pm pm; struct mutex cs_mutex; struct radeon_wb wb; bool gpu_lockup; bool shutdown; bool suspend; + bool need_dma32; + struct radeon_surface_reg surface_regs[RADEON_GEM_MAX_SURFACES]; }; int radeon_device_init(struct radeon_device *rdev, @@ -627,22 +705,42 @@ int radeon_device_init(struct radeon_device *rdev, void radeon_device_fini(struct radeon_device *rdev); int radeon_gpu_wait_for_idle(struct radeon_device *rdev); +static inline uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) +{ + if (reg < 0x10000) + return readl(((void __iomem *)rdev->rmmio) + reg); + else { + writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); + return readl(((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); + } +} + +static inline void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) +{ + if (reg < 0x10000) + writel(v, ((void __iomem *)rdev->rmmio) + reg); + else { + writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); + writel(v, ((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); + } +} + /* * Registers read & write functions. */ #define RREG8(reg) readb(((void __iomem *)rdev->rmmio) + (reg)) #define WREG8(reg, v) writeb(v, ((void __iomem *)rdev->rmmio) + (reg)) -#define RREG32(reg) rdev->mm_rreg(rdev, (reg)) -#define WREG32(reg, v) rdev->mm_wreg(rdev, (reg), (v)) +#define RREG32(reg) r100_mm_rreg(rdev, (reg)) +#define WREG32(reg, v) r100_mm_wreg(rdev, (reg), (v)) #define REG_SET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) #define REG_GET(FIELD, v) (((v) << FIELD##_SHIFT) & FIELD##_MASK) #define RREG32_PLL(reg) rdev->pll_rreg(rdev, (reg)) #define WREG32_PLL(reg, v) rdev->pll_wreg(rdev, (reg), (v)) #define RREG32_MC(reg) rdev->mc_rreg(rdev, (reg)) #define WREG32_MC(reg, v) rdev->mc_wreg(rdev, (reg), (v)) -#define RREG32_PCIE(reg) rdev->pcie_rreg(rdev, (reg)) -#define WREG32_PCIE(reg, v) rdev->pcie_wreg(rdev, (reg), (v)) +#define RREG32_PCIE(reg) rv370_pcie_rreg(rdev, (reg)) +#define WREG32_PCIE(reg, v) rv370_pcie_wreg(rdev, (reg), (v)) #define WREG32_P(reg, val, mask) \ do { \ uint32_t tmp_ = RREG32(reg); \ @@ -658,12 +756,32 @@ int radeon_gpu_wait_for_idle(struct radeon_device *rdev); WREG32_PLL(reg, tmp_); \ } while (0) +/* + * Indirect registers accessor + */ +static inline uint32_t rv370_pcie_rreg(struct radeon_device *rdev, uint32_t reg) +{ + uint32_t r; + + WREG32(RADEON_PCIE_INDEX, ((reg) & rdev->pcie_reg_mask)); + r = RREG32(RADEON_PCIE_DATA); + return r; +} + +static inline void rv370_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) +{ + WREG32(RADEON_PCIE_INDEX, ((reg) & rdev->pcie_reg_mask)); + WREG32(RADEON_PCIE_DATA, (v)); +} + void r100_pll_errata_after_index(struct radeon_device *rdev); /* * ASICs helpers. */ +#define ASIC_IS_RN50(rdev) ((rdev->pdev->device == 0x515e) || \ + (rdev->pdev->device == 0x5969)) #define ASIC_IS_RV100(rdev) ((rdev->family == CHIP_RV100) || \ (rdev->family == CHIP_RV200) || \ (rdev->family == CHIP_RS100) || \ @@ -763,6 +881,7 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) /* * ASICs macro. */ +#define radeon_init(rdev) (rdev)->asic->init((rdev)) #define radeon_cs_parse(p) rdev->asic->cs_parse((p)) #define radeon_errata(rdev) (rdev)->asic->errata((rdev)) #define radeon_vram_info(rdev) (rdev)->asic->vram_info((rdev)) @@ -781,6 +900,7 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) #define radeon_ring_start(rdev) (rdev)->asic->ring_start((rdev)) #define radeon_irq_set(rdev) (rdev)->asic->irq_set((rdev)) #define radeon_irq_process(rdev) (rdev)->asic->irq_process((rdev)) +#define radeon_get_vblank_counter(rdev, crtc) (rdev)->asic->get_vblank_counter((rdev), (crtc)) #define radeon_fence_ring_emit(rdev, fence) (rdev)->asic->fence_ring_emit((rdev), (fence)) #define radeon_copy_blit(rdev, s, d, np, f) (rdev)->asic->copy_blit((rdev), (s), (d), (np), (f)) #define radeon_copy_dma(rdev, s, d, np, f) (rdev)->asic->copy_dma((rdev), (s), (d), (np), (f)) @@ -789,5 +909,8 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) #define radeon_set_memory_clock(rdev, e) (rdev)->asic->set_engine_clock((rdev), (e)) #define radeon_set_pcie_lanes(rdev, l) (rdev)->asic->set_pcie_lanes((rdev), (l)) #define radeon_set_clock_gating(rdev, e) (rdev)->asic->set_clock_gating((rdev), (e)) +#define radeon_set_surface_reg(rdev, r, f, p, o, s) ((rdev)->asic->set_surface_reg((rdev), (r), (f), (p), (o), (s))) +#define radeon_clear_surface_reg(rdev, r) ((rdev)->asic->clear_surface_reg((rdev), (r))) +#define radeon_bandwidth_update(rdev) (rdev)->asic->bandwidth_update((rdev)) #endif |