From: <jb...@ke...> - 2008-08-16 19:09:47
|
linux-core/i915_drv.c | 31 ---------------------- linux-core/i915_gem.c | 6 ---- linux-core/i915_ioc32.c | 61 --------------------------------------------- linux-core/intel_display.c | 27 ++++++++----------- linux-core/intel_fb.c | 6 ++++ shared-core/i915_drv.h | 35 ++----------------------- shared-core/i915_init.c | 3 -- shared-core/i915_irq.c | 3 -- 8 files changed, 23 insertions(+), 149 deletions(-) New commits: commit a2adc696569de830c7a95722dd111bff706a0bbc Author: Jesse Barnes <jb...@vi...> Date: Sat Aug 16 12:09:24 2008 -0700 i915: finish removing TTM bits Makes it build again. diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c index 2e67eb7..3885947 100644 --- a/linux-core/i915_drv.c +++ b/linux-core/i915_drv.c @@ -48,31 +48,6 @@ module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400); unsigned int i915_rightof = 1; module_param_named(i915_rightof, i915_rightof, int, 0400); -#if defined(I915_HAVE_FENCE) && defined(I915_TTM) -extern struct drm_fence_driver i915_fence_driver; -#endif - -#if defined(I915_HAVE_BUFFER) && defined(I915_TTM) - -static uint32_t i915_mem_prios[] = {DRM_BO_MEM_VRAM, DRM_BO_MEM_TT, DRM_BO_MEM_LOCAL}; -static uint32_t i915_busy_prios[] = {DRM_BO_MEM_TT, DRM_BO_MEM_VRAM, DRM_BO_MEM_LOCAL}; - -static struct drm_bo_driver i915_bo_driver = { - .mem_type_prio = i915_mem_prios, - .mem_busy_prio = i915_busy_prios, - .num_mem_type_prio = sizeof(i915_mem_prios)/sizeof(uint32_t), - .num_mem_busy_prio = sizeof(i915_busy_prios)/sizeof(uint32_t), - .create_ttm_backend_entry = i915_create_ttm_backend_entry, - .fence_type = i915_fence_type, - .invalidate_caches = i915_invalidate_caches, - .init_mem_type = i915_init_mem_type, - .evict_flags = i915_evict_flags, - .move = i915_move, - .ttm_cache_flush = i915_flush_ttm, - .command_stream_barrier = NULL, -}; -#endif /* ttm */ - static int i915_suspend(struct drm_device *dev, pm_message_t state) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -175,12 +150,6 @@ static struct drm_driver driver = { .probe = probe, .remove = remove, }, -#if defined(I915_HAVE_FENCE) && defined(I915_TTM) - .fence_driver = &i915_fence_driver, -#endif -#if defined(I915_HAVE_BUFFER) && defined(I915_TTM) - .bo_driver = &i915_bo_driver, -#endif .name = DRIVER_NAME, .desc = DRIVER_DESC, .date = DRIVER_DATE, diff --git a/linux-core/i915_ioc32.c b/linux-core/i915_ioc32.c index 0b8fff1..d2d69a0 100644 --- a/linux-core/i915_ioc32.c +++ b/linux-core/i915_ioc32.c @@ -183,73 +183,12 @@ static int compat_i915_alloc(struct file *file, unsigned int cmd, DRM_IOCTL_I915_ALLOC, (unsigned long) request); } -typedef struct drm_i915_execbuffer32 { - uint64_t ops_list; - uint32_t num_buffers; - struct _drm_i915_batchbuffer32 batch; - drm_context_t context; - struct drm_fence_arg fence_arg; -} drm_i915_execbuffer32_t; - -static int compat_i915_execbuffer(struct file *file, unsigned int cmd, - unsigned long arg) -{ - drm_i915_execbuffer32_t req32; - struct drm_i915_execbuffer __user *request; - int err; - - if (copy_from_user(&req32, (void __user *) arg, sizeof(req32))) - return -EFAULT; - - request = compat_alloc_user_space(sizeof(*request)); - - if (!access_ok(VERIFY_WRITE, request, sizeof(*request)) - || __put_user(req32.ops_list, &request->ops_list) - || __put_user(req32.num_buffers, &request->num_buffers) - || __put_user(req32.context, &request->context) - || __copy_to_user(&request->fence_arg, &req32.fence_arg, - sizeof(req32.fence_arg)) - || __put_user(req32.batch.start, &request->batch.start) - || __put_user(req32.batch.used, &request->batch.used) - || __put_user(req32.batch.DR1, &request->batch.DR1) - || __put_user(req32.batch.DR4, &request->batch.DR4) - || __put_user(req32.batch.num_cliprects, - &request->batch.num_cliprects) - || __put_user((int __user *)(unsigned long)req32.batch.cliprects, - &request->batch.cliprects)) - return -EFAULT; - - err = drm_ioctl(file->f_dentry->d_inode, file, - DRM_IOCTL_I915_EXECBUFFER, (unsigned long)request); - - if (err) - return err; - - if (__get_user(req32.fence_arg.handle, &request->fence_arg.handle) - || __get_user(req32.fence_arg.fence_class, &request->fence_arg.fence_class) - || __get_user(req32.fence_arg.type, &request->fence_arg.type) - || __get_user(req32.fence_arg.flags, &request->fence_arg.flags) - || __get_user(req32.fence_arg.signaled, &request->fence_arg.signaled) - || __get_user(req32.fence_arg.error, &request->fence_arg.error) - || __get_user(req32.fence_arg.sequence, &request->fence_arg.sequence)) - return -EFAULT; - - if (copy_to_user((void __user *)arg, &req32, sizeof(req32))) - return -EFAULT; - - return 0; -} - - drm_ioctl_compat_t *i915_compat_ioctls[] = { [DRM_I915_BATCHBUFFER] = compat_i915_batchbuffer, [DRM_I915_CMDBUFFER] = compat_i915_cmdbuffer, [DRM_I915_GETPARAM] = compat_i915_getparam, [DRM_I915_IRQ_EMIT] = compat_i915_irq_emit, [DRM_I915_ALLOC] = compat_i915_alloc, -#ifdef I915_HAVE_BUFFER - [DRM_I915_EXECBUFFER] = compat_i915_execbuffer, -#endif }; /** diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index a031afd..04062c4 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -42,7 +42,6 @@ #define DRIVER_DATE "20080730" #if defined(__linux__) -#define I915_HAVE_FENCE #define I915_HAVE_BUFFER #endif @@ -62,7 +61,7 @@ * 1.12: TTM relocation optimization */ #define DRIVER_MAJOR 1 -#if defined(I915_HAVE_FENCE) && defined(I915_HAVE_BUFFER) +#if defined(I915_HAVE_BUFFER) #define DRIVER_MINOR 13 #else #define DRIVER_MINOR 6 @@ -176,12 +175,6 @@ struct drm_i915_private { struct drm_mm vram; -#ifdef I915_HAVE_FENCE - uint32_t flush_sequence; - uint32_t flush_flags; - uint32_t flush_pending; - uint32_t saved_flush_status; -#endif #ifdef I915_HAVE_BUFFER void *agp_iomap; unsigned int max_validate_buffers; @@ -556,30 +549,7 @@ extern void i915_mem_release(struct drm_device * dev, extern int i915_save_state(struct drm_device *dev); extern int i915_restore_state(struct drm_device *dev); -#ifdef I915_HAVE_FENCE -/* i915_fence.c */ -extern void i915_fence_handler(struct drm_device *dev); -extern void i915_invalidate_reported_sequence(struct drm_device *dev); - -#endif - -#if defined(I915_HAVE_BUFFER) && defined(I915_TTM) -/* i915_buffer.c */ -extern struct drm_ttm_backend *i915_create_ttm_backend_entry(struct drm_device *dev); -extern int i915_fence_type(struct drm_buffer_object *bo, uint32_t *fclass, - uint32_t *type); -extern int i915_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags); -extern int i915_init_mem_type(struct drm_device *dev, uint32_t type, - struct drm_mem_type_manager *man); -extern uint64_t i915_evict_flags(struct drm_buffer_object *bo); -extern int i915_move(struct drm_buffer_object *bo, int evict, - int no_wait, struct drm_bo_mem_reg *new_mem); -void i915_flush_ttm(struct drm_ttm *ttm); -#endif /* ttm */ #ifdef I915_HAVE_BUFFER -/* i915_execbuf.c */ -int i915_execbuffer(struct drm_device *dev, void *data, - struct drm_file *file_priv); /* i915_gem.c */ int i915_gem_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 7b88cc8..d638392 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -519,8 +519,5 @@ int i915_driver_firstopen(struct drm_device *dev) { if (drm_core_check_feature(dev, DRIVER_MODESET)) return 0; -#if defined(I915_HAVE_BUFFER) && defined(I915_TTM) - drm_bo_driver_init(dev); -#endif return 0; } diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c index 28fa35f..ee83b14 100644 --- a/shared-core/i915_irq.c +++ b/shared-core/i915_irq.c @@ -554,9 +554,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) if (iir & I915_USER_INTERRUPT) { dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev); DRM_WAKEUP(&dev_priv->irq_queue); -#ifdef I915_HAVE_FENCE - i915_fence_handler(dev); -#endif } if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS| commit d313108167a793652a5fe4c1015198e0a9deac4c Merge: 893315d... 2030db7... Author: Jesse Barnes <jb...@vi...> Date: Sat Aug 16 11:45:53 2008 -0700 Merge branch 'modesetting-gem' of ssh://git.freedesktop.org/git/mesa/drm into modesetting-gem commit 893315d49ed678de95cf6ac553efb6093cc7343c Author: Jesse Barnes <jb...@vi...> Date: Sat Aug 16 11:35:10 2008 -0700 i915: set domain properly on fb mapping, flush out changes The user visible ioctl does this, but since we call into GEM internals directly, we have to flush things ourselves. Fixes initial fb console corruption. diff --git a/linux-core/i915_gem.c b/linux-core/i915_gem.c index 64ffa35..6966c84 100644 --- a/linux-core/i915_gem.c +++ b/linux-core/i915_gem.c @@ -33,10 +33,6 @@ #include <linux/swap.h> static int -i915_gem_object_set_domain(struct drm_gem_object *obj, - uint32_t read_domains, - uint32_t write_domain); -static int i915_gem_object_set_domain_range(struct drm_gem_object *obj, uint64_t offset, uint64_t size, @@ -1318,7 +1314,7 @@ i915_gem_clflush_object(struct drm_gem_object *obj) * MI_FLUSH * drm_agp_chipset_flush */ -static int +int i915_gem_object_set_domain(struct drm_gem_object *obj, uint32_t read_domains, uint32_t write_domain) diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c index ce8ac3d..c1391c0 100644 --- a/linux-core/intel_fb.c +++ b/linux-core/intel_fb.c @@ -716,12 +716,18 @@ int intelfb_create(struct drm_device *dev, uint32_t fb_width, uint32_t fb_height obj_priv = fbo->driver_private; mutex_lock(&dev->struct_mutex); + /* Flush everything out, we'll be doing GTT only from now on */ + i915_gem_object_set_domain(fbo, I915_GEM_DOMAIN_GTT, + I915_GEM_DOMAIN_GTT); + ret = i915_gem_object_pin(fbo, PAGE_SIZE); if (ret) { DRM_ERROR("failed to pin fb: %d\n", ret); goto out_unref; } + i915_gem_clflush_object(fbo); + fb = intel_user_framebuffer_create(dev, NULL, &mode_cmd); if (!fb) { DRM_ERROR("failed to allocate fb.\n"); diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h index 087c6d6..a031afd 100644 --- a/shared-core/i915_drv.h +++ b/shared-core/i915_drv.h @@ -627,6 +627,9 @@ int i915_gem_init_ringbuffer(struct drm_device *dev); void i915_gem_cleanup_ringbuffer(struct drm_device *dev); int i915_gem_do_init(struct drm_device *dev, unsigned long start, unsigned long end); +int i915_gem_object_set_domain(struct drm_gem_object *obj, + uint32_t read_domains, + uint32_t write_domain); void i915_gem_retire_work_handler(struct work_struct *work); void i915_gem_clflush_object(struct drm_gem_object *obj); #endif commit 5f9e4a764ac7acf1311388dd693bc4f0e6c0c4e9 Author: Jesse Barnes <jb...@vi...> Date: Wed Aug 13 16:57:42 2008 -0700 i915: update cursor handling to use GEM objects diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index fbe06f7..dfc0b50 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -982,12 +982,12 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct drm_buffer_object *bo; + struct drm_gem_object *bo; + struct drm_i915_gem_object *obj_priv; int pipe = intel_crtc->pipe; uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR; uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; uint32_t temp; - int ret; size_t addr; DRM_DEBUG("\n"); @@ -1010,25 +1010,22 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, return -EINVAL; } - ret = drm_get_buffer_object(dev, &bo, handle); - if (ret) { - return -EINVAL; - } + bo = drm_gem_object_lookup(dev, file_priv, handle); + if (!bo) + return -ENOENT; - if ((bo->mem.flags & DRM_BO_MASK_MEM) != DRM_BO_FLAG_MEM_VRAM) { - DRM_ERROR("buffer needs to be in VRAM\n"); - return -ENOMEM; - } + obj_priv = bo->driver_private; - if (bo->mem.size < width * height * 4) { + if (bo->size < width * height * 4) { DRM_ERROR("buffer is to small\n"); return -ENOMEM; } - if (dev_priv->cursor_needs_physical) - addr = dev_priv->stolen_base + bo->offset; - else - addr = bo->offset; + if (dev_priv->cursor_needs_physical) { + addr = dev->agp->base + obj_priv->gtt_offset; + } else { + addr = obj_priv->gtt_offset; + } intel_crtc->cursor_addr = addr; temp = 0; |
From: <ag...@ke...> - 2008-08-18 07:46:11
|
linux-core/radeon_atombios.c | 52 ++++++ linux-core/radeon_combios.c | 73 +++++++++ linux-core/radeon_connectors.c | 3 linux-core/radeon_display.c | 1 linux-core/radeon_encoders.c | 200 +++++++++++++++++++++++-- linux-core/radeon_gem.c | 2 linux-core/radeon_legacy_encoders.c | 279 ++++++++++++++++++++++++++++++++++-- linux-core/radeon_mode.h | 159 +------------------- shared-core/radeon_cp.c | 6 9 files changed, 594 insertions(+), 181 deletions(-) New commits: commit 232c369a05bbd9db17a0453380229c993cbbc8bd Author: Alex Deucher <ale...@gm...> Date: Sun Aug 17 18:38:41 2008 -0400 radeon: first pass at legacy dac detect - done: primary dac, vga on tvdac - todo: ext dac, tv on tvdac diff --git a/linux-core/radeon_legacy_encoders.c b/linux-core/radeon_legacy_encoders.c index 6452154..a418d1d 100644 --- a/linux-core/radeon_legacy_encoders.c +++ b/linux-core/radeon_legacy_encoders.c @@ -511,11 +511,68 @@ static void radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder, RADEON_WRITE(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); } -static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) +static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_encoder *encoder, + struct drm_connector *connector) { - // FIXME - return connector_status_disconnected; + struct drm_device *dev = encoder->dev; + struct drm_radeon_private *dev_priv = dev->dev_private; + uint32_t vclk_ecp_cntl, crtc_ext_cntl; + uint32_t dac_ext_cntl, dac_cntl, dac_macro_cntl, tmp; + enum drm_connector_status found = connector_status_disconnected; + bool color = true; + + /* save the regs we need */ + vclk_ecp_cntl = RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL); + crtc_ext_cntl = RADEON_READ(RADEON_CRTC_EXT_CNTL); + dac_ext_cntl = RADEON_READ(RADEON_DAC_EXT_CNTL); + dac_cntl = RADEON_READ(RADEON_DAC_CNTL); + dac_macro_cntl = RADEON_READ(RADEON_DAC_MACRO_CNTL); + + tmp = vclk_ecp_cntl & + ~(RADEON_PIXCLK_ALWAYS_ONb | RADEON_PIXCLK_DAC_ALWAYS_ONb); + RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, tmp); + + tmp = crtc_ext_cntl | RADEON_CRTC_CRT_ON; + RADEON_WRITE(RADEON_CRTC_EXT_CNTL, tmp); + + tmp = RADEON_DAC_FORCE_BLANK_OFF_EN | + RADEON_DAC_FORCE_DATA_EN; + + if (color) + tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB; + else + tmp |= RADEON_DAC_FORCE_DATA_SEL_G; + + if (radeon_is_r300(dev_priv)) + tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); + else + tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); + + RADEON_WRITE(RADEON_DAC_EXT_CNTL, tmp); + + tmp = dac_cntl & ~(RADEON_DAC_RANGE_CNTL_MASK | RADEON_DAC_PDWN); + tmp |= RADEON_DAC_RANGE_CNTL_PS2 | RADEON_DAC_CMP_EN; + RADEON_WRITE(RADEON_DAC_CNTL, tmp); + + tmp &= ~(RADEON_DAC_PDWN_R | + RADEON_DAC_PDWN_G | + RADEON_DAC_PDWN_B); + + RADEON_WRITE(RADEON_DAC_MACRO_CNTL, tmp); + + udelay(2000); + + if (RADEON_READ(RADEON_DAC_CNTL) & RADEON_DAC_CMP_OUTPUT) + found = connector_status_connected; + /* restore the regs we used */ + RADEON_WRITE(RADEON_DAC_CNTL, dac_cntl); + RADEON_WRITE(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); + RADEON_WRITE(RADEON_DAC_EXT_CNTL, dac_ext_cntl); + RADEON_WRITE(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl); + RADEON_WRITE_PLL(dev_priv, RADEON_VCLK_ECP_CNTL, vclk_ecp_cntl); + + return found; } static const struct drm_encoder_helper_funcs radeon_legacy_primary_dac_helper_funcs = { @@ -1102,9 +1159,100 @@ static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, } -static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) +static enum drm_connector_status radeon_legacy_tv_dac_detect(struct drm_encoder *encoder, + struct drm_connector *connector) { - // FIXME + struct drm_device *dev = encoder->dev; + struct drm_radeon_private *dev_priv = dev->dev_private; + uint32_t crtc2_gen_cntl, tv_dac_cntl, dac_cntl2, dac_ext_cntl; + uint32_t disp_hw_debug, disp_output_cntl, gpiopad_a, pixclks_cntl, tmp; + enum drm_connector_status found = connector_status_disconnected; + bool color = true; + + // FIXME tv + + /* save the regs we need */ + pixclks_cntl = RADEON_READ_PLL(dev_priv, RADEON_PIXCLKS_CNTL); + gpiopad_a = radeon_is_r300(dev_priv) ? RADEON_READ(RADEON_GPIOPAD_A) : 0; + disp_output_cntl = radeon_is_r300(dev_priv) ? RADEON_READ(RADEON_DISP_OUTPUT_CNTL) : 0; + disp_hw_debug = radeon_is_r300(dev_priv) ? 0 : RADEON_READ(RADEON_DISP_HW_DEBUG); + crtc2_gen_cntl = RADEON_READ(RADEON_CRTC2_GEN_CNTL); + tv_dac_cntl = RADEON_READ(RADEON_TV_DAC_CNTL); + dac_ext_cntl = RADEON_READ(RADEON_DAC_EXT_CNTL); + dac_cntl2 = RADEON_READ(RADEON_DAC_CNTL2); + + tmp = pixclks_cntl & ~(RADEON_PIX2CLK_ALWAYS_ONb + | RADEON_PIX2CLK_DAC_ALWAYS_ONb); + RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, tmp); + + if (radeon_is_r300(dev_priv)) + RADEON_WRITE_P(RADEON_GPIOPAD_A, 1, ~1); + + tmp = crtc2_gen_cntl & ~RADEON_CRTC2_PIX_WIDTH_MASK; + tmp |= RADEON_CRTC2_CRT2_ON | + (2 << RADEON_CRTC2_PIX_WIDTH_SHIFT); + + RADEON_WRITE(RADEON_CRTC2_GEN_CNTL, tmp); + + if (radeon_is_r300(dev_priv)) { + tmp = disp_output_cntl & ~RADEON_DISP_TVDAC_SOURCE_MASK; + tmp |= RADEON_DISP_TVDAC_SOURCE_CRTC2; + RADEON_WRITE(RADEON_DISP_OUTPUT_CNTL, tmp); + } else { + tmp = disp_hw_debug & ~RADEON_CRT2_DISP1_SEL; + RADEON_WRITE(RADEON_DISP_HW_DEBUG, tmp); + } + + tmp = RADEON_TV_DAC_NBLANK | + RADEON_TV_DAC_NHOLD | + RADEON_TV_MONITOR_DETECT_EN | + RADEON_TV_DAC_STD_PS2; + + RADEON_WRITE(RADEON_TV_DAC_CNTL, tmp); + + tmp = RADEON_DAC2_FORCE_BLANK_OFF_EN | + RADEON_DAC2_FORCE_DATA_EN; + + if (color) + tmp |= RADEON_DAC_FORCE_DATA_SEL_RGB; + else + tmp |= RADEON_DAC_FORCE_DATA_SEL_G; + + if (radeon_is_r300(dev_priv)) + tmp |= (0x1b6 << RADEON_DAC_FORCE_DATA_SHIFT); + else + tmp |= (0x180 << RADEON_DAC_FORCE_DATA_SHIFT); + + RADEON_WRITE(RADEON_DAC_EXT_CNTL, tmp); + + tmp = dac_cntl2 | RADEON_DAC2_DAC2_CLK_SEL | RADEON_DAC2_CMP_EN; + RADEON_WRITE(RADEON_DAC_CNTL2, tmp); + + udelay(10000); + + if (radeon_is_r300(dev_priv)) { + if (RADEON_READ(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUT_B) + found = connector_status_connected; + } else { + if (RADEON_READ(RADEON_DAC_CNTL2) & RADEON_DAC2_CMP_OUTPUT) + found = connector_status_connected; + } + + /* restore regs we used */ + RADEON_WRITE(RADEON_DAC_CNTL2, dac_cntl2); + RADEON_WRITE(RADEON_DAC_EXT_CNTL, dac_ext_cntl); + RADEON_WRITE(RADEON_TV_DAC_CNTL, tv_dac_cntl); + RADEON_WRITE(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); + + if (radeon_is_r300(dev_priv)) { + RADEON_WRITE(RADEON_DISP_OUTPUT_CNTL, disp_output_cntl); + RADEON_WRITE_P(RADEON_GPIOPAD_A, gpiopad_a, ~1 ); + } else { + RADEON_WRITE(RADEON_DISP_HW_DEBUG, disp_hw_debug); + } + RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, pixclks_cntl); + + //return found; return connector_status_disconnected; } commit aed70622ab33500721a30b06ec3783c581615cbb Author: Alex Deucher <ale...@gm...> Date: Sun Aug 17 18:09:07 2008 -0400 radeon: first pass at bios scratch regs - todo: updated connected status diff --git a/linux-core/radeon_atombios.c b/linux-core/radeon_atombios.c index eb482d9..ca287bc 100644 --- a/linux-core/radeon_atombios.c +++ b/linux-core/radeon_atombios.c @@ -363,3 +363,55 @@ void radeon_atom_static_pwrmgt_setup(struct drm_device *dev, int enable) atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); } +void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + uint32_t bios_2_scratch, bios_6_scratch; + + if (dev_priv->chip_family >= CHIP_R600) { + bios_2_scratch = RADEON_READ(RADEON_BIOS_0_SCRATCH); + bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH); + } else { + bios_2_scratch = RADEON_READ(RADEON_BIOS_0_SCRATCH); + bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH); + } + + /* let the bios control the backlight */ + bios_2_scratch &= ~ATOM_S2_VRI_BRIGHT_ENABLE; + + /* tell the bios not to handle mode switching */ + bios_6_scratch |= (ATOM_S6_ACC_BLOCK_DISPLAY_SWITCH | + ATOM_S6_ACC_MODE); + + if (dev_priv->chip_family >= CHIP_R600) { + RADEON_WRITE(R600_BIOS_2_SCRATCH, bios_2_scratch); + RADEON_WRITE(R600_BIOS_6_SCRATCH, bios_6_scratch); + } else { + RADEON_WRITE(RADEON_BIOS_2_SCRATCH, bios_2_scratch); + RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch); + } + +} + +void +radeon_atom_output_lock(struct drm_encoder *encoder, bool lock) +{ + struct drm_device *dev = encoder->dev; + struct drm_radeon_private *dev_priv = dev->dev_private; + uint32_t bios_6_scratch; + + if (dev_priv->chip_family >= CHIP_R600) + bios_6_scratch = RADEON_READ(R600_BIOS_6_SCRATCH); + else + bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH); + + if (lock) + bios_6_scratch |= ATOM_S6_CRITICAL_STATE; + else + bios_6_scratch &= ~ATOM_S6_CRITICAL_STATE; + + if (dev_priv->chip_family >= CHIP_R600) + RADEON_WRITE(R600_BIOS_6_SCRATCH, bios_6_scratch); + else + RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch); +} diff --git a/linux-core/radeon_combios.c b/linux-core/radeon_combios.c index 02f7335..200761e 100644 --- a/linux-core/radeon_combios.c +++ b/linux-core/radeon_combios.c @@ -1301,3 +1301,44 @@ void radeon_combios_asic_init(struct drm_device *dev) combios_parse_mmio_table(dev, table); } + +void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + uint32_t bios_0_scratch, bios_6_scratch, bios_7_scratch; + + bios_0_scratch = RADEON_READ(RADEON_BIOS_0_SCRATCH); + bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH); + //bios_7_scratch = RADEON_READ(RADEON_BIOS_7_SCRATCH); + + /* let the bios control the backlight */ + bios_0_scratch &= ~RADEON_DRIVER_BRIGHTNESS_EN; + + /* tell the bios not to handle mode switching */ + bios_6_scratch |= (RADEON_DISPLAY_SWITCHING_DIS | + RADEON_ACC_MODE_CHANGE); + + /* tell the bios a driver is loaded */ + //bios_7_scratch |= RADEON_DRV_LOADED; + + RADEON_WRITE(RADEON_BIOS_0_SCRATCH, bios_0_scratch); + RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch); + //RADEON_WRITE(RADEON_BIOS_7_SCRATCH, bios_7_scratch); +} + +void +radeon_combios_output_lock(struct drm_encoder *encoder, bool lock) +{ + struct drm_device *dev = encoder->dev; + struct drm_radeon_private *dev_priv = dev->dev_private; + uint32_t bios_6_scratch; + + bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH); + + if (lock) + bios_6_scratch |= RADEON_DRIVER_CRITICAL; + else + bios_6_scratch &= ~RADEON_DRIVER_CRITICAL; + + RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch); +} diff --git a/linux-core/radeon_connectors.c b/linux-core/radeon_connectors.c index 32f969a..7b2d7c4 100644 --- a/linux-core/radeon_connectors.c +++ b/linux-core/radeon_connectors.c @@ -66,6 +66,7 @@ static int radeon_lvds_mode_valid(struct drm_connector *connector, static enum drm_connector_status radeon_lvds_detect(struct drm_connector *connector) { + // check acpi lid status ??? return connector_status_connected; } @@ -240,7 +241,7 @@ struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector) } /* see if we have a default encoder TODO */ - + /* then check use digitial */ /* pick the first one */ if (enc_id) { diff --git a/linux-core/radeon_display.c b/linux-core/radeon_display.c index 39eb91e..2877cd3 100644 --- a/linux-core/radeon_display.c +++ b/linux-core/radeon_display.c @@ -600,4 +600,3 @@ void radeon_modeset_cleanup(struct drm_device *dev) { drm_mode_config_cleanup(dev); } - diff --git a/linux-core/radeon_encoders.c b/linux-core/radeon_encoders.c index 04c5709..ec36e43 100644 --- a/linux-core/radeon_encoders.c +++ b/linux-core/radeon_encoders.c @@ -134,7 +134,6 @@ static void atombios_display_device_control(struct drm_encoder *encoder, int ind atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); } - static void atombios_scaler_setup(struct drm_encoder *encoder, struct drm_display_mode *mode) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); @@ -213,7 +212,7 @@ void atombios_set_crtc_source(struct drm_encoder *encoder, int source) default: return; } - + atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)param); } @@ -264,7 +263,7 @@ static void radeon_lvtma_mode_set(struct drm_encoder *encoder, else args.ucMisc = 0; args.usPixelClock = cpu_to_le16(adjusted_mode->clock / 10); - + printk("executing set LVDS encoder\n"); atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); } @@ -273,18 +272,44 @@ static void radeon_lvtma_mode_set(struct drm_encoder *encoder, static void radeon_lvtma_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; + struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); int index = GetIndexIntoMasterTable(COMMAND, LCD1OutputControl); + uint32_t bios_2_scratch, bios_3_scratch; + + if (dev_priv->chip_family >= CHIP_R600) { + bios_2_scratch = RADEON_READ(R600_BIOS_2_SCRATCH); + bios_3_scratch = RADEON_READ(R600_BIOS_3_SCRATCH); + } else { + bios_2_scratch = RADEON_READ(RADEON_BIOS_2_SCRATCH); + bios_3_scratch = RADEON_READ(RADEON_BIOS_3_SCRATCH); + } + + bios_2_scratch &= ~ATOM_S3_LCD1_CRTC_ACTIVE; + bios_3_scratch |= (radeon_crtc->crtc_id << 17); switch(mode) { case DRM_MODE_DPMS_ON: atombios_display_device_control(encoder, index, ATOM_ENABLE); + bios_2_scratch &= ~ATOM_S2_LCD1_DPMS_STATE; + bios_3_scratch |= ATOM_S3_LCD1_ACTIVE; break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: atombios_display_device_control(encoder, index, ATOM_DISABLE); + bios_2_scratch |= ATOM_S2_LCD1_DPMS_STATE; + bios_3_scratch &= ~ATOM_S3_LCD1_ACTIVE; break; } + + if (dev_priv->chip_family >= CHIP_R600) { + RADEON_WRITE(R600_BIOS_2_SCRATCH, bios_2_scratch); + RADEON_WRITE(R600_BIOS_3_SCRATCH, bios_3_scratch); + } else { + RADEON_WRITE(RADEON_BIOS_2_SCRATCH, bios_2_scratch); + RADEON_WRITE(RADEON_BIOS_3_SCRATCH, bios_3_scratch); + } } static bool radeon_lvtma_mode_fixup(struct drm_encoder *encoder, @@ -297,18 +322,20 @@ static bool radeon_lvtma_mode_fixup(struct drm_encoder *encoder, if (radeon_encoder->rmx_type != RMX_OFF) radeon_rmx_mode_fixup(encoder, mode, adjusted_mode); - + return true; } static void radeon_lvtma_prepare(struct drm_encoder *encoder) { + radeon_atom_output_lock(encoder, true); radeon_lvtma_dpms(encoder, DRM_MODE_DPMS_OFF); } static void radeon_lvtma_commit(struct drm_encoder *encoder) { radeon_lvtma_dpms(encoder, DRM_MODE_DPMS_ON); + radeon_atom_output_lock(encoder, false); } static const struct drm_encoder_helper_funcs radeon_atom_lvtma_helper_funcs = { @@ -366,25 +393,91 @@ static void radeon_atom_dac_dpms(struct drm_encoder *encoder, int mode) struct drm_device *dev = encoder->dev; struct drm_radeon_private *dev_priv = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); int atom_type = -1; int index; + uint32_t bios_2_scratch, bios_3_scratch; atom_type = atom_dac_find_atom_type(radeon_encoder, NULL); if (atom_type == -1) return; - + + if (dev_priv->chip_family >= CHIP_R600) { + bios_2_scratch = RADEON_READ(R600_BIOS_2_SCRATCH); + bios_3_scratch = RADEON_READ(R600_BIOS_3_SCRATCH); + } else { + bios_2_scratch = RADEON_READ(RADEON_BIOS_2_SCRATCH); + bios_3_scratch = RADEON_READ(RADEON_BIOS_3_SCRATCH); + } + switch(atom_type) { case ATOM_DEVICE_CRT1_INDEX: index = GetIndexIntoMasterTable(COMMAND, DAC1OutputControl); + bios_2_scratch &= ~ATOM_S3_CRT1_CRTC_ACTIVE; + bios_3_scratch |= (radeon_crtc->crtc_id << 16); + switch(mode) { + case DRM_MODE_DPMS_ON: + bios_2_scratch &= ~ATOM_S2_CRT1_DPMS_STATE; + bios_3_scratch |= ATOM_S3_CRT1_ACTIVE; + break; + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + case DRM_MODE_DPMS_OFF: + bios_2_scratch |= ATOM_S2_CRT1_DPMS_STATE; + bios_3_scratch &= ~ATOM_S3_CRT1_ACTIVE; + break; + } break; case ATOM_DEVICE_CRT2_INDEX: index = GetIndexIntoMasterTable(COMMAND, DAC2OutputControl); + bios_2_scratch &= ~ATOM_S3_CRT2_CRTC_ACTIVE; + bios_3_scratch |= (radeon_crtc->crtc_id << 20); + switch(mode) { + case DRM_MODE_DPMS_ON: + bios_2_scratch &= ~ATOM_S2_CRT2_DPMS_STATE; + bios_3_scratch |= ATOM_S3_CRT2_ACTIVE; + break; + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + case DRM_MODE_DPMS_OFF: + bios_2_scratch |= ATOM_S2_CRT2_DPMS_STATE; + bios_3_scratch &= ~ATOM_S3_CRT2_ACTIVE; + break; + } break; case ATOM_DEVICE_TV1_INDEX: index = GetIndexIntoMasterTable(COMMAND, TV1OutputControl); + bios_3_scratch &= ~ATOM_S3_TV1_CRTC_ACTIVE; + bios_3_scratch |= (radeon_crtc->crtc_id << 18); + switch(mode) { + case DRM_MODE_DPMS_ON: + bios_2_scratch &= ~ATOM_S2_TV1_DPMS_STATE; + bios_3_scratch |= ATOM_S3_TV1_ACTIVE; + break; + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + case DRM_MODE_DPMS_OFF: + bios_2_scratch |= ATOM_S2_TV1_DPMS_STATE; + bios_3_scratch &= ~ATOM_S3_TV1_ACTIVE; + break; + } break; case ATOM_DEVICE_CV_INDEX: index = GetIndexIntoMasterTable(COMMAND, CV1OutputControl); + bios_2_scratch &= ~ATOM_S3_CV_CRTC_ACTIVE; + bios_3_scratch |= (radeon_crtc->crtc_id << 24); + switch(mode) { + case DRM_MODE_DPMS_ON: + bios_2_scratch &= ~ATOM_S2_CV_DPMS_STATE; + bios_3_scratch |= ATOM_S3_CV_ACTIVE; + break; + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + case DRM_MODE_DPMS_OFF: + bios_2_scratch |= ATOM_S2_CV_DPMS_STATE; + bios_3_scratch &= ~ATOM_S3_CV_ACTIVE; + break; + } break; default: return; @@ -394,12 +487,20 @@ static void radeon_atom_dac_dpms(struct drm_encoder *encoder, int mode) case DRM_MODE_DPMS_ON: atombios_display_device_control(encoder, index, ATOM_ENABLE); break; - case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: atombios_display_device_control(encoder, index, ATOM_DISABLE); break; } + + if (dev_priv->chip_family >= CHIP_R600) { + RADEON_WRITE(R600_BIOS_2_SCRATCH, bios_2_scratch); + RADEON_WRITE(R600_BIOS_3_SCRATCH, bios_3_scratch); + } else { + RADEON_WRITE(RADEON_BIOS_2_SCRATCH, bios_2_scratch); + RADEON_WRITE(RADEON_BIOS_3_SCRATCH, bios_3_scratch); + } } static bool radeon_atom_dac_mode_fixup(struct drm_encoder *encoder, @@ -411,12 +512,14 @@ static bool radeon_atom_dac_mode_fixup(struct drm_encoder *encoder, static void radeon_atom_dac_prepare(struct drm_encoder *encoder) { + radeon_atom_output_lock(encoder, true); radeon_atom_dac_dpms(encoder, DRM_MODE_DPMS_OFF); } static void radeon_atom_dac_commit(struct drm_encoder *encoder) { radeon_atom_dac_dpms(encoder, DRM_MODE_DPMS_ON); + radeon_atom_output_lock(encoder, false); } static int atombios_dac_setup(struct drm_encoder *encoder, @@ -447,7 +550,7 @@ static int atombios_dac_setup(struct drm_encoder *encoder, args.ucDacStandard = id ? ATOM_DAC2_NTSC : ATOM_DAC1_NTSC; /* TODO PAL */ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); - + return 0; } @@ -471,7 +574,7 @@ static int atombios_tv1_setup(struct drm_encoder *encoder, } args.sTVEncoder.usPixelClock = cpu_to_le16(mode->clock / 10); - + atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); return 0; } @@ -496,7 +599,7 @@ static void radeon_atom_dac_mode_set(struct drm_encoder *encoder, if ((atom_type == ATOM_DEVICE_TV1_INDEX) || (atom_type == ATOM_DEVICE_CV_INDEX)) atombios_tv1_setup(encoder, adjusted_mode, atom_type); - + } static bool atom_dac_load_detect(struct drm_encoder *encoder, int atom_devices) @@ -525,11 +628,11 @@ static bool atom_dac_load_detect(struct drm_encoder *encoder, int atom_devices) args.sDacload.ucMisc = 1; } else return false; - + DRM_DEBUG("writing %x %x\n", args.sDacload.usDeviceID, args.sDacload.ucDacType); atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); return true; -} +} static enum drm_connector_status radeon_atom_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) { @@ -551,7 +654,7 @@ static enum drm_connector_status radeon_atom_dac_detect(struct drm_encoder *enco } - if (dev_priv->chip_family >= CHIP_R600) + if (dev_priv->chip_family >= CHIP_R600) bios_0_scratch = RADEON_READ(R600_BIOS_0_SCRATCH); else bios_0_scratch = RADEON_READ(RADEON_BIOS_0_SCRATCH); @@ -607,7 +710,7 @@ static void atombios_tmds1_setup(struct drm_encoder *encoder, args.usPixelClock = cpu_to_le16(mode->clock / 10); - atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); + atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); } static void atombios_tmds2_setup(struct drm_encoder *encoder, @@ -628,7 +731,7 @@ static void atombios_tmds2_setup(struct drm_encoder *encoder, args.usPixelClock = cpu_to_le16(mode->clock / 10); - atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); + atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); } @@ -652,7 +755,7 @@ static void atombios_ext_tmds_setup(struct drm_encoder *encoder, // TODO 6-bit DAC // args.usPixelClock = cpu_to_le16(mode->clock / 10); - atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); + atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); } static void atombios_dig1_setup(struct drm_encoder *encoder, @@ -680,7 +783,7 @@ static void atombios_dig1_setup(struct drm_encoder *encoder, } // TODO Encoder MODE - atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); + atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); } static void atombios_ddia_setup(struct drm_encoder *encoder, @@ -699,7 +802,7 @@ static void atombios_ddia_setup(struct drm_encoder *encoder, else args.sDVOEncoder.usDevAttr.sDigAttrib.ucAttribute = 0; - atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); + atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); } struct drm_encoder *radeon_encoder_atom_dac_add(struct drm_device *dev, int bios_index, int dac_type, int with_tv) @@ -760,8 +863,10 @@ static void radeon_atom_tmds_dpms(struct drm_encoder *encoder, int mode) struct drm_device *dev = encoder->dev; struct drm_radeon_private *dev_priv = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); int atom_type = -1; int index = -1; + uint32_t bios_2_scratch, bios_3_scratch; if (radeon_encoder->atom_device & ATOM_DEVICE_DFP1_SUPPORT) atom_type = ATOM_DEVICE_DFP1_INDEX; @@ -773,15 +878,65 @@ static void radeon_atom_tmds_dpms(struct drm_encoder *encoder, int mode) if (atom_type == -1) return; + if (dev_priv->chip_family >= CHIP_R600) { + bios_2_scratch = RADEON_READ(R600_BIOS_2_SCRATCH); + bios_3_scratch = RADEON_READ(R600_BIOS_3_SCRATCH); + } else { + bios_2_scratch = RADEON_READ(RADEON_BIOS_2_SCRATCH); + bios_3_scratch = RADEON_READ(RADEON_BIOS_3_SCRATCH); + } + switch(atom_type) { case ATOM_DEVICE_DFP1_INDEX: index = GetIndexIntoMasterTable(COMMAND, TMDSAOutputControl); + bios_2_scratch &= ~ATOM_S3_DFP1_CRTC_ACTIVE; + bios_3_scratch |= (radeon_crtc->crtc_id << 19); + switch(mode) { + case DRM_MODE_DPMS_ON: + bios_2_scratch &= ~ATOM_S2_DFP1_DPMS_STATE; + bios_3_scratch |= ATOM_S3_DFP1_ACTIVE; + break; + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + case DRM_MODE_DPMS_OFF: + bios_2_scratch |= ATOM_S2_DFP1_DPMS_STATE; + bios_3_scratch &= ~ATOM_S3_DFP1_ACTIVE; + break; + } break; case ATOM_DEVICE_DFP2_INDEX: index = GetIndexIntoMasterTable(COMMAND, DVOOutputControl); + bios_2_scratch &= ~ATOM_S3_DFP2_CRTC_ACTIVE; + bios_3_scratch |= (radeon_crtc->crtc_id << 23); + switch(mode) { + case DRM_MODE_DPMS_ON: + bios_2_scratch &= ~ATOM_S2_DFP2_DPMS_STATE; + bios_3_scratch |= ATOM_S3_DFP2_ACTIVE; + break; + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + case DRM_MODE_DPMS_OFF: + bios_2_scratch |= ATOM_S2_DFP2_DPMS_STATE; + bios_3_scratch &= ~ATOM_S3_DFP2_ACTIVE; + break; + } break; case ATOM_DEVICE_DFP3_INDEX: index = GetIndexIntoMasterTable(COMMAND, LVTMAOutputControl); + bios_2_scratch &= ~ATOM_S3_DFP3_CRTC_ACTIVE; + bios_3_scratch |= (radeon_crtc->crtc_id << 25); + switch(mode) { + case DRM_MODE_DPMS_ON: + bios_2_scratch &= ~ATOM_S2_DFP3_DPMS_STATE; + bios_3_scratch |= ATOM_S3_DFP3_ACTIVE; + break; + case DRM_MODE_DPMS_STANDBY: + case DRM_MODE_DPMS_SUSPEND: + case DRM_MODE_DPMS_OFF: + bios_2_scratch |= ATOM_S2_DFP3_DPMS_STATE; + bios_3_scratch &= ~ATOM_S3_DFP3_ACTIVE; + break; + } break; } @@ -798,6 +953,14 @@ static void radeon_atom_tmds_dpms(struct drm_encoder *encoder, int mode) atombios_display_device_control(encoder, index, ATOM_DISABLE); break; } + + if (dev_priv->chip_family >= CHIP_R600) { + RADEON_WRITE(R600_BIOS_2_SCRATCH, bios_2_scratch); + RADEON_WRITE(R600_BIOS_3_SCRATCH, bios_3_scratch); + } else { + RADEON_WRITE(RADEON_BIOS_2_SCRATCH, bios_2_scratch); + RADEON_WRITE(RADEON_BIOS_3_SCRATCH, bios_3_scratch); + } } static bool radeon_atom_tmds_mode_fixup(struct drm_encoder *encoder, @@ -845,12 +1008,14 @@ static void radeon_atom_tmds_mode_set(struct drm_encoder *encoder, static void radeon_atom_tmds_prepare(struct drm_encoder *encoder) { + radeon_atom_output_lock(encoder, true); radeon_atom_tmds_dpms(encoder, DRM_MODE_DPMS_OFF); } static void radeon_atom_tmds_commit(struct drm_encoder *encoder) { radeon_atom_tmds_dpms(encoder, DRM_MODE_DPMS_ON); + radeon_atom_output_lock(encoder, false); } static const struct drm_encoder_helper_funcs radeon_atom_tmds_helper_funcs = { @@ -894,4 +1059,3 @@ struct drm_encoder *radeon_encoder_atom_tmds_add(struct drm_device *dev, int bio radeon_encoder->atom_device &= analog_enc_mask; return encoder; } - diff --git a/linux-core/radeon_gem.c b/linux-core/radeon_gem.c index 6a7529c..d572008 100644 --- a/linux-core/radeon_gem.c +++ b/linux-core/radeon_gem.c @@ -225,7 +225,7 @@ int radeon_gem_mmap_ioctl(struct drm_device *dev, void *data, args->addr_ptr = (uint64_t) addr; return 0; - + } int radeon_gem_pin_ioctl(struct drm_device *dev, void *data, diff --git a/linux-core/radeon_legacy_encoders.c b/linux-core/radeon_legacy_encoders.c index 48cdd18..6452154 100644 --- a/linux-core/radeon_legacy_encoders.c +++ b/linux-core/radeon_legacy_encoders.c @@ -197,10 +197,19 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) struct drm_device *dev = encoder->dev; struct drm_radeon_private *dev_priv = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); uint32_t lvds_gen_cntl, lvds_pll_cntl, pixclks_cntl, disp_pwr_man; + uint32_t bios_5_scratch, bios_6_scratch; DRM_DEBUG("\n"); + // FIXME atom/legacy cards like r4xx + bios_5_scratch = RADEON_READ(RADEON_BIOS_5_SCRATCH); + bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH); + + bios_5_scratch &= ~RADEON_LCD1_CRTC_MASK; + bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_LCD1_CRTC_SHIFT); + switch (mode) { case DRM_MODE_DPMS_ON: disp_pwr_man = RADEON_READ(RADEON_DISP_PWR_MAN); @@ -228,6 +237,11 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) /* enable backlight */ lvds_gen_cntl |= RADEON_LVDS_BLON; RADEON_WRITE(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); + + /* update bios scratch regs */ + bios_5_scratch |= RADEON_LCD1_ON; + bios_6_scratch |= RADEON_LCD_DPMS_ON; + break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: @@ -239,18 +253,27 @@ static void radeon_legacy_lvds_dpms(struct drm_encoder *encoder, int mode) lvds_gen_cntl &= ~(RADEON_LVDS_ON | RADEON_LVDS_BLON | RADEON_LVDS_EN | RADEON_LVDS_DIGON); RADEON_WRITE(RADEON_LVDS_GEN_CNTL, lvds_gen_cntl); RADEON_WRITE_PLL(dev_priv, RADEON_PIXCLKS_CNTL, pixclks_cntl); + + bios_5_scratch &= ~RADEON_LCD1_ON; + bios_6_scratch &= ~RADEON_LCD_DPMS_ON; break; } + RADEON_WRITE(RADEON_BIOS_5_SCRATCH, bios_5_scratch); + RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch); } static void radeon_legacy_lvds_prepare(struct drm_encoder *encoder) { + // fix me: atom/legacy r4xx + radeon_combios_output_lock(encoder, true); radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_OFF); } static void radeon_legacy_lvds_commit(struct drm_encoder *encoder) { radeon_legacy_lvds_dpms(encoder, DRM_MODE_DPMS_ON); + // fix me: atom/legacy r4xx + radeon_combios_output_lock(encoder, false); } static void radeon_legacy_lvds_mode_set(struct drm_encoder *encoder, @@ -372,9 +395,20 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode { struct drm_device *dev = encoder->dev; struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); uint32_t crtc_ext_cntl = RADEON_READ(RADEON_CRTC_EXT_CNTL); uint32_t dac_cntl = RADEON_READ(RADEON_DAC_CNTL); uint32_t dac_macro_cntl = RADEON_READ(RADEON_DAC_MACRO_CNTL); + uint32_t bios_5_scratch, bios_6_scratch; + + DRM_DEBUG("\n"); + + // FIXME atom/legacy cards like r4xx + bios_5_scratch = RADEON_READ(RADEON_BIOS_5_SCRATCH); + bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH); + + bios_5_scratch &= ~RADEON_CRT1_CRTC_MASK; + bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT1_CRTC_SHIFT); DRM_DEBUG("\n"); @@ -385,6 +419,8 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode dac_macro_cntl &= ~(RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G | RADEON_DAC_PDWN_B); + bios_5_scratch |= RADEON_CRT1_ON; + bios_6_scratch |= RADEON_CRT_DPMS_ON; break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: @@ -394,6 +430,8 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode dac_macro_cntl |= (RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G | RADEON_DAC_PDWN_B); + bios_5_scratch &= ~RADEON_CRT1_ON; + bios_6_scratch &= ~RADEON_CRT_DPMS_ON; break; } @@ -401,16 +439,22 @@ static void radeon_legacy_primary_dac_dpms(struct drm_encoder *encoder, int mode RADEON_WRITE(RADEON_DAC_CNTL, dac_cntl); RADEON_WRITE(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); + RADEON_WRITE(RADEON_BIOS_5_SCRATCH, bios_5_scratch); + RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch); } static void radeon_legacy_primary_dac_prepare(struct drm_encoder *encoder) { + // fix me: atom/legacy r4xx + radeon_combios_output_lock(encoder, true); radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_OFF); } static void radeon_legacy_primary_dac_commit(struct drm_encoder *encoder) { radeon_legacy_primary_dac_dpms(encoder, DRM_MODE_DPMS_ON); + // fix me: atom/legacy r4xx + radeon_combios_output_lock(encoder, false); } static void radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder, @@ -527,32 +571,52 @@ static void radeon_legacy_tmds_int_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); uint32_t fp_gen_cntl = RADEON_READ(RADEON_FP_GEN_CNTL); + uint32_t bios_5_scratch, bios_6_scratch; DRM_DEBUG("\n"); + // FIXME atom/legacy cards like r4xx + bios_5_scratch = RADEON_READ(RADEON_BIOS_5_SCRATCH); + bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH); + + bios_5_scratch &= ~RADEON_DFP1_CRTC_MASK; + bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP1_CRTC_SHIFT); + switch(mode) { case DRM_MODE_DPMS_ON: fp_gen_cntl |= (RADEON_FP_FPON | RADEON_FP_TMDS_EN); + bios_5_scratch |= RADEON_DFP1_ON; + bios_6_scratch |= RADEON_DFP_DPMS_ON; break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: fp_gen_cntl &= ~(RADEON_FP_FPON | RADEON_FP_TMDS_EN); + bios_5_scratch &= ~RADEON_DFP1_ON; + bios_6_scratch &= ~RADEON_DFP_DPMS_ON; break; } RADEON_WRITE(RADEON_FP_GEN_CNTL, fp_gen_cntl); + + RADEON_WRITE(RADEON_BIOS_5_SCRATCH, bios_5_scratch); + RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch); } static void radeon_legacy_tmds_int_prepare(struct drm_encoder *encoder) { + // fix me: atom/legacy r4xx + radeon_combios_output_lock(encoder, true); radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_OFF); } static void radeon_legacy_tmds_int_commit(struct drm_encoder *encoder) { radeon_legacy_tmds_int_dpms(encoder, DRM_MODE_DPMS_ON); + // fix me: atom/legacy r4xx + radeon_combios_output_lock(encoder, true); } static void radeon_legacy_tmds_int_mode_set(struct drm_encoder *encoder, @@ -691,34 +755,54 @@ static void radeon_legacy_tmds_ext_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); uint32_t fp2_gen_cntl = RADEON_READ(RADEON_FP2_GEN_CNTL); + uint32_t bios_5_scratch, bios_6_scratch; DRM_DEBUG("\n"); + // FIXME atom/legacy cards like r4xx + bios_5_scratch = RADEON_READ(RADEON_BIOS_5_SCRATCH); + bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH); + + bios_5_scratch &= ~RADEON_DFP2_CRTC_MASK; + bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_DFP2_CRTC_SHIFT); + switch(mode) { case DRM_MODE_DPMS_ON: fp2_gen_cntl &= ~RADEON_FP2_BLANK_EN; fp2_gen_cntl |= (RADEON_FP2_ON | RADEON_FP2_DVO_EN); + bios_5_scratch |= RADEON_DFP2_ON; + bios_6_scratch |= RADEON_DFP_DPMS_ON; break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: fp2_gen_cntl |= RADEON_FP2_BLANK_EN; fp2_gen_cntl &= ~(RADEON_FP2_ON | RADEON_FP2_DVO_EN); + bios_5_scratch &= ~RADEON_DFP2_ON; + bios_6_scratch &= ~RADEON_DFP_DPMS_ON; break; } RADEON_WRITE(RADEON_FP2_GEN_CNTL, fp2_gen_cntl); + + RADEON_WRITE(RADEON_BIOS_5_SCRATCH, bios_5_scratch); + RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch); } static void radeon_legacy_tmds_ext_prepare(struct drm_encoder *encoder) { + // fix me: atom/legacy r4xx + radeon_combios_output_lock(encoder, true); radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_OFF); } static void radeon_legacy_tmds_ext_commit(struct drm_encoder *encoder) { radeon_legacy_tmds_ext_dpms(encoder, DRM_MODE_DPMS_ON); + // fix me: atom/legacy r4xx + radeon_combios_output_lock(encoder, false); } static void radeon_legacy_tmds_ext_mode_set(struct drm_encoder *encoder, @@ -827,11 +911,23 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); uint32_t fp2_gen_cntl = 0, crtc2_gen_cntl = 0, tv_dac_cntl = 0; //uint32_t tv_master_cntl = 0; + uint32_t bios_5_scratch, bios_6_scratch; DRM_DEBUG("\n"); + // FIXME atom/legacy cards like r4xx + bios_5_scratch = RADEON_READ(RADEON_BIOS_5_SCRATCH); + bios_6_scratch = RADEON_READ(RADEON_BIOS_6_SCRATCH); + + bios_5_scratch &= ~RADEON_CRT2_CRTC_MASK; + bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_CRT2_CRTC_SHIFT); + // FIXME TV + //bios_5_scratch &= ~RADEON_TV1_CRTC_MASK; + //bios_5_scratch |= (radeon_crtc->crtc_id << RADEON_TV1_CRTC_SHIFT); + if (dev_priv->chip_family == CHIP_R200) fp2_gen_cntl = RADEON_READ(RADEON_FP2_GEN_CNTL); else { @@ -860,6 +956,10 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) RADEON_TV_DAC_BDACPD | RADEON_TV_DAC_BGSLEEP); } + //bios_5_scratch |= RADEON_TV1_ON; + //bios_6_scratch |= RADEON_TV_DPMS_ON; + bios_5_scratch |= RADEON_CRT2_ON; + bios_6_scratch |= RADEON_CRT_DPMS_ON; break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: @@ -881,6 +981,10 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) RADEON_TV_DAC_BDACPD | RADEON_TV_DAC_BGSLEEP); } + //bios_5_scratch &= ~RADEON_TV1_ON; + //bios_6_scratch &= ~RADEON_TV_DPMS_ON; + bios_5_scratch &= ~RADEON_CRT2_ON; + bios_6_scratch &= ~RADEON_CRT_DPMS_ON; break; } @@ -892,16 +996,22 @@ static void radeon_legacy_tv_dac_dpms(struct drm_encoder *encoder, int mode) RADEON_WRITE(RADEON_TV_DAC_CNTL, tv_dac_cntl); } + RADEON_WRITE(RADEON_BIOS_5_SCRATCH, bios_5_scratch); + RADEON_WRITE(RADEON_BIOS_6_SCRATCH, bios_6_scratch); } static void radeon_legacy_tv_dac_prepare(struct drm_encoder *encoder) { + // fix me: atom/legacy r4xx + radeon_combios_output_lock(encoder, true); radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_OFF); } static void radeon_legacy_tv_dac_commit(struct drm_encoder *encoder) { radeon_legacy_tv_dac_dpms(encoder, DRM_MODE_DPMS_ON); + // fix me: atom/legacy r4xx + radeon_combios_output_lock(encoder, false); } static void radeon_legacy_tv_dac_mode_set(struct drm_encoder *encoder, diff --git a/linux-core/radeon_mode.h b/linux-core/radeon_mode.h index 7278c42..d7c60fa 100644 --- a/linux-core/radeon_mode.h +++ b/linux-core/radeon_mode.h @@ -293,6 +293,10 @@ extern bool radeon_combios_get_tmds_info(struct radeon_encoder *encoder); extern bool radeon_combios_get_tv_info(struct radeon_encoder *encoder); extern bool radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder); extern bool radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder); +extern void radeon_combios_output_lock(struct drm_encoder *encoder, bool lock); +extern void radeon_combios_initialize_bios_scratch_regs(struct drm_device *dev); +extern void radeon_atom_output_lock(struct drm_encoder *encoder, bool lock); +extern void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev); extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, int regno); struct drm_framebuffer *radeon_user_framebuffer_create(struct drm_device *dev, @@ -311,6 +315,7 @@ void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_stat void radeon_atom_static_pwrmgt_setup(struct drm_device *dev, int enable); void radeon_atom_dyn_clk_setup(struct drm_device *dev, int enable); +void radeon_combios_dyn_clk_setup(struct drm_device *dev, int enable); void radeon_get_clock_info(struct drm_device *dev); extern bool radeon_get_atom_connector_info_from_bios_connector_table(struct drm_device *dev); diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index e30696f..6b71360 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2409,8 +2409,12 @@ int radeon_modeset_preinit(struct drm_device *dev) if (dev_priv->is_atom_bios) { dev_priv->mode_info.atom_context = atom_parse(&card, dev_priv->bios); - } + radeon_atom_initialize_bios_scratch_regs(dev); + } else + radeon_combios_initialize_bios_scratch_regs(dev); + radeon_get_clock_info(dev); + return 0; } commit 226c97e3b772f2f4bf09085374cd931b83dea2b0 Author: Alex Deucher <ale...@gm...> Date: Sun Aug 17 15:38:05 2008 -0400 radeon: remove unused legacy state diff --git a/linux-core/radeon_mode.h b/linux-core/radeon_mode.h index ee80160..7278c42 100644 --- a/linux-core/radeon_mode.h +++ b/linux-core/radeon_mode.h @@ -161,160 +161,10 @@ struct radeon_pll { uint32_t best_vco; }; -#define MAX_H_CODE_TIMING_LEN 32 -#define MAX_V_CODE_TIMING_LEN 32 - -struct radeon_legacy_state { - - uint32_t bus_cntl; - - /* DAC */ - uint32_t dac_cntl; - uint32_t dac2_cntl; - uint32_t dac_macro_cntl; - - /* CRTC 1 */ - uint32_t crtc_gen_cntl; - uint32_t crtc_ext_cntl; - uint32_t crtc_h_total_disp; - uint32_t crtc_h_sync_strt_wid; - uint32_t crtc_v_total_disp; - uint32_t crtc_v_sync_strt_wid; - uint32_t crtc_offset; - uint32_t crtc_offset_cntl; - uint32_t crtc_pitch; - uint32_t disp_merge_cntl; - uint32_t grph_buffer_cntl; - uint32_t crtc_more_cntl; - uint32_t crtc_tile_x0_y0; - - /* CRTC 2 */ - uint32_t crtc2_gen_cntl; - uint32_t crtc2_h_total_disp; - uint32_t crtc2_h_sync_strt_wid; - uint32_t crtc2_v_total_disp; - uint32_t crtc2_v_sync_strt_wid; - uint32_t crtc2_offset; - uint32_t crtc2_offset_cntl; - uint32_t crtc2_pitch; - uint32_t crtc2_tile_x0_y0; - - uint32_t disp_output_cntl; - uint32_t disp_tv_out_cntl; - uint32_t disp_hw_debug; - uint32_t disp2_merge_cntl; - uint32_t grph2_buffer_cntl; - - /* FP regs */ - uint32_t fp_crtc_h_total_disp; - uint32_t fp_crtc_v_total_disp; - uint32_t fp_gen_cntl; - uint32_t fp2_gen_cntl; - uint32_t fp_h_sync_strt_wid; - uint32_t fp_h2_sync_strt_wid; - uint32_t fp_horz_stretch; - uint32_t fp_horz_vert_active; - uint32_t fp_panel_cntl; - uint32_t fp_v_sync_strt_wid; - uint32_t fp_v2_sync_strt_wid; - uint32_t fp_vert_stretch; - uint32_t lvds_gen_cntl; - uint32_t lvds_pll_cntl; - uint32_t tmds_pll_cntl; - uint32_t tmds_transmitter_cntl; - - /* Computed values for PLL */ - uint32_t dot_clock_freq; - uint32_t pll_output_freq; - int feedback_div; - int reference_div; - int post_div; - - /* PLL registers */ - uint32_t ppll_ref_div; - uint32_t ppll_div_3; - uint32_t htotal_cntl; - uint32_t vclk_ecp_cntl; - - /* Computed values for PLL2 */ - uint32_t dot_clock_freq_2; - uint32_t pll_output_freq_2; - int feedback_div_2; - int reference_div_2; - int post_div_2; - - /* PLL2 registers */ - uint32_t p2pll_ref_div; - uint32_t p2pll_div_0; - uint32_t htotal_cntl2; - uint32_t pixclks_cntl; - - bool palette_valid; - uint32_t palette[256]; - uint32_t palette2[256]; - - uint32_t disp2_req_cntl1; - uint32_t disp2_req_cntl2; - uint32_t dmif_mem_cntl1; - uint32_t disp1_req_cntl1; - - uint32_t fp_2nd_gen_cntl; - uint32_t fp2_2_gen_cntl; - uint32_t tmds2_cntl; - uint32_t tmds2_transmitter_cntl; - - /* TV out registers */ - uint32_t tv_master_cntl; - uint32_t tv_htotal; - uint32_t tv_hsize; - uint32_t tv_hdisp; - uint32_t tv_hstart; - uint32_t tv_vtotal; - uint32_t tv_vdisp; - uint32_t tv_timing_cntl; - uint32_t tv_vscaler_cntl1; - uint32_t tv_vscaler_cntl2; - uint32_t tv_sync_size; - uint32_t tv_vrestart; - uint32_t tv_hrestart; - uint32_t tv_frestart; - uint32_t tv_ftotal; - uint32_t tv_clock_sel_cntl; - uint32_t tv_clkout_cntl; - uint32_t tv_data_delay_a; - uint32_t tv_data_delay_b; - uint32_t tv_dac_cntl; - uint32_t tv_pll_cntl; - uint32_t tv_pll_cntl1; - uint32_t tv_pll_fine_cntl; - uint32_t tv_modulator_cntl1; - uint32_t tv_modulator_cntl2; - uint32_t tv_frame_lock_cntl; - uint32_t tv_pre_dac_mux_cntl; - uint32_t tv_rgb_cntl; - uint32_t tv_y_saw_tooth_cntl; - uint32_t tv_y_rise_cntl; - uint32_t tv_y_fall_cntl; - uint32_t tv_uv_adr; - uint32_t tv_upsamp_and_gain_cntl; - uint32_t tv_gain_limit_settings; - uint32_t tv_linear_gain_settings; - uint32_t tv_crc_cntl; - uint32_t tv_sync_cntl; - uint32_t gpiopad_a; - uint32_t pll_test_cntl; - - uint16_t h_code_timing[MAX_H_CODE_TIMING_LEN]; - uint16_t v_code_timing[MAX_V_CODE_TIMING_LEN]; - - -}; - struct radeon_mode_info { struct atom_context *atom_context; struct radeon_bios_connector bios_connector[RADEON_MAX_BIOS_CONNECTOR]; struct radeon_pll pll; - struct radeon_legacy_state legacy_state; }; struct radeon_crtc { commit 6af286079b57248405e543d7d99e111931983eac Author: Alex Deucher <ale...@gm...> Date: Sun Aug 17 15:33:31 2008 -0400 radeon: get primary dac adj info from bios tables diff --git a/linux-core/radeon_combios.c b/linux-core/radeon_combios.c index 5611646..02f7335 100644 --- a/linux-core/radeon_combios.c +++ b/linux-core/radeon_combios.c @@ -460,6 +460,36 @@ bool radeon_combios_get_clock_info(struct drm_device *dev) return false; } +bool radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder) +{ + struct drm_device *dev = encoder->base.dev; + struct drm_radeon_private *dev_priv = dev->dev_private; + uint16_t dac_info; + uint8_t rev, bg, dac; + + /* check CRT table */ + dac_info = combios_get_table_offset(dev, COMBIOS_CRT_INFO_TABLE); + if (dac_info) { + rev = radeon_bios8(dev_priv, dac_info) & 0x3; + if (rev < 2) { + bg = radeon_bios8(dev_priv, dac_info + 0x2) & 0xf; + dac = (radeon_bios8(dev_priv, dac_info + 0x2) >> 4) & 0xf; + encoder->ps2_pdac_adj = (bg << 8) | (dac); + + return true; + } else { + bg = radeon_bios8(dev_priv, dac_info + 0x2) & 0xf; + dac = radeon_bios8(dev_priv, dac_info + 0x3) & 0xf; + encoder->ps2_pdac_adj = (bg << 8) | (dac); + + return true; + } + + } + + return false; +} + bool radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder) { struct drm_device *dev = encoder->base.dev; @@ -908,7 +938,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) dev_priv->chip_family == CHIP_RS480) { uint16_t lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE); if (lcd_info) { - uint16_t lcd_ddc_info = lcd_ddc_info = combios_get_table_offset(dev, COMBIOS_LCD_DDC_INFO_TABLE); + uint16_t lcd_ddc_info = combios_get_table_offset(dev, COMBIOS_LCD_DDC_INFO_TABLE); mode_info->bios_connector[4].valid = true; mode_info->bios_connector[4].connector_type = CONNECTOR_LVDS; diff --git a/linux-core/radeon_legacy_encoders.c b/linux-core/radeon_legacy_encoders.c index 172f93d..48cdd18 100644 --- a/linux-core/radeon_legacy_encoders.c +++ b/linux-core/radeon_legacy_encoders.c @@ -420,6 +420,7 @@ static void radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder, struct drm_device *dev = encoder->dev; struct drm_radeon_private *dev_priv = dev->dev_private; struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); + struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); uint32_t disp_output_cntl, dac_cntl, dac2_cntl, dac_macro_cntl; DRM_DEBUG("\n"); @@ -458,7 +459,11 @@ static void radeon_legacy_primary_dac_mode_set(struct drm_encoder *encoder, RADEON_DAC_RANGE_CNTL | RADEON_DAC_BLANKING); - dac_macro_cntl = RADEON_READ(RADEON_DAC_MACRO_CNTL); + if (radeon_encoder->ps2_pdac_adj) + dac_macro_cntl = radeon_encoder->ps2_pdac_adj; + else + dac_macro_cntl = RADEON_READ(RADEON_DAC_MACRO_CNTL); + dac_macro_cntl |= RADEON_DAC_PDWN_R | RADEON_DAC_PDWN_G | RADEON_DAC_PDWN_B; RADEON_WRITE(RADEON_DAC_MACRO_CNTL, dac_macro_cntl); } @@ -504,8 +509,8 @@ struct drm_encoder *radeon_encoder_legacy_primary_dac_add(struct drm_device *dev drm_encoder_helper_add(encoder, &radeon_legacy_primary_dac_helper_funcs); - /* TODO get the primary dac vals from bios tables */ - //radeon_combios_get_lvds_info(radeon_encoder); + /* get the primary dac bg/adj vals from bios tables */ + radeon_combios_get_primary_dac_info(radeon_encoder); return encoder; } diff --git a/linux-core/radeon_mode.h b/linux-core/radeon_mode.h index 3271375..ee80160 100644 --- a/linux-core/radeon_mode.h +++ b/linux-core/radeon_mode.h @@ -368,6 +368,9 @@ struct radeon_encoder { bool use_bios_dividers; uint32_t lvds_gen_cntl; + /* legacy primary dac */ + uint32_t ps2_pdac_adj; + /* legacy tv dac */ uint32_t ps2_tvdac_adj; uint32_t ntsc_tvdac_adj; @@ -439,6 +442,7 @@ extern bool radeon_combios_get_lvds_info(struct radeon_encoder *encoder); extern bool radeon_combios_get_tmds_info(struct radeon_encoder *encoder); extern bool radeon_combios_get_tv_info(struct radeon_encoder *encoder); extern bool radeon_combios_get_tv_dac_info(struct radeon_encoder *encoder); +extern bool radeon_combios_get_primary_dac_info(struct radeon_encoder *encoder); extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, int regno); struct drm_framebuffer *radeon_user_framebuffer_create(struct drm_device *dev, |
From: <ag...@ke...> - 2008-09-18 14:32:40
|
linux-core/atombios_crtc.c | 34 ++++++-- linux-core/radeon_atombios.c | 167 +++++++++++++++++++++++++++++----------- linux-core/radeon_combios.c | 73 +++++++++++++---- linux-core/radeon_display.c | 115 ++++++++++++++++++++++++--- linux-core/radeon_encoders.c | 16 +++ linux-core/radeon_legacy_crtc.c | 15 ++- linux-core/radeon_mode.h | 39 +++++---- linux-core/radeon_pm.c | 60 ++++++++++++++ linux-core/radeon_reg.h | 70 +++++++++++----- shared-core/radeon_cp.c | 6 - shared-core/radeon_drv.h | 1 11 files changed, 466 insertions(+), 130 deletions(-) New commits: commit 075ed1d6fd1d58c1f46d556df79f44153f10edd8 Author: Alex Deucher <ale...@gm...> Date: Thu Sep 18 17:27:00 2008 -0400 radeon: pll and interlace updates from the ddx also some formatting cleanup in radeon_reg.h diff --git a/linux-core/atombios_crtc.c b/linux-core/atombios_crtc.c index 03077a1..cefe922 100644 --- a/linux-core/atombios_crtc.c +++ b/linux-core/atombios_crtc.c @@ -150,8 +150,7 @@ void atombios_crtc_set_timing(struct drm_crtc *crtc, SET_CRTC_TIMING_PARAMETERS_ atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&conv_param); } -void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode, - int pll_flags) +void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) { struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct drm_device *dev = crtc->dev; @@ -164,10 +163,17 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode, uint32_t sclock = mode->clock; uint32_t ref_div = 0, fb_div = 0, post_div = 0; struct radeon_pll *pll; + int pll_flags = 0; memset(&spc_param, 0, sizeof(SET_PIXEL_CLOCK_PS_ALLOCATION)); - pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; + if (!radeon_is_avivo(dev_priv)) + pll_flags |= RADEON_PLL_LEGACY; + + if (mode->clock > 120000) /* range limits??? */ + pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; + else + pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; if (radeon_crtc->crtc_id == 0) pll = &dev_priv->mode_info.p1pll; @@ -293,6 +299,12 @@ void atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y) RADEON_WRITE(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset, (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay); + if (crtc->mode.flags & DRM_MODE_FLAG_INTERLACE) + RADEON_WRITE(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, + AVIVO_D1MODE_INTERLEAVE_EN); + else + RADEON_WRITE(AVIVO_D1MODE_DATA_FORMAT + radeon_crtc->crtc_offset, + 0); } void atombios_crtc_mode_set(struct drm_crtc *crtc, @@ -305,7 +317,6 @@ void atombios_crtc_mode_set(struct drm_crtc *crtc, struct drm_radeon_private *dev_priv = dev->dev_private; struct drm_encoder *encoder; SET_CRTC_TIMING_PARAMETERS_PS_ALLOCATION crtc_timing; - int pll_flags = 0; /* TODO color tiling */ memset(&crtc_timing, 0, sizeof(crtc_timing)); @@ -347,9 +358,10 @@ void atombios_crtc_mode_set(struct drm_crtc *crtc, else radeon_crtc_set_base(crtc, x, y); - atombios_crtc_set_pll(crtc, adjusted_mode, pll_flags); + atombios_crtc_set_pll(crtc, adjusted_mode); atombios_crtc_set_timing(crtc, &crtc_timing); + } static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, diff --git a/linux-core/radeon_display.c b/linux-core/radeon_display.c index fd0855e..e2d02be 100644 --- a/linux-core/radeon_display.c +++ b/linux-core/radeon_display.c @@ -451,7 +451,12 @@ void radeon_compute_pll(struct radeon_pll *pll, best_freq = current_freq; best_error = error; best_vco_diff = vco_diff; - } else if ((flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) { + } else if (((flags & RADEON_PLL_PREFER_LOW_REF_DIV) && (ref_div < best_ref_div)) || + ((flags & RADEON_PLL_PREFER_HIGH_REF_DIV) && (ref_div > best_ref_div)) || + ((flags & RADEON_PLL_PREFER_LOW_FB_DIV) && (feedback_div < best_feedback_div)) || + ((flags & RADEON_PLL_PREFER_HIGH_FB_DIV) && (feedback_div > best_feedback_div)) || + ((flags & RADEON_PLL_PREFER_LOW_POST_DIV) && (post_div < best_post_div)) || + ((flags & RADEON_PLL_PREFER_HIGH_POST_DIV) && (post_div > best_post_div))) { best_post_div = post_div; best_ref_div = ref_div; best_feedback_div = feedback_div; diff --git a/linux-core/radeon_encoders.c b/linux-core/radeon_encoders.c index 82ffcfb..98be705 100644 --- a/linux-core/radeon_encoders.c +++ b/linux-core/radeon_encoders.c @@ -517,9 +517,15 @@ static void radeon_atom_dac_dpms(struct drm_encoder *encoder, int mode) } static bool radeon_atom_dac_mode_fixup(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) { + + /* hw bug */ + if ((mode->flags & DRM_MODE_FLAG_INTERLACE) + && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) + adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; + return true; } @@ -987,6 +993,12 @@ static bool radeon_atom_tmds_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) { + + /* hw bug */ + if ((mode->flags & DRM_MODE_FLAG_INTERLACE) + && (mode->crtc_vsync_start < (mode->crtc_vdisplay + 2))) + adjusted_mode->crtc_vsync_start = adjusted_mode->crtc_vdisplay + 2; + return true; } diff --git a/linux-core/radeon_legacy_crtc.c b/linux-core/radeon_legacy_crtc.c index f029c47..d51fc52 100644 --- a/linux-core/radeon_legacy_crtc.c +++ b/linux-core/radeon_legacy_crtc.c @@ -401,7 +401,7 @@ static void radeon_set_pll1(struct drm_crtc *crtc, struct drm_display_mode *mode uint32_t post_divider = 0; uint32_t freq = 0; uint8_t pll_gain; - int pll_flags = RADEON_PLL_LEGACY | RADEON_PLL_PREFER_LOW_REF_DIV; + int pll_flags = RADEON_PLL_LEGACY; bool use_bios_divs = false; /* PLL registers */ uint32_t ppll_ref_div = 0; @@ -431,6 +431,11 @@ static void radeon_set_pll1(struct drm_crtc *crtc, struct drm_display_mode *mode { 0, 0 } }; + if (mode->clock > 120000) /* range limits??? */ + pll_flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; + else + pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { if (encoder->crtc == crtc) { if (encoder->encoder_type != DRM_MODE_ENCODER_DAC) diff --git a/linux-core/radeon_mode.h b/linux-core/radeon_mode.h index 62672c3..d4b33dd 100644 --- a/linux-core/radeon_mode.h +++ b/linux-core/radeon_mode.h @@ -137,11 +137,16 @@ struct radeon_tmds_pll { #define RADEON_MAX_BIOS_CONNECTOR 16 -#define RADEON_PLL_USE_BIOS_DIVS (1 << 0) -#define RADEON_PLL_NO_ODD_POST_DIV (1 << 1) -#define RADEON_PLL_USE_REF_DIV (1 << 2) -#define RADEON_PLL_LEGACY (1 << 3) -#define RADEON_PLL_PREFER_LOW_REF_DIV (1 << 4) +#define RADEON_PLL_USE_BIOS_DIVS (1 << 0) +#define RADEON_PLL_NO_ODD_POST_DIV (1 << 1) +#define RADEON_PLL_USE_REF_DIV (1 << 2) +#define RADEON_PLL_LEGACY (1 << 3) +#define RADEON_PLL_PREFER_LOW_REF_DIV (1 << 4) +#define RADEON_PLL_PREFER_HIGH_REF_DIV (1 << 5) +#define RADEON_PLL_PREFER_LOW_FB_DIV (1 << 6) +#define RADEON_PLL_PREFER_HIGH_FB_DIV (1 << 7) +#define RADEON_PLL_PREFER_LOW_POST_DIV (1 << 8) +#define RADEON_PLL_PREFER_HIGH_POST_DIV (1 << 9) struct radeon_pll { uint16_t reference_freq; diff --git a/linux-core/radeon_reg.h b/linux-core/radeon_reg.h index 113a826..8698e86 100644 --- a/linux-core/radeon_reg.h +++ b/linux-core/radeon_reg.h @@ -3583,7 +3583,7 @@ #define AVIVO_D1CRTC_V_SYNC_B_CNTL 0x6034 #define AVIVO_D1CRTC_CONTROL 0x6080 -# define AVIVO_CRTC_EN (1<<0) +# define AVIVO_CRTC_EN (1 << 0) #define AVIVO_D1CRTC_BLANK_CONTROL 0x6084 #define AVIVO_D1CRTC_INTERLACE_CONTROL 0x6088 #define AVIVO_D1CRTC_INTERLACE_STATUS 0x608c @@ -3595,30 +3595,30 @@ #define AVIVO_D1GRPH_ENABLE 0x6100 #define AVIVO_D1GRPH_CONTROL 0x6104 -# define AVIVO_D1GRPH_CONTROL_DEPTH_8BPP (0<<0) -# define AVIVO_D1GRPH_CONTROL_DEPTH_16BPP (1<<0) -# define AVIVO_D1GRPH_CONTROL_DEPTH_32BPP (2<<0) -# define AVIVO_D1GRPH_CONTROL_DEPTH_64BPP (3<<0) +# define AVIVO_D1GRPH_CONTROL_DEPTH_8BPP (0 << 0) +# define AVIVO_D1GRPH_CONTROL_DEPTH_16BPP (1 << 0) +# define AVIVO_D1GRPH_CONTROL_DEPTH_32BPP (2 << 0) +# define AVIVO_D1GRPH_CONTROL_DEPTH_64BPP (3 << 0) -# define AVIVO_D1GRPH_CONTROL_8BPP_INDEXED (0<<8) +# define AVIVO_D1GRPH_CONTROL_8BPP_INDEXED (0 << 8) -# define AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555 (0<<8) -# define AVIVO_D1GRPH_CONTROL_16BPP_RGB565 (1<<8) -# define AVIVO_D1GRPH_CONTROL_16BPP_ARGB4444 (2<<8) -# define AVIVO_D1GRPH_CONTROL_16BPP_AI88 (3<<8) -# define AVIVO_D1GRPH_CONTROL_16BPP_MONO16 (4<<8) +# define AVIVO_D1GRPH_CONTROL_16BPP_ARGB1555 (0 << 8) +# define AVIVO_D1GRPH_CONTROL_16BPP_RGB565 (1 << 8) +# define AVIVO_D1GRPH_CONTROL_16BPP_ARGB4444 (2 << 8) +# define AVIVO_D1GRPH_CONTROL_16BPP_AI88 (3 << 8) +# define AVIVO_D1GRPH_CONTROL_16BPP_MONO16 (4 << 8) -# define AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888 (0<<8) -# define AVIVO_D1GRPH_CONTROL_32BPP_ARGB2101010 (1<<8) -# define AVIVO_D1GRPH_CONTROL_32BPP_DIGITAL (2<<8) -# define AVIVO_D1GRPH_CONTROL_32BPP_8B_ARGB2101010 (3<<8) +# define AVIVO_D1GRPH_CONTROL_32BPP_ARGB8888 (0 << 8) +# define AVIVO_D1GRPH_CONTROL_32BPP_ARGB2101010 (1 << 8) +# define AVIVO_D1GRPH_CONTROL_32BPP_DIGITAL (2 << 8) +# define AVIVO_D1GRPH_CONTROL_32BPP_8B_ARGB2101010 (3 << 8) -# define AVIVO_D1GRPH_CONTROL_64BPP_ARGB16161616 (0<<8) +# define AVIVO_D1GRPH_CONTROL_64BPP_ARGB16161616 (0 << 8) -# define AVIVO_D1GRPH_SWAP_RB (1<<16) -# define AVIVO_D1GRPH_TILED (1<<20) -# define AVIVO_D1GRPH_MACRO_ADDRESS_MODE (1<<21) +# define AVIVO_D1GRPH_SWAP_RB (1 << 16) +# define AVIVO_D1GRPH_TILED (1 << 20) +# define AVIVO_D1GRPH_MACRO_ADDRESS_MODE (1 << 21) #define AVIVO_D1GRPH_LUT_SEL 0x6108 #define AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 @@ -3644,7 +3644,7 @@ #define AVIVO_D1CUR_POSITION 0x6414 #define AVIVO_D1CUR_HOT_SPOT 0x6418 #define AVIVO_D1CUR_UPDATE 0x6424 -# define AVIVO_D1CURSOR_UPDATE_LOCK (1 << 16) +# define AVIVO_D1CURSOR_UPDATE_LOCK (1 << 16) #define AVIVO_DC_LUT_RW_SELECT 0x6480 #define AVIVO_DC_LUT_RW_MODE 0x6484 @@ -3664,7 +3664,8 @@ #define AVIVO_DC_LUTA_WHITE_OFFSET_GREEN 0x64d4 #define AVIVO_DC_LUTA_WHITE_OFFSET_RED 0x64d8 - +#define AVIVO_D1MODE_DATA_FORMAT 0x6528 +# define AVIVO_D1MODE_INTERLEAVE_EN (1 << 0) #define AVIVO_D1MODE_DESKTOP_HEIGHT 0x652C #define AVIVO_D1MODE_VIEWPORT_START 0x6580 #define AVIVO_D1MODE_VIEWPORT_SIZE 0x6584 @@ -3674,7 +3675,7 @@ #define AVIVO_D1SCL_SCALER_ENABLE 0x6590 #define AVIVO_D1SCL_SCALER_TAP_CONTROL 0x6594 #define AVIVO_D1SCL_UPDATE 0x65cc -# define AVIVO_D1SCL_UPDATE_LOCK (1<<16) +# define AVIVO_D1SCL_UPDATE_LOCK (1 << 16) /* second crtc */ #define AVIVO_D2CRTC_H_TOTAL 0x6800 commit 6988176195450da9033a0f0f21eafc6ae0a7a6a4 Author: Alex Deucher <ale...@gm...> Date: Thu Sep 18 16:42:22 2008 -0400 radeon: Add functions to set mem/eng clocks diff --git a/linux-core/radeon_atombios.c b/linux-core/radeon_atombios.c index 8bf6a7c..4d48593 100644 --- a/linux-core/radeon_atombios.c +++ b/linux-core/radeon_atombios.c @@ -450,6 +450,32 @@ void radeon_atom_static_pwrmgt_setup(struct drm_device *dev, int enable) atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); } +void radeon_atom_set_engine_clock(struct drm_device *dev, int eng_clock) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_mode_info *mode_info = &dev_priv->mode_info; + struct atom_context *ctx = mode_info->atom_context; + SET_ENGINE_CLOCK_PS_ALLOCATION args; + int index = GetIndexIntoMasterTable(COMMAND, SetEngineClock); + + args.ulTargetEngineClock = eng_clock; /* 10 khz */ + + atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); +} + +void radeon_atom_set_memory_clock(struct drm_device *dev, int mem_clock) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_mode_info *mode_info = &dev_priv->mode_info; + struct atom_context *ctx = mode_info->atom_context; + SET_MEMORY_CLOCK_PS_ALLOCATION args; + int index = GetIndexIntoMasterTable(COMMAND, SetMemoryClock); + + args.ulTargetMemoryClock = mem_clock; /* 10 khz */ + + atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args); +} + void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev) { struct drm_radeon_private *dev_priv = dev->dev_private; diff --git a/linux-core/radeon_display.c b/linux-core/radeon_display.c index 7403719..fd0855e 100644 --- a/linux-core/radeon_display.c +++ b/linux-core/radeon_display.c @@ -543,6 +543,51 @@ void radeon_get_clock_info(struct drm_device *dev) } +/* not sure of the best place for these */ +/* 10 khz */ +void radeon_legacy_set_engine_clock(struct drm_device *dev, int eng_clock) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_mode_info *mode_info = &dev_priv->mode_info; + struct radeon_pll *spll = &mode_info->spll; + uint32_t ref_div, fb_div; + uint32_t m_spll_ref_fb_div; + + /* FIXME wait for idle */ + + m_spll_ref_fb_div = RADEON_READ_PLL(dev_priv, RADEON_M_SPLL_REF_FB_DIV); + m_spll_ref_fb_div &= ((RADEON_M_SPLL_REF_DIV_MASK << RADEON_M_SPLL_REF_DIV_SHIFT) | + (RADEON_MPLL_FB_DIV_MASK << RADEON_MPLL_FB_DIV_SHIFT)); + ref_div = m_spll_ref_fb_div & RADEON_M_SPLL_REF_DIV_MASK; + + fb_div = radeon_div(eng_clock * ref_div, spll->reference_freq); + m_spll_ref_fb_div |= (fb_div & RADEON_SPLL_FB_DIV_MASK) << RADEON_SPLL_FB_DIV_SHIFT; + RADEON_WRITE_PLL(dev_priv, RADEON_M_SPLL_REF_FB_DIV, m_spll_ref_fb_div); + +} + +/* 10 khz */ +void radeon_legacy_set_memory_clock(struct drm_device *dev, int mem_clock) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + struct radeon_mode_info *mode_info = &dev_priv->mode_info; + struct radeon_pll *mpll = &mode_info->mpll; + uint32_t ref_div, fb_div; + uint32_t m_spll_ref_fb_div; + + /* FIXME wait for idle */ + + m_spll_ref_fb_div = RADEON_READ_PLL(dev_priv, RADEON_M_SPLL_REF_FB_DIV); + m_spll_ref_fb_div &= ((RADEON_M_SPLL_REF_DIV_MASK << RADEON_M_SPLL_REF_DIV_SHIFT) | + (RADEON_SPLL_FB_DIV_MASK << RADEON_SPLL_FB_DIV_SHIFT)); + ref_div = m_spll_ref_fb_div & RADEON_M_SPLL_REF_DIV_MASK; + + fb_div = radeon_div(mem_clock * ref_div, mpll->reference_freq); + m_spll_ref_fb_div |= (fb_div & RADEON_MPLL_FB_DIV_MASK) << RADEON_MPLL_FB_DIV_SHIFT; + RADEON_WRITE_PLL(dev_priv, RADEON_M_SPLL_REF_FB_DIV, m_spll_ref_fb_div); + +} + static void radeon_user_framebuffer_destroy(struct drm_framebuffer *fb) { struct radeon_framebuffer *radeon_fb = to_radeon_framebuffer(fb); diff --git a/linux-core/radeon_reg.h b/linux-core/radeon_reg.h index c4bc7a8..113a826 100644 --- a/linux-core/radeon_reg.h +++ b/linux-core/radeon_reg.h @@ -1549,6 +1549,13 @@ #define RADEON_SC_TOP_LEFT_C 0x1c88 # define RADEON_SC_SIGN_MASK_LO 0x8000 # define RADEON_SC_SIGN_MASK_HI 0x80000000 +#define RADEON_M_SPLL_REF_FB_DIV 0x000a /* PLL */ +# define RADEON_M_SPLL_REF_DIV_SHIFT 0 +# define RADEON_M_SPLL_REF_DIV_MASK 0xff +# define RADEON_MPLL_FB_DIV_SHIFT 8 +# define RADEON_MPLL_FB_DIV_MASK 0xff +# define RADEON_SPLL_FB_DIV_SHIFT 16 +# define RADEON_SPLL_FB_DIV_MASK 0xff #define RADEON_SCLK_CNTL 0x000d /* PLL */ # define RADEON_SCLK_SRC_SEL_MASK 0x0007 # define RADEON_DYN_STOP_LAT_MASK 0x00007ff8 commit 34af71c42a66e5ef6a9a08250ca541030ca3cc4f Author: Alex Deucher <ale...@gm...> Date: Thu Sep 18 16:07:41 2008 -0400 radeon: add function to configure PCIE lanes diff --git a/linux-core/radeon_pm.c b/linux-core/radeon_pm.c index e9a6130..5d14384 100644 --- a/linux-core/radeon_pm.c +++ b/linux-core/radeon_pm.c @@ -178,3 +178,63 @@ int radeon_resume(struct drm_device *dev) return 0; } + +bool radeon_set_pcie_lanes(struct drm_device *dev, int lanes) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + uint32_t link_width_cntl, mask; + + /* FIXME wait for idle */ + + + switch (lanes) { + case 0: + mask = RADEON_PCIE_LC_LINK_WIDTH_X0; + break; + case 1: + mask = RADEON_PCIE_LC_LINK_WIDTH_X1; + break; + case 2: + mask = RADEON_PCIE_LC_LINK_WIDTH_X2; + break; + case 4: + mask = RADEON_PCIE_LC_LINK_WIDTH_X4; + break; + case 8: + mask = RADEON_PCIE_LC_LINK_WIDTH_X8; + break; + case 12: + mask = RADEON_PCIE_LC_LINK_WIDTH_X12; + break; + case 16: + default: + mask = RADEON_PCIE_LC_LINK_WIDTH_X16; + break; + } + + link_width_cntl = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_LC_LINK_WIDTH_CNTL); + + if ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) == + (mask << RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT)) + return true; + + link_width_cntl &= ~(RADEON_PCIE_LC_LINK_WIDTH_MASK | + RADEON_PCIE_LC_RECONFIG_NOW | + RADEON_PCIE_LC_RECONFIG_LATER | + RADEON_PCIE_LC_SHORT_RECONFIG_EN); + link_width_cntl |= mask; + RADEON_WRITE_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); + RADEON_WRITE_PCIE(RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl | RADEON_PCIE_LC_RECONFIG_NOW); + + /* wait for lane set to complete */ + link_width_cntl = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_LC_LINK_WIDTH_CNTL); + while (link_width_cntl == 0xffffffff) + link_width_cntl = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_LC_LINK_WIDTH_CNTL); + + if ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) == + (mask << RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT)) + return true; + else + return false; +} + diff --git a/linux-core/radeon_reg.h b/linux-core/radeon_reg.h index e7f3081..c4bc7a8 100644 --- a/linux-core/radeon_reg.h +++ b/linux-core/radeon_reg.h @@ -274,6 +274,24 @@ #define RADEON_BUS_CNTL1 0x0034 # define RADEON_BUS_WAIT_ON_LOCK_EN (1 << 4) +//#define RADEON_PCIE_INDEX 0x0030 +//#define RADEON_PCIE_DATA 0x0034 +#define RADEON_PCIE_LC_LINK_WIDTH_CNTL 0xa2 /* PCIE */ +# define RADEON_PCIE_LC_LINK_WIDTH_SHIFT 0 +# define RADEON_PCIE_LC_LINK_WIDTH_MASK 0x7 +# define RADEON_PCIE_LC_LINK_WIDTH_X0 0 +# define RADEON_PCIE_LC_LINK_WIDTH_X1 1 +# define RADEON_PCIE_LC_LINK_WIDTH_X2 2 +# define RADEON_PCIE_LC_LINK_WIDTH_X4 3 +# define RADEON_PCIE_LC_LINK_WIDTH_X8 4 +# define RADEON_PCIE_LC_LINK_WIDTH_X12 5 +# define RADEON_PCIE_LC_LINK_WIDTH_X16 6 +# define RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT 4 +# define RADEON_PCIE_LC_LINK_WIDTH_RD_MASK 0x70 +# define RADEON_PCIE_LC_RECONFIG_NOW (1 << 8) +# define RADEON_PCIE_LC_RECONFIG_LATER (1 << 9) +# define RADEON_PCIE_LC_SHORT_RECONFIG_EN (1 << 10) + #define RADEON_CACHE_CNTL 0x1724 #define RADEON_CACHE_LINE 0x0f0c /* PCI */ #define RADEON_CAPABILITIES_ID 0x0f50 /* PCI */ diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 1ad005b..b934d3b 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -235,7 +235,7 @@ void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t da radeon_pll_errata_after_data(dev_priv); } -static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) +u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr) { RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff); return RADEON_READ(RADEON_PCIE_DATA); diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index 82d9d00..25a07e3 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -1298,6 +1298,7 @@ int radeon_resume(struct drm_device *dev); extern u32 RADEON_READ_PLL(struct drm_radeon_private *dev_priv, int addr); extern void RADEON_WRITE_PLL(struct drm_radeon_private *dev_priv, int addr, uint32_t data); +extern u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr); #define RADEON_WRITE_P(reg, val, mask) \ do { \ commit e1e782af5ddafdd24a4cf741139bb0b8e682e543 Author: Alex Deucher <ale...@gm...> Date: Thu Sep 18 15:11:48 2008 -0400 Radeon: restructure PLL data - store pixel clocks, core clock, and memory clocks separately - grab all pll limits from bios tables diff --git a/linux-core/atombios_crtc.c b/linux-core/atombios_crtc.c index 0a86f36..03077a1 100644 --- a/linux-core/atombios_crtc.c +++ b/linux-core/atombios_crtc.c @@ -163,13 +163,19 @@ void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode *mode, PIXEL_CLOCK_PARAMETERS_V3 *spc3_ptr; uint32_t sclock = mode->clock; uint32_t ref_div = 0, fb_div = 0, post_div = 0; + struct radeon_pll *pll; memset(&spc_param, 0, sizeof(SET_PIXEL_CLOCK_PS_ALLOCATION)); pll_flags |= RADEON_PLL_PREFER_LOW_REF_DIV; - radeon_compute_pll(&dev_priv->mode_info.pll, mode->clock, - &sclock, &fb_div, &ref_div, &post_div, pll_flags); + if (radeon_crtc->crtc_id == 0) + pll = &dev_priv->mode_info.p1pll; + else + pll = &dev_priv->mode_info.p2pll; + + radeon_compute_pll(pll, mode->clock, &sclock, + &fb_div, &ref_div, &post_div, pll_flags); if (radeon_is_avivo(dev_priv)) { uint32_t ss_cntl; @@ -338,6 +344,8 @@ void atombios_crtc_mode_set(struct drm_crtc *crtc, if (radeon_is_avivo(dev_priv)) atombios_crtc_set_base(crtc, x, y); + else + radeon_crtc_set_base(crtc, x, y); atombios_crtc_set_pll(crtc, adjusted_mode, pll_flags); diff --git a/linux-core/radeon_atombios.c b/linux-core/radeon_atombios.c index 4d98cba..8bf6a7c 100644 --- a/linux-core/radeon_atombios.c +++ b/linux-core/radeon_atombios.c @@ -37,7 +37,7 @@ union atom_supported_devices { struct _ATOM_SUPPORTED_DEVICES_INFO_2d1 info_2d1; }; -static inline struct radeon_i2c_bus_rec radeon_lookup_gpio_for_ddc(struct drm_device *dev, uint8_t id) +static inline struct radeon_i2c_bus_rec radeon_lookup_gpio(struct drm_device *dev, uint8_t id) { struct drm_radeon_private *dev_priv = dev->dev_private; struct atom_context *ctx = dev_priv->mode_info.atom_context; @@ -160,13 +160,13 @@ bool radeon_get_atom_connector_info_from_bios_connector_table(struct drm_device (dev_priv->chip_family == CHIP_RS740)) { if ((i == ATOM_DEVICE_DFP2_INDEX) || (i == ATOM_DEVICE_DFP3_INDEX)) mode_info->bios_connector[i].ddc_i2c = - radeon_lookup_gpio_for_ddc(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1); + radeon_lookup_gpio(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux + 1); else mode_info->bios_connector[i].ddc_i2c = - radeon_lookup_gpio_for_ddc(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux); + radeon_lookup_gpio(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux); } else mode_info->bios_connector[i].ddc_i2c = - radeon_lookup_gpio_for_ddc(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux); + radeon_lookup_gpio(dev, ci.sucI2cId.sbfAccess.bfI2C_LineMux); if (i == ATOM_DEVICE_DFP1_INDEX) mode_info->bios_connector[i].tmds_type = TMDS_INT; @@ -277,32 +277,79 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) int index = GetIndexIntoMasterTable(DATA, FirmwareInfo); union firmware_info *firmware_info; uint8_t frev, crev; - struct radeon_pll *pll = &mode_info->pll; + struct radeon_pll *p1pll = &mode_info->p1pll; + struct radeon_pll *p2pll = &mode_info->p2pll; + struct radeon_pll *spll = &mode_info->spll; + struct radeon_pll *mpll = &mode_info->mpll; uint16_t data_offset; atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); firmware_info = (union firmware_info *)(mode_info->atom_context->bios + data_offset); - pll->reference_freq = le16_to_cpu(firmware_info->info.usReferenceClock); - pll->reference_div = 0; + if (firmware_info) { + /* pixel clocks */ + p1pll->reference_freq = le16_to_cpu(firmware_info->info.usReferenceClock); + p1pll->reference_div = 0; - pll->pll_out_min = le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output); - pll->pll_out_max = le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output); + p1pll->pll_out_min = le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Output); + p1pll->pll_out_max = le32_to_cpu(firmware_info->info.ulMaxPixelClockPLL_Output); - if (pll->pll_out_min == 0) { - if (radeon_is_avivo(dev_priv)) - pll->pll_out_min = 64800; - else - pll->pll_out_min = 20000; - } + if (p1pll->pll_out_min == 0) { + if (radeon_is_avivo(dev_priv)) + p1pll->pll_out_min = 64800; + else + p1pll->pll_out_min = 20000; + } - pll->pll_in_min = le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Input); - pll->pll_in_max = le16_to_cpu(firmware_info->info.usMaxPixelClockPLL_Input); + p1pll->pll_in_min = le16_to_cpu(firmware_info->info.usMinPixelClockPLL_Input); + p1pll->pll_in_max = le16_to_cpu(firmware_info->info.usMaxPixelClockPLL_Input); - pll->xclk = le16_to_cpu(firmware_info->info.usMaxPixelClock); + *p2pll = *p1pll; - return true; + /* system clock */ + spll->reference_freq = le16_to_cpu(firmware_info->info.usReferenceClock); + spll->reference_div = 0; + + spll->pll_out_min = le16_to_cpu(firmware_info->info.usMinEngineClockPLL_Output); + spll->pll_out_max = le32_to_cpu(firmware_info->info.ulMaxEngineClockPLL_Output); + + /* ??? */ + if (spll->pll_out_min == 0) { + if (radeon_is_avivo(dev_priv)) + spll->pll_out_min = 64800; + else + spll->pll_out_min = 20000; + } + + spll->pll_in_min = le16_to_cpu(firmware_info->info.usMinEngineClockPLL_Input); + spll->pll_in_max = le16_to_cpu(firmware_info->info.usMaxEngineClockPLL_Input); + + + /* memory clock */ + mpll->reference_freq = le16_to_cpu(firmware_info->info.usReferenceClock); + mpll->reference_div = 0; + + mpll->pll_out_min = le16_to_cpu(firmware_info->info.usMinMemoryClockPLL_Output); + mpll->pll_out_max = le32_to_cpu(firmware_info->info.ulMaxMemoryClockPLL_Output); + + /* ??? */ + if (mpll->pll_out_min == 0) { + if (radeon_is_avivo(dev_priv)) + mpll->pll_out_min = 64800; + else + mpll->pll_out_min = 20000; + } + + mpll->pll_in_min = le16_to_cpu(firmware_info->info.usMinMemoryClockPLL_Input); + mpll->pll_in_max = le16_to_cpu(firmware_info->info.usMaxMemoryClockPLL_Input); + + mode_info->sclk = le32_to_cpu(firmware_info->info.ulDefaultEngineClock); + mode_info->mclk = le32_to_cpu(firmware_info->info.ulDefaultMemoryClock); + + return true; + } + return false; } @@ -322,21 +369,23 @@ void radeon_atombios_get_tmds_info(struct radeon_encoder *encoder) tmds_info = (struct _ATOM_TMDS_INFO *)(mode_info->atom_context->bios + data_offset); - maxfreq = le16_to_cpu(tmds_info->usMaxFrequency); - for (i = 0; i < 4; i++) { - encoder->tmds_pll[i].freq = le16_to_cpu(tmds_info->asMiscInfo[i].usFrequency); - encoder->tmds_pll[i].value = tmds_info->asMiscInfo[i].ucPLL_ChargePump & 0x3f; - encoder->tmds_pll[i].value |= (tmds_info->asMiscInfo[i].ucPLL_VCO_Gain & 0x3f << 6); - encoder->tmds_pll[i].value |= (tmds_info->asMiscInfo[i].ucPLL_DutyCycle & 0xf << 12); - encoder->tmds_pll[i].value |= (tmds_info->asMiscInfo[i].ucPLL_VoltageSwing & 0xf << 16); - - DRM_DEBUG("TMDS PLL From BIOS %u %x\n", - encoder->tmds_pll[i].freq, - encoder->tmds_pll[i].value); - - if (maxfreq == encoder->tmds_pll[i].freq) { - encoder->tmds_pll[i].freq = 0xffffffff; - break; + if (tmds_info) { + maxfreq = le16_to_cpu(tmds_info->usMaxFrequency); + for (i = 0; i < 4; i++) { + encoder->tmds_pll[i].freq = le16_to_cpu(tmds_info->asMiscInfo[i].usFrequency); + encoder->tmds_pll[i].value = tmds_info->asMiscInfo[i].ucPLL_ChargePump & 0x3f; + encoder->tmds_pll[i].value |= (tmds_info->asMiscInfo[i].ucPLL_VCO_Gain & 0x3f << 6); + encoder->tmds_pll[i].value |= (tmds_info->asMiscInfo[i].ucPLL_DutyCycle & 0xf << 12); + encoder->tmds_pll[i].value |= (tmds_info->asMiscInfo[i].ucPLL_VoltageSwing & 0xf << 16); + + DRM_DEBUG("TMDS PLL From BIOS %u %x\n", + encoder->tmds_pll[i].freq, + encoder->tmds_pll[i].value); + + if (maxfreq == encoder->tmds_pll[i].freq) { + encoder->tmds_pll[i].freq = 0xffffffff; + break; + } } } } @@ -360,17 +409,19 @@ void radeon_atombios_get_lvds_info(struct radeon_encoder *encoder) lvds_info = (union lvds_info *)(mode_info->atom_context->bios + data_offset); - encoder->dotclock = le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10; - encoder->panel_xres = le16_to_cpu(lvds_info->info.sLCDTiming.usHActive); - encoder->panel_yres = le16_to_cpu(lvds_info->info.sLCDTiming.usVActive); - encoder->hblank = le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time); - encoder->hoverplus = le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset); - encoder->hsync_width = le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth); - - encoder->vblank = le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time); - encoder->voverplus = le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset); - encoder->vsync_width = le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth); - encoder->panel_pwr_delay = le16_to_cpu(lvds_info->info.usOffDelayInMs); + if (lvds_info) { + encoder->dotclock = le16_to_cpu(lvds_info->info.sLCDTiming.usPixClk) * 10; + encoder->panel_xres = le16_to_cpu(lvds_info->info.sLCDTiming.usHActive); + encoder->panel_yres = le16_to_cpu(lvds_info->info.sLCDTiming.usVActive); + encoder->hblank = le16_to_cpu(lvds_info->info.sLCDTiming.usHBlanking_Time); + encoder->hoverplus = le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncOffset); + encoder->hsync_width = le16_to_cpu(lvds_info->info.sLCDTiming.usHSyncWidth); + + encoder->vblank = le16_to_cpu(lvds_info->info.sLCDTiming.usVBlanking_Time); + encoder->voverplus = le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncOffset); + encoder->vsync_width = le16_to_cpu(lvds_info->info.sLCDTiming.usVSyncWidth); + encoder->panel_pwr_delay = le16_to_cpu(lvds_info->info.usOffDelayInMs); + } } void radeon_atom_dyn_clk_setup(struct drm_device *dev, int enable) diff --git a/linux-core/radeon_combios.c b/linux-core/radeon_combios.c index 3219b99..f1693e6 100644 --- a/linux-core/radeon_combios.c +++ b/linux-core/radeon_combios.c @@ -73,7 +73,7 @@ enum radeon_combios_table_offset COMBIOS_ASIC_INIT_4_TABLE, /* offset from misc info */ COMBIOS_ASIC_INIT_5_TABLE, /* offset from misc info */ COMBIOS_RAM_RESET_TABLE, /* offset from mem config */ - COMBIOS_POWERPLAY_TABLE, /* offset from mobile info */ + COMBIOS_POWERPLAY_INFO_TABLE, /* offset from mobile info */ COMBIOS_GPIO_INFO_TABLE, /* offset from mobile info */ COMBIOS_LCD_DDC_INFO_TABLE, /* offset from mobile info */ COMBIOS_TMDS_POWER_TABLE, /* offset from mobile info */ @@ -325,7 +325,7 @@ static uint16_t combios_get_table_offset(struct drm_device *dev, enum radeon_com offset = check_offset; } break; - case COMBIOS_POWERPLAY_TABLE: /* offset from mobile info */ + case COMBIOS_POWERPLAY_INFO_TABLE: /* offset from mobile info */ check_offset = combios_get_table_offset(dev, COMBIOS_MOBILE_INFO_TABLE); if (check_offset) { check_offset = radeon_bios16(dev_priv, check_offset + 0x11); @@ -427,33 +427,72 @@ bool radeon_combios_get_clock_info(struct drm_device *dev) struct drm_radeon_private *dev_priv = dev->dev_private; struct radeon_mode_info *mode_info = &dev_priv->mode_info; uint16_t pll_info; - struct radeon_pll *pll = &mode_info->pll; + struct radeon_pll *p1pll = &mode_info->p1pll; + struct radeon_pll *p2pll = &mode_info->p2pll; + struct radeon_pll *spll = &mode_info->spll; + struct radeon_pll *mpll = &mode_info->mpll; int8_t rev; + uint16_t sclk, mclk; pll_info = combios_get_table_offset(dev, COMBIOS_PLL_INFO_TABLE); if (pll_info) { rev = radeon_bios8(dev_priv, pll_info); - pll->reference_freq = radeon_bios16(dev_priv, pll_info + 0xe); - pll->reference_div = radeon_bios16(dev_priv, pll_info + 0x10); - pll->pll_out_min = radeon_bios32(dev_priv, pll_info + 0x12); - pll->pll_out_max = radeon_bios32(dev_priv, pll_info + 0x16); + /* pixel clocks */ + p1pll->reference_freq = radeon_bios16(dev_priv, pll_info + 0xe); + p1pll->reference_div = radeon_bios16(dev_priv, pll_info + 0x10); + p1pll->pll_out_min = radeon_bios32(dev_priv, pll_info + 0x12); + p1pll->pll_out_max = radeon_bios32(dev_priv, pll_info + 0x16); if (rev > 9) { - pll->pll_in_min = radeon_bios32(dev_priv, pll_info + 0x36); - pll->pll_in_max = radeon_bios32(dev_priv, pll_info + 0x3a); + p1pll->pll_in_min = radeon_bios32(dev_priv, pll_info + 0x36); + p1pll->pll_in_max = radeon_bios32(dev_priv, pll_info + 0x3a); } else { - pll->pll_in_min = 40; - pll->pll_in_max = 500; + p1pll->pll_in_min = 40; + p1pll->pll_in_max = 500; } + *p2pll = *p1pll; - pll->xclk = radeon_bios16(dev_priv, pll_info + 0x08); + /* system clock */ + spll->reference_freq = radeon_bios16(dev_priv, pll_info + 0x1a); + spll->reference_div = radeon_bios16(dev_priv, pll_info + 0x1c); + spll->pll_out_min = radeon_bios32(dev_priv, pll_info + 0x1e); + spll->pll_out_max = radeon_bios32(dev_priv, pll_info + 0x22); - // sclk/mclk use fixed point - //sclk = radeon_bios16(pll_info + 8) / 100.0; - //mclk = radeon_bios16(pll_info + 10) / 100.0; - //if (sclk == 0) sclk = 200; - //if (mclk == 0) mclk = 200; + if (rev > 10) { + spll->pll_in_min = radeon_bios32(dev_priv, pll_info + 0x48); + spll->pll_in_max = radeon_bios32(dev_priv, pll_info + 0x4c); + } else { + /* ??? */ + spll->pll_in_min = 40; + spll->pll_in_max = 500; + } + + /* memory clock */ + mpll->reference_freq = radeon_bios16(dev_priv, pll_info + 0x26); + mpll->reference_div = radeon_bios16(dev_priv, pll_info + 0x28); + mpll->pll_out_min = radeon_bios32(dev_priv, pll_info + 0x2a); + mpll->pll_out_max = radeon_bios32(dev_priv, pll_info + 0x2e); + + if (rev > 10) { + mpll->pll_in_min = radeon_bios32(dev_priv, pll_info + 0x5a); + mpll->pll_in_max = radeon_bios32(dev_priv, pll_info + 0x5e); + } else { + /* ??? */ + mpll->pll_in_min = 40; + mpll->pll_in_max = 500; + } + + /* default sclk/mclk */ + sclk = radeon_bios16(dev_priv, pll_info + 0x8); + mclk = radeon_bios16(dev_priv, pll_info + 0xa); + if (sclk == 0) + sclk = 200; + if (mclk == 0) + mclk = 200; + + mode_info->sclk = sclk; + mode_info->mclk = mclk; return true; } diff --git a/linux-core/radeon_display.c b/linux-core/radeon_display.c index c532ef0..7403719 100644 --- a/linux-core/radeon_display.c +++ b/linux-core/radeon_display.c @@ -396,7 +396,10 @@ void radeon_compute_pll(struct radeon_pll *pll, (post_div == 7) || (post_div == 9) || (post_div == 10) || - (post_div == 11)) + (post_div == 11) || + (post_div == 13) || + (post_div == 14) || + (post_div == 15)) continue; } @@ -475,7 +478,10 @@ void radeon_compute_pll(struct radeon_pll *pll, void radeon_get_clock_info(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev->dev_private; - struct radeon_pll *pll = &dev_priv->mode_info.pll; + struct radeon_pll *p1pll = &dev_priv->mode_info.p1pll; + struct radeon_pll *p2pll = &dev_priv->mode_info.p2pll; + struct radeon_pll *spll = &dev_priv->mode_info.spll; + struct radeon_pll *mpll = &dev_priv->mode_info.mpll; int ret; if (dev_priv->is_atom_bios) @@ -484,25 +490,56 @@ void radeon_get_clock_info(struct drm_device *dev) ret = radeon_combios_get_clock_info(dev); if (ret) { - - if (pll->reference_div < 2) pll->reference_div = 12; + if (p1pll->reference_div < 2) + p1pll->reference_div = 12; + if (p2pll->reference_div < 2) + p2pll->reference_div = 12; } else { // TODO FALLBACK } + /* pixel clocks */ if (radeon_is_avivo(dev_priv)) { - pll->min_post_div = 2; - pll->max_post_div = 0x7f; + p1pll->min_post_div = 2; + p1pll->max_post_div = 0x7f; + p2pll->min_post_div = 2; + p2pll->max_post_div = 0x7f; } else { - pll->min_post_div = 1; - pll->max_post_div = 12; // 16 on crtc 0?? + p1pll->min_post_div = 1; + p1pll->max_post_div = 16; + p2pll->min_post_div = 1; + p2pll->max_post_div = 12; } - pll->min_ref_div = 2; - pll->max_ref_div = 0x3ff; - pll->min_feedback_div = 4; - pll->max_feedback_div = 0x7ff; - pll->best_vco = 0; + p1pll->min_ref_div = 2; + p1pll->max_ref_div = 0x3ff; + p1pll->min_feedback_div = 4; + p1pll->max_feedback_div = 0x7ff; + p1pll->best_vco = 0; + + p2pll->min_ref_div = 2; + p2pll->max_ref_div = 0x3ff; + p2pll->min_feedback_div = 4; + p2pll->max_feedback_div = 0x7ff; + p2pll->best_vco = 0; + + /* system clock */ + spll->min_post_div = 1; + spll->max_post_div = 1; + spll->min_ref_div = 2; + spll->max_ref_div = 0xff; + spll->min_feedback_div = 4; + spll->max_feedback_div = 0xff; + spll->best_vco = 0; + + /* memory clock */ + mpll->min_post_div = 1; + mpll->max_post_div = 1; + mpll->min_ref_div = 2; + mpll->max_ref_div = 0xff; + mpll->min_feedback_div = 4; + mpll->max_feedback_div = 0xff; + mpll->best_vco = 0; } diff --git a/linux-core/radeon_legacy_crtc.c b/linux-core/radeon_legacy_crtc.c index 58c2f9d..f029c47 100644 --- a/linux-core/radeon_legacy_crtc.c +++ b/linux-core/radeon_legacy_crtc.c @@ -409,7 +409,7 @@ static void radeon_set_pll1(struct drm_crtc *crtc, struct drm_display_mode *mode uint32_t htotal_cntl = 0; uint32_t vclk_ecp_cntl; - struct radeon_pll *pll = &dev_priv->mode_info.pll; + struct radeon_pll *pll = &dev_priv->mode_info.p1pll; struct { int divider; @@ -485,7 +485,7 @@ static void radeon_set_pll1(struct drm_crtc *crtc, struct drm_display_mode *mode vclk_ecp_cntl = (RADEON_READ_PLL(dev_priv, RADEON_VCLK_ECP_CNTL) & ~RADEON_VCLK_SRC_SEL_MASK) | RADEON_VCLK_SRC_SEL_PPLLCLK; - pll_gain = radeon_compute_pll_gain(dev_priv->mode_info.pll.reference_freq, + pll_gain = radeon_compute_pll_gain(dev_priv->mode_info.p1pll.reference_freq, ppll_ref_div & RADEON_PPLL_REF_DIV_MASK, ppll_div_3 & RADEON_PPLL_FB3_DIV_MASK); @@ -812,7 +812,7 @@ static void radeon_set_pll2(struct drm_crtc *crtc, struct drm_display_mode *mode uint32_t htotal_cntl2 = 0; uint32_t pixclks_cntl; - struct radeon_pll *pll = &dev_priv->mode_info.pll; + struct radeon_pll *pll = &dev_priv->mode_info.p2pll; struct { int divider; @@ -882,7 +882,7 @@ static void radeon_set_pll2(struct drm_crtc *crtc, struct drm_display_mode *mode ~(RADEON_PIX2CLK_SRC_SEL_MASK)) | RADEON_PIX2CLK_SRC_SEL_P2PLLCLK); - pll_gain = radeon_compute_pll_gain(dev_priv->mode_info.pll.reference_freq, + pll_gain = radeon_compute_pll_gain(dev_priv->mode_info.p2pll.reference_freq, p2pll_ref_div & RADEON_P2PLL_REF_DIV_MASK, p2pll_div_0 & RADEON_P2PLL_FB0_DIV_MASK); diff --git a/linux-core/radeon_mode.h b/linux-core/radeon_mode.h index a4ee78a..62672c3 100644 --- a/linux-core/radeon_mode.h +++ b/linux-core/radeon_mode.h @@ -161,10 +161,22 @@ struct radeon_pll { uint32_t best_vco; }; +struct radeon_i2c_chan { + struct drm_device *dev; + struct i2c_adapter adapter; + struct i2c_algo_bit_data algo; + struct radeon_i2c_bus_rec rec; +}; + struct radeon_mode_info { struct atom_context *atom_context; struct radeon_bios_connector bios_connector[RADEON_MAX_BIOS_CONNECTOR]; - struct radeon_pll pll; + struct radeon_pll p1pll; + struct radeon_pll p2pll; + struct radeon_pll spll; + struct radeon_pll mpll; + uint32_t mclk; + uint32_t sclk; }; struct radeon_crtc { @@ -178,14 +190,6 @@ struct radeon_crtc { struct drm_mode_set mode_set; }; -struct radeon_i2c_chan { - struct drm_device *dev; - struct i2c_adapter adapter; - struct i2c_algo_bit_data algo; - struct radeon_i2c_bus_rec rec; -}; - - #define RADEON_USE_RMX 1 struct radeon_encoder { @@ -278,6 +282,8 @@ extern void atombios_crtc_mode_set(struct drm_crtc *crtc, int x, int y); extern void atombios_crtc_dpms(struct drm_crtc *crtc, int mode); +extern void radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y); + extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, uint32_t handle, diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 6c5bf03..1ad005b 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2506,8 +2506,6 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) else dev_priv->flags |= RADEON_IS_PCI; - - DRM_DEBUG("%s card detected\n", ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); @@ -2527,7 +2525,7 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) if (dev_priv->chip_family == CHIP_R300 && (RADEON_READ(RADEON_CONFIG_CNTL) & RADEON_CFG_ATI_REV_ID_MASK) == RADEON_CFG_ATI_REV_A11) dev_priv->pll_errata |= CHIP_ERRATA_R300_CG; - + if (dev_priv->chip_family == CHIP_RV200 || dev_priv->chip_family == CHIP_RS200) dev_priv->pll_errata |= CHIP_ERRATA_PLL_DUMMYREADS; |
From: <gl...@ke...> - 2008-11-05 23:41:19
|
libdrm/radeon/Makefile.am | 9 - libdrm/radeon/radeon_bo.h | 36 +++-- libdrm/radeon/radeon_bo_gem.c | 76 +++++++----- libdrm/radeon/radeon_bo_gem.h | 3 libdrm/radeon/radeon_cs_gem.c | 266 ++++++++++++++++++++++++++++++++++++++++++ libdrm/radeon/radeon_cs_gem.h | 40 ++++++ linux-core/drm_gem.c | 3 7 files changed, 384 insertions(+), 49 deletions(-) New commits: commit 273cc1a69887df2bccfab96120f992c506c9035e Author: Jerome Glisse <gl...@fr...> Date: Thu Nov 6 00:40:06 2008 +0100 radeon: lib radeon add bo & cs gem backend diff --git a/libdrm/radeon/Makefile.am b/libdrm/radeon/Makefile.am index 6af06a7..cc4951a 100644 --- a/libdrm/radeon/Makefile.am +++ b/libdrm/radeon/Makefile.am @@ -35,9 +35,12 @@ libdrm_radeon_la_LDFLAGS = -version-number 1:0:0 -no-undefined libdrm_radeon_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@ libdrm_radeon_la_SOURCES = \ - radeon_bo_gem.c + radeon_bo_gem.c \ + radeon_cs_gem.c -libdrm_radeonincludedir = ${includedir} +libdrm_radeonincludedir = ${includedir}/drm libdrm_radeoninclude_HEADERS = \ radeon_bo.h \ - radeon_cs.h + radeon_cs.h \ + radeon_bo_gem.h \ + radeon_cs_gem.h diff --git a/libdrm/radeon/radeon_bo.h b/libdrm/radeon/radeon_bo.h index c1f25fa..a073926 100644 --- a/libdrm/radeon/radeon_bo.h +++ b/libdrm/radeon/radeon_bo.h @@ -42,6 +42,7 @@ struct radeon_bo { uint32_t alignment; uint32_t handle; uint32_t size; + uint32_t domains; uint32_t flags; unsigned cref; void *ptr; @@ -54,6 +55,7 @@ struct radeon_bo_funcs { uint32_t handle, uint32_t size, uint32_t alignment, + uint32_t domains, uint32_t flags); void (*bo_ref)(struct radeon_bo *bo); void (*bo_unref)(struct radeon_bo *bo); @@ -80,13 +82,14 @@ static inline struct radeon_bo *_radeon_bo_open(struct radeon_bo_manager *bom, uint32_t handle, uint32_t size, uint32_t alignment, + uint32_t domains, uint32_t flags, const char *file, const char *func, int line) { struct radeon_bo *bo; - bo = bom->funcs->bo_open(bom, handle, size, alignment, flags); + bo = bom->funcs->bo_open(bom, handle, size, alignment, domains, flags); #ifdef RADEON_BO_TRACK_OPEN if (bo) { _radeon_bo_debug(bo, 1, file, func, line); @@ -142,8 +145,8 @@ static inline int _radeon_bo_unmap(struct radeon_bo *bo, return bo->bom->funcs->bo_unmap(bo); } -#define radeon_bo_open(bom, h, s, a, f)\ - _radeon_bo_open(bom, h, s, a, f, __FILE__, __FUNCTION__, __LINE__) +#define radeon_bo_open(bom, h, s, a, d, f)\ + _radeon_bo_open(bom, h, s, a, d, f, __FILE__, __FUNCTION__, __LINE__) #define radeon_bo_ref(bo)\ _radeon_bo_ref(bo, __FILE__, __FUNCTION__, __LINE__) #define radeon_bo_unref(bo)\ diff --git a/libdrm/radeon/radeon_bo_gem.c b/libdrm/radeon/radeon_bo_gem.c index 21fe41f..04e36c5 100644 --- a/libdrm/radeon/radeon_bo_gem.c +++ b/libdrm/radeon/radeon_bo_gem.c @@ -42,14 +42,19 @@ struct radeon_bo_gem { struct radeon_bo base; - int ref_count; + uint32_t name; int map_count; }; +struct bo_manager_gem { + struct radeon_bo_manager base; +}; + static struct radeon_bo *bo_open(struct radeon_bo_manager *bom, uint32_t handle, uint32_t size, uint32_t alignment, + uint32_t domains, uint32_t flags) { struct radeon_bo_gem *bo; @@ -64,11 +69,10 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom, bo->base.handle = 0; bo->base.size = size; bo->base.alignment = alignment; + bo->base.domains = domains; bo->base.flags = flags; bo->base.ptr = NULL; - bo->ref_count = 0; bo->map_count = 0; - if (handle) { struct drm_gem_open open_arg; @@ -80,13 +84,15 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom, free(bo); return NULL; } - bo->base.handle = handle; + bo->base.handle = open_arg.handle; + bo->base.size = open_arg.size; + bo->name = handle; } else { struct drm_radeon_gem_create args; args.size = size; args.alignment = alignment; - args.initial_domain = RADEON_GEM_DOMAIN_CPU; + args.initial_domain = bo->base.domains; args.no_backing_store = 0; r = drmCommandWriteRead(bom->fd, DRM_RADEON_GEM_CREATE, &args, sizeof(args)); @@ -99,7 +105,11 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom, return (struct radeon_bo*)bo; } -static void bo_close(struct radeon_bo *bo) +static void bo_ref(struct radeon_bo *bo) +{ +} + +static void bo_unref(struct radeon_bo *bo) { struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo; struct drm_gem_close args; @@ -107,10 +117,10 @@ static void bo_close(struct radeon_bo *bo) if (bo == NULL) { return; } - if (bo_gem->ref_count) { + if (bo->cref) { /* FIXME: what to do ? */ + return; } - if (bo_gem->map_count) { munmap(bo->ptr, bo->size); } @@ -121,33 +131,20 @@ static void bo_close(struct radeon_bo *bo) free(bo_gem); } -static void bo_pin(struct radeon_bo *bo) -{ - struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo; - - bo_gem->ref_count++; -} - -static void bo_unpin(struct radeon_bo *bo) -{ - struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo; - - bo_gem->ref_count--; -} - -static int bo_map(struct radeon_bo *bo, unsigned int flags) +static int bo_map(struct radeon_bo *bo, int write) { struct radeon_bo_gem *bo_gem = (struct radeon_bo_gem*)bo; struct drm_radeon_gem_mmap args; int r; + uint8_t *tt; if (bo_gem->map_count++ != 0) { return 0; } + bo->ptr = NULL; args.handle = bo->handle; args.offset = 0; - args.size = bo->size; - + args.size = (uint64_t)bo->size; r = drmCommandWriteRead(bo->bom->fd, DRM_RADEON_GEM_MMAP, &args, @@ -155,6 +152,7 @@ static int bo_map(struct radeon_bo *bo, unsigned int flags) if (!r) { bo->ptr = (void *)(unsigned long)args.addr_ptr; } + tt = bo->ptr; return r; } @@ -165,7 +163,6 @@ static int bo_unmap(struct radeon_bo *bo) if (--bo_gem->map_count > 0) { return 0; } - munmap(bo->ptr, bo->size); bo->ptr = NULL; return 0; @@ -173,14 +170,31 @@ static int bo_unmap(struct radeon_bo *bo) static struct radeon_bo_funcs bo_gem_funcs = { bo_open, - bo_close, - bo_pin, - bo_unpin, + bo_ref, + bo_unref, bo_map, bo_unmap }; -struct radeon_bo_funcs *radeon_bo_gem_initialize(int fd) +struct radeon_bo_manager *radeon_bo_manager_gem(int fd) { - return &bo_gem_funcs; + struct bo_manager_gem *bomg; + + bomg = (struct bo_manager_gem*)calloc(1, sizeof(struct bo_manager_gem)); + if (bomg == NULL) { + return NULL; + } + bomg->base.funcs = &bo_gem_funcs; + bomg->base.fd = fd; + return (struct radeon_bo_manager*)bomg; +} + +void radeon_bo_manager_gem_shutdown(struct radeon_bo_manager *bom) +{ + struct bo_manager_gem *bomg = (struct bo_manager_gem*)bom; + + if (bom == NULL) { + return; + } + free(bomg); } diff --git a/libdrm/radeon/radeon_bo_gem.h b/libdrm/radeon/radeon_bo_gem.h index e0ed61f..d099761 100644 --- a/libdrm/radeon/radeon_bo_gem.h +++ b/libdrm/radeon/radeon_bo_gem.h @@ -33,6 +33,7 @@ #include "radeon_bo.h" -struct radeon_bo_funcs *radeon_bo_gem_initialize(int fd); +struct radeon_bo_manager *radeon_bo_manager_gem(int fd); +void radeon_bo_manager_gem_shutdown(struct radeon_bo_manager *bom); #endif diff --git a/libdrm/radeon/radeon_cs_gem.c b/libdrm/radeon/radeon_cs_gem.c new file mode 100644 index 0000000..7ed5780 --- /dev/null +++ b/libdrm/radeon/radeon_cs_gem.c @@ -0,0 +1,266 @@ +/* + * Copyright © 2008 Jérôme Glisse + * All Rights Reserved. + * + * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Jérôme Glisse <gl...@fr...> + */ +#include <errno.h> +#include <stdlib.h> +#include "radeon_cs.h" +#include "radeon_cs_gem.h" +#include "radeon_bo_gem.h" +#include "drm.h" +#include "radeon_drm.h" + +#pragma pack(1) +struct cs_reloc_gem { + uint32_t handle; + uint32_t domains; + uint32_t soffset; + uint32_t eoffset; +}; +#pragma pack() + +struct cs_gem { + struct radeon_cs base; + struct drm_radeon_cs2 cs; + struct drm_radeon_cs_chunk chunks[2]; + unsigned nrelocs; + uint32_t *relocs; +}; + +static struct radeon_cs *cs_create(struct radeon_cs_manager *csm, + uint32_t ndw) +{ + struct cs_gem *csg; + + /* max cmd buffer size is 64Kb */ + if (ndw > (64 * 1024 / 4)) { + return NULL; + } + csg = (struct cs_gem*)calloc(1, sizeof(struct cs_gem)); + if (csg == NULL) { + return NULL; + } + csg->base.csm = csm; + csg->base.ndw = 64 * 1024 / 4; + csg->base.packets = (uint32_t*)calloc(1, 64 * 1024); + if (csg->base.packets == NULL) { + free(csg); + return NULL; + } + csg->base.relocs_total_size = 0; + csg->base.crelocs = 0; + csg->nrelocs = 4096 / (4 * 4) ; + csg->base.relocs = csg->relocs = (uint32_t*)calloc(1, 4096); + if (csg->relocs == NULL) { + free(csg->base.packets); + free(csg); + return NULL; + } + csg->chunks[0].chunk_id = RADEON_CHUNK_ID_IB; + csg->chunks[0].length_dw = 0; + csg->chunks[0].chunk_data = (uint64_t)(intptr_t)csg->base.packets; + csg->chunks[1].chunk_id = RADEON_CHUNK_ID_RELOCS; + csg->chunks[1].length_dw = 0; + csg->chunks[1].chunk_data = (uint64_t)(intptr_t)csg->relocs; + return (struct radeon_cs*)csg; +} + +static int cs_write_dword(struct radeon_cs *cs, uint32_t dword) +{ + if (cs->cdw >= cs->ndw) { + uint32_t tmp, *ptr; + tmp = (cs->cdw + 1 + 0x3FF) & (~0x3FF); + ptr = (uint32_t*)realloc(cs->packets, 4 * tmp); + if (ptr == NULL) { + return -ENOMEM; + } + cs->packets = ptr; + cs->ndw = tmp; + } + cs->packets[cs->cdw++] = dword; + if (cs->section) { + cs->section_cdw++; + } + return 0; +} + +static int cs_write_reloc(struct radeon_cs *cs, + struct radeon_bo *bo, + uint32_t soffset, + uint32_t eoffset, + uint32_t domains) +{ + struct cs_gem *csg = (struct cs_gem*)cs; + struct cs_reloc_gem *reloc; + unsigned i; + + /* check reloc window */ + if (eoffset > bo->size) { + return -EINVAL; + } + if (soffset > eoffset) { + return -EINVAL; + } + /* check if bo is already referenced */ + for(i = 0; i < cs->crelocs; i++) { + reloc = (struct cs_reloc_gem*)&csg->relocs[i * 4]; + + if (reloc->handle == bo->handle) { + /* update start offset and size */ + if (eoffset > reloc->eoffset) { + reloc->eoffset = eoffset; + } + if (soffset < reloc->soffset) { + reloc->soffset = soffset; + } + reloc->domains |= domains; + return 0; + } + } + /* add bo */ + if (csg->base.crelocs >= csg->nrelocs) { + uint32_t *tmp, size; + size = (csg->nrelocs * 4 * 4) + (4096 / (4 * 4)); + tmp = (uint32_t*)realloc(csg->relocs, size); + if (tmp == NULL) { + return -ENOMEM; + } + cs->relocs = csg->relocs = tmp; + csg->nrelocs = size / (4 * 4); + } + reloc = (struct cs_reloc_gem*)&csg->relocs[csg->base.crelocs * 4]; + reloc->handle = bo->handle; + reloc->soffset = soffset; + reloc->eoffset = eoffset; + reloc->domains = domains; + cs->crelocs++; + radeon_bo_ref(bo); + return 0; +} + +static int cs_begin(struct radeon_cs *cs, + uint32_t ndw, + const char *file, + const char *func, + int line) +{ + if (cs->section) { + fprintf(stderr, "CS already in a section(%s,%s,%d)\n", + cs->section_file, cs->section_func, cs->section_line); + fprintf(stderr, "CS can't start section(%s,%s,%d)\n", + file, func, line); + return -EPIPE; + } + cs->section = 1; + cs->section_ndw = ndw; + cs->section_cdw = 0; + cs->section_file = file; + cs->section_func = func; + cs->section_line = line; + return 0; +} + +static int cs_end(struct radeon_cs *cs, + const char *file, + const char *func, + int line) + +{ + if (!cs->section) { + fprintf(stderr, "CS no section to end at (%s,%s,%d)\n", + file, func, line); + return -EPIPE; + } + cs->section = 0; + if (cs->section_ndw != cs->section_cdw) { + fprintf(stderr, "CS section size missmatch start at (%s,%s,%d)\n", + cs->section_file, cs->section_func, cs->section_line); + fprintf(stderr, "CS section end at (%s,%s,%d)\n", + file, func, line); + return -EPIPE; + } + return 0; +} + +static int cs_emit(struct radeon_cs *cs) +{ + return 0; +} + +static int cs_destroy(struct radeon_cs *cs) +{ + free(cs->relocs); + free(cs->packets); + free(cs); + return 0; +} + +static int cs_erase(struct radeon_cs *cs) +{ + cs->relocs_total_size = 0; + cs->relocs = NULL; + cs->crelocs = 0; + cs->cdw = 0; + cs->section = 0; + return 0; +} + +static int cs_need_flush(struct radeon_cs *cs) +{ + return (cs->relocs_total_size > (7*1024*1024)); +} + +struct radeon_cs_funcs radeon_cs_funcs = { + cs_create, + cs_write_dword, + cs_write_reloc, + cs_begin, + cs_end, + cs_emit, + cs_destroy, + cs_erase, + cs_need_flush +}; + +struct radeon_cs_manager *radeon_cs_manager_gem(int fd) +{ + struct radeon_cs_manager *csm; + + csm = (struct radeon_cs_manager*)calloc(1, + sizeof(struct radeon_cs_manager)); + if (csm == NULL) { + return NULL; + } + csm->funcs = &radeon_cs_funcs; + csm->fd = fd; + return csm; +} + +void radeon_cs_manager_gem_shutdown(struct radeon_cs_manager *csm) +{ + free(csm); +} diff --git a/libdrm/radeon/radeon_cs_gem.h b/libdrm/radeon/radeon_cs_gem.h new file mode 100644 index 0000000..a032a8c --- /dev/null +++ b/libdrm/radeon/radeon_cs_gem.h @@ -0,0 +1,40 @@ +/* + * Copyright © 2008 Nicolai Haehnle + * Copyright © 2008 Jérôme Glisse + * All Rights Reserved. + * + * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS 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. + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + */ +/* + * Authors: + * Aapo Tahkola <ae...@ra...> + * Nicolai Haehnle <pre...@gm...> + * Jérôme Glisse <gl...@fr...> + */ +#ifndef RADEON_CS_GEM_H +#define RADEON_CS_GEM_H + +#include "radeon_cs.h" + +struct radeon_cs_manager *radeon_cs_manager_gem(int fd); +void radeon_cs_manager_gem_shutdown(struct radeon_cs_manager *csm); + +#endif diff --git a/linux-core/drm_gem.c b/linux-core/drm_gem.c index 0cbf9ca..607c8b6 100644 --- a/linux-core/drm_gem.c +++ b/linux-core/drm_gem.c @@ -263,8 +263,9 @@ again: spin_lock(&dev->object_name_lock); if (obj->name) { + args->name = (uint64_t) obj->name; spin_unlock(&dev->object_name_lock); - return -EEXIST; + return 0; } ret = idr_get_new_above(&dev->object_name_idr, obj, 1, &obj->name); commit 2d822542c74c9a38d18724f568642397b5a4d13d Author: Jerome Glisse <gl...@fr...> Date: Wed Nov 5 16:00:04 2008 +0100 radeon: libdrm_radeon add handle to debug string diff --git a/libdrm/radeon/radeon_bo.h b/libdrm/radeon/radeon_bo.h index 68adc3e..c1f25fa 100644 --- a/libdrm/radeon/radeon_bo.h +++ b/libdrm/radeon/radeon_bo.h @@ -72,8 +72,8 @@ static inline void _radeon_bo_debug(struct radeon_bo *bo, const char *func, int line) { - fprintf(stderr, "%02d %p 0x%08X 0x%08X [%s %s %d]\n", - opcode, bo, bo->size, bo->cref, file, func, line); + fprintf(stderr, "%02d %p 0x%08X 0x%08X 0x%08X [%s %s %d]\n", + opcode, bo, bo->handle, bo->size, bo->cref, file, func, line); } static inline struct radeon_bo *_radeon_bo_open(struct radeon_bo_manager *bom, commit ddfb12b32e64d00d302f7fbb36fb079deec3646f Merge: 7651b4c... 68fcb77... Author: Jerome Glisse <gl...@fr...> Date: Wed Nov 5 15:59:37 2008 +0100 Merge branch 'modesetting-gem' of ssh://git.freedesktop.org/git/mesa/drm into modesetting-gem commit 7651b4c424aa6c6ac6c47b2d07c8f65d0b9d0191 Author: Jerome Glisse <gl...@fr...> Date: Sun Nov 2 16:00:06 2008 +0100 radeon: debug bo diff --git a/libdrm/radeon/radeon_bo.h b/libdrm/radeon/radeon_bo.h index 00dd521..68adc3e 100644 --- a/libdrm/radeon/radeon_bo.h +++ b/libdrm/radeon/radeon_bo.h @@ -65,6 +65,16 @@ struct radeon_bo_manager { struct radeon_bo_funcs *funcs; int fd; }; + +static inline void _radeon_bo_debug(struct radeon_bo *bo, + int opcode, + const char *file, + const char *func, + int line) +{ + fprintf(stderr, "%02d %p 0x%08X 0x%08X [%s %s %d]\n", + opcode, bo, bo->size, bo->cref, file, func, line); +} static inline struct radeon_bo *_radeon_bo_open(struct radeon_bo_manager *bom, uint32_t handle, @@ -79,8 +89,7 @@ static inline struct radeon_bo *_radeon_bo_open(struct radeon_bo_manager *bom, bo = bom->funcs->bo_open(bom, handle, size, alignment, flags); #ifdef RADEON_BO_TRACK_OPEN if (bo) { - fprintf(stderr, "+open (%p, %d, %d) at (%s, %s, %d)\n", - bo, bo->size, bo->cref, file, func, line); + _radeon_bo_debug(bo, 1, file, func, line); } #endif return bo; @@ -93,8 +102,7 @@ static inline void _radeon_bo_ref(struct radeon_bo *bo, { bo->cref++; #ifdef RADEON_BO_TRACK_REF - fprintf(stderr, "+ref (%p, %d, %d) at (%s, %s, %d)\n", - bo, bo->size, bo->cref, file, func, line); + _radeon_bo_debug(bo, 2, file, func, line); #endif bo->bom->funcs->bo_ref(bo); } @@ -106,8 +114,7 @@ static inline void _radeon_bo_unref(struct radeon_bo *bo, { bo->cref--; #ifdef RADEON_BO_TRACK_REF - fprintf(stderr, "-unref(%p, %d, %d) at (%s, %s, %d)\n", - bo, bo->size, bo->cref, file, func, line); + _radeon_bo_debug(bo, 3, file, func, line); #endif bo->bom->funcs->bo_unref(bo); } @@ -119,8 +126,7 @@ static inline int _radeon_bo_map(struct radeon_bo *bo, int line) { #ifdef RADEON_BO_TRACK_MAP - fprintf(stderr, "+map (%p, %d, %d) at (%s, %s, %d)\n", - bo, bo->size, bo->cref, file, func, line); + _radeon_bo_debug(bo, 4, file, func, line); #endif return bo->bom->funcs->bo_map(bo, write); } @@ -131,8 +137,7 @@ static inline int _radeon_bo_unmap(struct radeon_bo *bo, int line) { #ifdef RADEON_BO_TRACK_MAP - fprintf(stderr, "-unmap(%p, %d, %d) at (%s, %s, %d)\n", - bo, bo->size, bo->cref, file, func, line); + _radeon_bo_debug(bo, 5, file, func, line); #endif return bo->bom->funcs->bo_unmap(bo); } @@ -147,5 +152,7 @@ static inline int _radeon_bo_unmap(struct radeon_bo *bo, _radeon_bo_map(bo, w, __FILE__, __FUNCTION__, __LINE__) #define radeon_bo_unmap(bo)\ _radeon_bo_unmap(bo, __FILE__, __FUNCTION__, __LINE__) +#define radeon_bo_debug(bo, opcode)\ + _radeon_bo_debug(bo, opcode, __FILE__, __FUNCTION__, __LINE__) #endif |
From: <jb...@ke...> - 2008-11-20 19:01:38
|
shared-core/drm.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) New commits: commit 10c3e1a8b55355b1ae1697ebf3d77ac4702d61c9 Merge: 5923831... 2e2fd6c... Author: Jesse Barnes <jb...@vi...> Date: Thu Nov 20 11:01:24 2008 -0800 Merge branch 'master' into modesetting-gem commit 2e2fd6c63204cbea3b29a4872be77ac69677c841 Author: Jesse Barnes <jb...@vi...> Date: Thu Nov 20 11:00:29 2008 -0800 DRM: make drm_map_type match upstream kernel Since the TTM type isn't upstream yet, we need to make sure libdrm uses what the kernel uses, which is _DRM_GEM = 6. diff --git a/shared-core/drm.h b/shared-core/drm.h index 472cd89..507f047 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -236,8 +236,8 @@ enum drm_map_type { _DRM_AGP = 3, /**< AGP/GART */ _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */ - _DRM_TTM = 6, - _DRM_GEM = 7 + _DRM_GEM = 6, + _DRM_TTM = 7, }; /** commit 5923831bafca3cf2358ffc7f8b0079ab4de9da5c Author: Jesse Barnes <jb...@vi...> Date: Thu Nov 20 10:57:33 2008 -0800 DRM: make drm_map_type match kernel GEM is upstream, but TTM isn't, so _DRM_GEM needs to be 6, not 7. diff --git a/shared-core/drm.h b/shared-core/drm.h index 08882b7..218a469 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -236,8 +236,8 @@ enum drm_map_type { _DRM_AGP = 3, /**< AGP/GART */ _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */ - _DRM_TTM = 6, - _DRM_GEM = 7, + _DRM_GEM = 6, + _DRM_TTM = 7, }; /** commit c029ed2510f32318d4bd6a195e81712d1b4ea29b Author: Stephane Marchesin <mar...@ic...> Date: Wed Nov 19 23:17:27 2008 +0100 Unbreak drm build. diff --git a/shared-core/drm.h b/shared-core/drm.h index 05fc91d..472cd89 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -236,7 +236,8 @@ enum drm_map_type { _DRM_AGP = 3, /**< AGP/GART */ _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */ - _DRM_GEM = 6 + _DRM_TTM = 6, + _DRM_GEM = 7 }; /** |
From: <dar...@ke...> - 2009-03-25 05:07:41
|
linux-core/nouveau_dma.h | 1 + linux-core/nv50_display.c | 2 ++ linux-core/nv50_fbcon.c | 4 +++- shared-core/nouveau_drv.h | 1 + shared-core/nouveau_fifo.c | 29 ++++++++++++++++++++++++++++- shared-core/nouveau_object.c | 3 +++ 6 files changed, 38 insertions(+), 2 deletions(-) New commits: commit 62888f088f4d41ac7f30180acb526f29768436f6 Author: Ben Skeggs <bs...@re...> Date: Wed Mar 25 15:00:52 2009 +1000 nouveau: idle the channel a bit better before destroying it diff --git a/shared-core/nouveau_fifo.c b/shared-core/nouveau_fifo.c index d8ac567..332ac33 100644 --- a/shared-core/nouveau_fifo.c +++ b/shared-core/nouveau_fifo.c @@ -463,6 +463,8 @@ void nouveau_fifo_free(struct nouveau_channel *chan) struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine = &dev_priv->engine; uint64_t t_start; + bool timeout = false; + int ret; DRM_INFO("%s: freeing fifo %d\n", __func__, chan->id); @@ -472,11 +474,35 @@ void nouveau_fifo_free(struct nouveau_channel *chan) if (engine->timer.read(dev) - t_start > 2000000000ULL) { DRM_ERROR("Failed to idle channel %d before destroy." "Prepare for strangeness..\n", chan->id); + timeout = true; break; } } - /* Signal all pending fences, if any */ + /* Wait on a fence until channel goes idle, this ensures the engine + * has finished with the last push buffer completely before we destroy + * the channel. + */ + if (!timeout && dev_priv->mm_enabled) { + struct drm_fence_object *fence = NULL; + + ret = drm_fence_object_create(dev, chan->id, DRM_FENCE_TYPE_EXE, + DRM_FENCE_FLAG_EMIT, &fence); + if (ret == 0) + ret = drm_fence_object_wait(fence, 0, 1, + DRM_FENCE_TYPE_EXE); + + if (ret) { + DRM_ERROR("Failed to idle channel %d before destroy. " + "Prepare for strangeness..\n", chan->id); + timeout = true; + } + } + + /* Ensure all outstanding fences are signaled. They should be if the + * above attempts at idling were OK, but if we failed this'll tell TTM + * we're done with the buffers. + */ if (dev_priv->mm_enabled) { drm_fence_handler(dev, chan->id, chan->next_sequence, DRM_FENCE_TYPE_EXE, 0); @@ -484,6 +510,7 @@ void nouveau_fifo_free(struct nouveau_channel *chan) /*XXX: Maybe should wait for PGRAPH to finish with the stuff it fetched * from CACHE1 too? + *25/3/2009: handled in the mm_enabled case */ /* disable the fifo caches */ commit 8c46fa5a40503e4854d2f8d7dffbe09eb1333a77 Author: Ben Skeggs <bs...@re...> Date: Wed Mar 25 15:00:20 2009 +1000 nouveau: fix potential oops in gpuobj_channel_takedown diff --git a/shared-core/nouveau_object.c b/shared-core/nouveau_object.c index 36a559d..454550d 100644 --- a/shared-core/nouveau_object.c +++ b/shared-core/nouveau_object.c @@ -1162,6 +1162,9 @@ nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan) DRM_DEBUG("ch%d\n", chan->id); + if (!chan->ramht_refs.next) + return; + list_for_each_safe(entry, tmp, &chan->ramht_refs) { ref = list_entry(entry, struct nouveau_gpuobj_ref, list); commit 1e7d005aa0ccd86012194c8292fe55ca8534348b Author: Ben Skeggs <bs...@re...> Date: Wed Mar 25 14:59:07 2009 +1000 nouveau: prevent fbcon notifier waits when unnecessary It seems fbcon_sync will get called continually by something even while not at a console, so ignore the call unless we've previously rendered to the fbcon. diff --git a/linux-core/nouveau_dma.h b/linux-core/nouveau_dma.h index 66d567f..085c506 100644 --- a/linux-core/nouveau_dma.h +++ b/linux-core/nouveau_dma.h @@ -91,6 +91,7 @@ FIRE_RING(struct nouveau_channel *chan) if (chan->dma.cur == chan->dma.put) return; + chan->accel_done = true; DRM_MEMORYBARRIER(); chan->dma.put = chan->dma.cur; diff --git a/linux-core/nv50_fbcon.c b/linux-core/nv50_fbcon.c index dfa14ae..9e0625d 100644 --- a/linux-core/nv50_fbcon.c +++ b/linux-core/nv50_fbcon.c @@ -12,7 +12,8 @@ nv50_fbcon_sync(struct fb_info *info) struct nouveau_channel *chan = dev_priv->channel; int ret, i; - if (info->state != FBINFO_STATE_RUNNING || + if (!chan->accel_done || + info->state != FBINFO_STATE_RUNNING || info->flags & FBINFO_HWACCEL_DISABLED) return 0; @@ -44,6 +45,7 @@ nv50_fbcon_sync(struct fb_info *info) return 0; } + chan->accel_done = false; return 0; } diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h index 87ef8ef..0667c16 100644 --- a/shared-core/nouveau_drv.h +++ b/shared-core/nouveau_drv.h @@ -173,6 +173,7 @@ struct nouveau_channel volatile uint32_t *m2mf_ntfy_map; uint32_t vram_handle; uint32_t gart_handle; + bool accel_done; /* Push buffer state (only for drm's channel on !mm_enabled) */ struct { commit f4cb7a7340e1954ed282efec94a62e816918bfa7 Author: Ben Skeggs <bs...@re...> Date: Wed Mar 25 14:57:25 2009 +1000 nv50: turn off crtcs in display_disable diff --git a/linux-core/nv50_display.c b/linux-core/nv50_display.c index ac69865..b509d6d 100644 --- a/linux-core/nv50_display.c +++ b/linux-core/nv50_display.c @@ -163,11 +163,13 @@ static int nv50_display_disable(struct drm_device *dev) DRM_DEBUG("\n"); + dev_priv->in_modeset = true; list_for_each_entry(drm_crtc, &dev->mode_config.crtc_list, head) { struct drm_crtc_helper_funcs *helper = drm_crtc->helper_private; helper->dpms(drm_crtc, DRM_MODE_DPMS_OFF); } + dev_priv->in_modeset = false; OUT_MODE(NV50_UPDATE_DISPLAY, 0); |