Skip to content

Commit

Permalink
Merge remote branch 'korg/drm-radeon-next' of into drm-linus
Browse files Browse the repository at this point in the history
This merges some TTM overhauls to allow us to do better object placement
for certain radeon GPUs that need scanout+cursor within range of each other,
along with an API change to not return ERESTART to userspace, but to use
ERESTARTSYS properly internally and have it convert to EINTR and catch that
correctly. Also lots of radeon fixes across the board.
  • Loading branch information
Dave Airlie committed Dec 10, 2009
2 parents 0b5e8db + fb53f86 commit 115a5c2
Show file tree
Hide file tree
Showing 32 changed files with 849 additions and 512 deletions.
3 changes: 3 additions & 0 deletions drivers/gpu/drm/drm_crtc_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1020,6 +1020,9 @@ bool drm_helper_initial_config(struct drm_device *dev)
{
int count = 0;

/* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(dev);

drm_fb_helper_parse_command_line(dev);

count = drm_helper_probe_connector_modes(dev,
Expand Down
108 changes: 108 additions & 0 deletions drivers/gpu/drm/drm_mm.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,44 @@ struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node,
}
EXPORT_SYMBOL(drm_mm_get_block_generic);

struct drm_mm_node *drm_mm_get_block_range_generic(struct drm_mm_node *node,
unsigned long size,
unsigned alignment,
unsigned long start,
unsigned long end,
int atomic)
{
struct drm_mm_node *align_splitoff = NULL;
unsigned tmp = 0;
unsigned wasted = 0;

if (node->start < start)
wasted += start - node->start;
if (alignment)
tmp = ((node->start + wasted) % alignment);

if (tmp)
wasted += alignment - tmp;
if (wasted) {
align_splitoff = drm_mm_split_at_start(node, wasted, atomic);
if (unlikely(align_splitoff == NULL))
return NULL;
}

if (node->size == size) {
list_del_init(&node->fl_entry);
node->free = 0;
} else {
node = drm_mm_split_at_start(node, size, atomic);
}

if (align_splitoff)
drm_mm_put_block(align_splitoff);

return node;
}
EXPORT_SYMBOL(drm_mm_get_block_range_generic);

/*
* Put a block. Merge with the previous and / or next block if they are free.
* Otherwise add to the free stack.
Expand Down Expand Up @@ -331,6 +369,56 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm,
}
EXPORT_SYMBOL(drm_mm_search_free);

struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm,
unsigned long size,
unsigned alignment,
unsigned long start,
unsigned long end,
int best_match)
{
struct list_head *list;
const struct list_head *free_stack = &mm->fl_entry;
struct drm_mm_node *entry;
struct drm_mm_node *best;
unsigned long best_size;
unsigned wasted;

best = NULL;
best_size = ~0UL;

list_for_each(list, free_stack) {
entry = list_entry(list, struct drm_mm_node, fl_entry);
wasted = 0;

if (entry->size < size)
continue;

if (entry->start > end || (entry->start+entry->size) < start)
continue;

if (entry->start < start)
wasted += start - entry->start;

if (alignment) {
register unsigned tmp = (entry->start + wasted) % alignment;
if (tmp)
wasted += alignment - tmp;
}

if (entry->size >= size + wasted) {
if (!best_match)
return entry;
if (size < best_size) {
best = entry;
best_size = entry->size;
}
}
}

return best;
}
EXPORT_SYMBOL(drm_mm_search_free_in_range);

int drm_mm_clean(struct drm_mm * mm)
{
struct list_head *head = &mm->ml_entry;
Expand Down Expand Up @@ -381,6 +469,26 @@ void drm_mm_takedown(struct drm_mm * mm)
}
EXPORT_SYMBOL(drm_mm_takedown);

void drm_mm_debug_table(struct drm_mm *mm, const char *prefix)
{
struct drm_mm_node *entry;
int total_used = 0, total_free = 0, total = 0;

list_for_each_entry(entry, &mm->ml_entry, ml_entry) {
printk(KERN_DEBUG "%s 0x%08lx-0x%08lx: %8ld: %s\n",
prefix, entry->start, entry->start + entry->size,
entry->size, entry->free ? "free" : "used");
total += entry->size;
if (entry->free)
total_free += entry->size;
else
total_used += entry->size;
}
printk(KERN_DEBUG "%s total: %d, used %d free %d\n", prefix, total,
total_used, total_free);
}
EXPORT_SYMBOL(drm_mm_debug_table);

#if defined(CONFIG_DEBUG_FS)
int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm)
{
Expand Down
19 changes: 15 additions & 4 deletions drivers/gpu/drm/radeon/atombios_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -499,8 +499,18 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
else
pll = &rdev->clock.p2pll;

radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
&ref_div, &post_div, pll_flags);
if (ASIC_IS_AVIVO(rdev)) {
if (radeon_new_pll)
radeon_compute_pll_avivo(pll, adjusted_clock, &pll_clock,
&fb_div, &frac_fb_div,
&ref_div, &post_div, pll_flags);
else
radeon_compute_pll(pll, adjusted_clock, &pll_clock,
&fb_div, &frac_fb_div,
&ref_div, &post_div, pll_flags);
} else
radeon_compute_pll(pll, adjusted_clock, &pll_clock, &fb_div, &frac_fb_div,
&ref_div, &post_div, pll_flags);

index = GetIndexIntoMasterTable(COMMAND, SetPixelClock);
atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev,
Expand Down Expand Up @@ -599,8 +609,6 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
}
radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
radeon_bo_unreserve(rbo);
if (tiling_flags & RADEON_TILING_MACRO)
fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;

switch (crtc->fb->bits_per_pixel) {
case 8:
Expand Down Expand Up @@ -630,6 +638,9 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
return -EINVAL;
}

if (tiling_flags & RADEON_TILING_MACRO)
fb_format |= AVIVO_D1GRPH_MACRO_ADDRESS_MODE;

if (tiling_flags & RADEON_TILING_MICRO)
fb_format |= AVIVO_D1GRPH_TILED;

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/radeon/r100.c
Original file line number Diff line number Diff line change
Expand Up @@ -3299,6 +3299,8 @@ int r100_resume(struct radeon_device *rdev)
radeon_combios_asic_init(rdev->ddev);
/* Resume clock after posting */
r100_clock_startup(rdev);
/* Initialize surface registers */
radeon_surface_init(rdev);
return r100_startup(rdev);
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/radeon/r300.c
Original file line number Diff line number Diff line change
Expand Up @@ -1250,6 +1250,8 @@ int r300_resume(struct radeon_device *rdev)
radeon_combios_asic_init(rdev->ddev);
/* Resume clock after posting */
r300_clock_startup(rdev);
/* Initialize surface registers */
radeon_surface_init(rdev);
return r300_startup(rdev);
}

Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/radeon/r420.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ int r420_resume(struct radeon_device *rdev)
}
/* Resume clock after posting */
r420_clock_resume(rdev);

