diff options
| -rw-r--r-- | linux-core/radeon_drv.c | 5 | ||||
| -rw-r--r-- | shared-core/radeon_cp.c | 102 | ||||
| -rw-r--r-- | shared-core/radeon_drv.h | 1 | 
3 files changed, 107 insertions, 1 deletions
| diff --git a/linux-core/radeon_drv.c b/linux-core/radeon_drv.c index 79bcc3e6..f1fe3012 100644 --- a/linux-core/radeon_drv.c +++ b/linux-core/radeon_drv.c @@ -39,6 +39,7 @@  int radeon_no_wb;  int radeon_dynclks = 1;  int radeon_r4xx_atom = 0; +int radeon_agpmode = 0;  MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n");  module_param_named(no_wb, radeon_no_wb, int, 0444); @@ -52,6 +53,10 @@ module_param_named(dynclks, radeon_dynclks, int, 0444);  MODULE_PARM_DESC(r4xx_atom, "Enable ATOMBIOS modesetting for R4xx");  module_param_named(r4xx_atom, radeon_r4xx_atom, int, 0444); +MODULE_PARM_DESC(agpmode, "AGP Mode (-1 == PCI)"); +module_param_named(agpmode, radeon_agpmode, int, 0444); + +  static int dri_library_name(struct drm_device * dev, char * buf)  {  	drm_radeon_private_t *dev_priv = dev->dev_private; diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c index 9825d709..190b1432 100644 --- a/shared-core/radeon_cp.c +++ b/shared-core/radeon_cp.c @@ -2334,7 +2334,6 @@ int radeon_modeset_cp_suspend(struct drm_device *dev)  int radeon_modeset_cp_resume(struct drm_device *dev)  {  	drm_radeon_private_t *dev_priv = dev->dev_private; -	uint32_t tmp;  	radeon_do_wait_for_idle(dev_priv);  #if __OS_HAS_AGP @@ -2358,6 +2357,95 @@ int radeon_modeset_cp_resume(struct drm_device *dev)  	return 0;  } +#if __OS_HAS_AGP +int radeon_modeset_agp_init(struct drm_device *dev) +{ +	drm_radeon_private_t *dev_priv = dev->dev_private; +	struct drm_agp_mode mode; +	struct drm_agp_info info; +	int ret; +	int default_mode; +	uint32_t agp_status; +	bool is_v3; + +	/* Acquire AGP. */ +	ret = drm_agp_acquire(dev); +	if (ret) { +		DRM_ERROR("Unable to acquire AGP: %d\n", ret); +		return ret; +	} + +	ret = drm_agp_info(dev, &info); +	if (ret) { +		DRM_ERROR("Unable to get AGP info: %d\n", ret); +		return ret; + 	} + +	mode.mode = info.mode; + +	agp_status = (RADEON_READ(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode; +	is_v3 = !!(agp_status & RADEON_AGPv3_MODE); + +	if (is_v3) { +		default_mode = (agp_status & RADEON_AGPv3_8X_MODE) ? 8 : 4; +	} else { +		if (agp_status & RADEON_AGP_4X_MODE) default_mode = 4; +		else if (agp_status & RADEON_AGP_2X_MODE) default_mode = 2; +		else default_mode = 1; +	} + +	if (radeon_agpmode > 0) { +		if ((radeon_agpmode < (is_v3 ? 4 : 1)) || +		    (radeon_agpmode > (is_v3 ? 8 : 4)) || +		    (radeon_agpmode & (radeon_agpmode - 1))) { +			DRM_ERROR("Illegal AGP Mode: %d (valid %s), leaving at %d\n", +				  radeon_agpmode, is_v3 ? "4, 8" : "1, 2, 4", +				  default_mode); +			radeon_agpmode = default_mode; +		} +		else +			DRM_INFO("AGP mode requested: %d\n", radeon_agpmode); +	} else +		radeon_agpmode = default_mode; + +	mode.mode &= ~RADEON_AGP_MODE_MASK; +	if (is_v3) { +		switch(radeon_agpmode) { +		case 8: +			mode.mode |= RADEON_AGPv3_8X_MODE; +			break; +		case 4: +		default: +			mode.mode |= RADEON_AGPv3_4X_MODE; +			break; +		} +	} else { +		switch(radeon_agpmode) { +		case 4: mode.mode |= RADEON_AGP_4X_MODE; +		case 2: mode.mode |= RADEON_AGP_2X_MODE; +		case 1: +		default: +			mode.mode |= RADEON_AGP_1X_MODE; +			break; +		} +	} + +	mode.mode &= ~RADEON_AGP_FW_MODE; /* disable fw */ + +	ret = drm_agp_enable(dev, mode); +	if (ret) { +		DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode); +		return ret; +	} + +	/* workaround some hw issues */ +	if (dev_priv->chip_family <= CHIP_R200) { +		RADEON_WRITE(RADEON_AGP_CNTL, RADEON_READ(RADEON_AGP_CNTL) | 0x000e0000); +	} +	return 0; +} +#endif +  int radeon_modeset_cp_init(struct drm_device *dev)  {  	drm_radeon_private_t *dev_priv = dev->dev_private; @@ -2389,6 +2477,11 @@ int radeon_modeset_cp_init(struct drm_device *dev)  	dev_priv->new_memmap = true;  	r300_init_reg_flags(dev); + +#if __OS_HAS_AGP +	if (dev_priv->flags & RADEON_IS_AGP) +		radeon_modeset_agp_init(dev); +#endif  	return radeon_modeset_cp_resume(dev);  } @@ -2478,6 +2571,7 @@ int radeon_static_clocks_init(struct drm_device *dev)  		}  	}  	radeon_force_some_clocks(dev); +	return 0;  }  int radeon_driver_load(struct drm_device *dev, unsigned long flags) @@ -2523,6 +2617,12 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)  	DRM_DEBUG("%s card detected\n",  		  ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI")))); +	if ((dev_priv->flags & RADEON_IS_AGP) && (radeon_agpmode == -1)) { +		DRM_INFO("Forcing AGP to PCI mode\n"); +		dev_priv->flags &= ~RADEON_IS_AGP; +	} + +  	ret = drm_addmap(dev, drm_get_resource_start(dev, 2),  			 drm_get_resource_len(dev, 2), _DRM_REGISTERS,  			 _DRM_DRIVER | _DRM_READ_ONLY, &dev_priv->mmio); diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h index c37f23d6..a6ce129d 100644 --- a/shared-core/radeon_drv.h +++ b/shared-core/radeon_drv.h @@ -459,6 +459,7 @@ extern int radeon_dynclks;  extern int radeon_r4xx_atom;  extern struct drm_ioctl_desc radeon_ioctls[];  extern int radeon_max_ioctl; +extern int radeon_agpmode;  /* Check whether the given hardware address is inside the framebuffer or the   * GART area. | 