/* Initialize surface registers */
radeon_surface_init(rdev);
return r420_startup(rdev);
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/radeon/r520.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ int r520_resume(struct radeon_device *rdev)
atom_asic_init(rdev->mode_info.atom_context);
/* Resume clock after posting */
rv515_clock_startup(rdev);
/* Initialize surface registers */
radeon_surface_init(rdev);
return r520_startup(rdev);
}

Expand Down
24 changes: 12 additions & 12 deletions drivers/gpu/drm/radeon/r600.c
Original file line number Diff line number Diff line change
Expand Up @@ -1845,6 +1845,14 @@ int r600_startup(struct radeon_device *rdev)
{
int r;

if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
r = r600_init_microcode(rdev);
if (r) {
DRM_ERROR("Failed to load firmware!\n");
return r;
}
}

r600_mc_program(rdev);
if (rdev->flags & RADEON_IS_AGP) {
r600_agp_enable(rdev);
Expand Down Expand Up @@ -2026,25 +2034,17 @@ int r600_init(struct radeon_device *rdev)
rdev->ih.ring_obj = NULL;
r600_ih_ring_init(rdev, 64 * 1024);

if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
r = r600_init_microcode(rdev);
if (r) {
DRM_ERROR("Failed to load firmware!\n");
return r;
}
}

r = r600_pcie_gart_init(rdev);
if (r)
return r;

rdev->accel_working = true;
r = r600_blit_init(rdev);
if (r) {
DRM_ERROR("radeon: failled blitter (%d).\n", r);
DRM_ERROR("radeon: failed blitter (%d).\n", r);
return r;
}

rdev->accel_working = true;
r = r600_startup(rdev);
if (r) {
r600_suspend(rdev);
Expand All @@ -2056,12 +2056,12 @@ int r600_init(struct radeon_device *rdev)
if (rdev->accel_working) {
r = radeon_ib_pool_init(rdev);
if (r) {
DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r);
DRM_ERROR("radeon: failed initializing IB pool (%d).\n", r);
rdev->accel_working = false;
}
r = r600_ib_test(rdev);
if (r) {
DRM_ERROR("radeon: failled testing IB (%d).\n", r);
DRM_ERROR("radeon: failed testing IB (%d).\n", r);
rdev->accel_working = false;
}
}
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/radeon/radeon.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ extern int radeon_benchmarking;
extern int radeon_testing;
extern int radeon_connector_table;
extern int radeon_tv;
extern int radeon_new_pll;

/*
* Copy from radeon_drv.h so we don't have to include both and have conflicting
Expand Down Expand Up @@ -208,6 +209,8 @@ struct radeon_bo {
/* Protected by gem.mutex */
struct list_head list;
/* Protected by tbo.reserved */
u32 placements[3];
struct ttm_placement placement;
struct ttm_buffer_object tbo;
struct ttm_bo_kmap_obj kmap;
unsigned pin_count;
Expand Down Expand Up @@ -1012,6 +1015,7 @@ extern void radeon_surface_init(struct radeon_device *rdev);
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_atom_set_clock_gating(struct radeon_device *rdev, int enable);
extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain);

/* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
struct r100_mc_save {
Expand Down
Loading

0 comments on commit 115a5c2

Please sign in to comment.