Merge remote-tracking branch 'airlied/drm-next' into for-airlied

Manually resolve the conflict between the new enum drm property
helpers in drm-next and the new "force-dvi" option that the "audio" output
property gained in drm-intel-next.

While resolving this conflict, switch the new drm_prop_enum_list to
use the newly introduced enum defines instead of magic values.

Conflicts:
	drivers/gpu/drm/i915/intel_modes.c

Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
Daniel Vetter 2012-02-23 14:54:20 +01:00
commit ff5f4b0585
67 changed files with 2564 additions and 715 deletions

View file

@ -38,11 +38,6 @@
#include "drm_edid.h"
#include "drm_fourcc.h"
struct drm_prop_enum_list {
int type;
char *name;
};
/* Avoid boilerplate. I'm tired of typing. */
#define DRM_ENUM_NAME_FN(fnname, list) \
char *fnname(int val) \
@ -442,7 +437,7 @@ void drm_mode_remove(struct drm_connector *connector,
struct drm_display_mode *mode)
{
list_del(&mode->head);
kfree(mode);
drm_mode_destroy(connector->dev, mode);
}
EXPORT_SYMBOL(drm_mode_remove);
@ -454,7 +449,7 @@ EXPORT_SYMBOL(drm_mode_remove);
* @name: user visible name of the connector
*
* LOCKING:
* Caller must hold @dev's mode_config lock.
* Takes mode config lock.
*
* Initialises a preallocated connector. Connectors should be
* subclassed as part of driver connector objects.
@ -497,7 +492,7 @@ EXPORT_SYMBOL(drm_connector_init);
* @connector: connector to cleanup
*
* LOCKING:
* Caller must hold @dev's mode_config lock.
* Takes mode config lock.
*
* Cleans up the connector but doesn't free the object.
*/
@ -658,7 +653,6 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
{
struct drm_property *edid;
struct drm_property *dpms;
int i;
/*
* Standard properties (apply to all connectors)
@ -668,11 +662,9 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
"EDID", 0);
dev->mode_config.edid_property = edid;
dpms = drm_property_create(dev, DRM_MODE_PROP_ENUM,
"DPMS", ARRAY_SIZE(drm_dpms_enum_list));
for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++)
drm_property_add_enum(dpms, i, drm_dpms_enum_list[i].type,
drm_dpms_enum_list[i].name);
dpms = drm_property_create_enum(dev, 0,
"DPMS", drm_dpms_enum_list,
ARRAY_SIZE(drm_dpms_enum_list));
dev->mode_config.dpms_property = dpms;
return 0;
@ -688,30 +680,21 @@ int drm_mode_create_dvi_i_properties(struct drm_device *dev)
{
struct drm_property *dvi_i_selector;
struct drm_property *dvi_i_subconnector;
int i;
if (dev->mode_config.dvi_i_select_subconnector_property)
return 0;
dvi_i_selector =
drm_property_create(dev, DRM_MODE_PROP_ENUM,
drm_property_create_enum(dev, 0,
"select subconnector",
drm_dvi_i_select_enum_list,
ARRAY_SIZE(drm_dvi_i_select_enum_list));
for (i = 0; i < ARRAY_SIZE(drm_dvi_i_select_enum_list); i++)
drm_property_add_enum(dvi_i_selector, i,
drm_dvi_i_select_enum_list[i].type,
drm_dvi_i_select_enum_list[i].name);
dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector;
dvi_i_subconnector =
drm_property_create(dev, DRM_MODE_PROP_ENUM |
DRM_MODE_PROP_IMMUTABLE,
dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
"subconnector",
drm_dvi_i_subconnector_enum_list,
ARRAY_SIZE(drm_dvi_i_subconnector_enum_list));
for (i = 0; i < ARRAY_SIZE(drm_dvi_i_subconnector_enum_list); i++)
drm_property_add_enum(dvi_i_subconnector, i,
drm_dvi_i_subconnector_enum_list[i].type,
drm_dvi_i_subconnector_enum_list[i].name);
dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector;
return 0;
@ -742,51 +725,33 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
/*
* Basic connector properties
*/
tv_selector = drm_property_create(dev, DRM_MODE_PROP_ENUM,
tv_selector = drm_property_create_enum(dev, 0,
"select subconnector",
drm_tv_select_enum_list,
ARRAY_SIZE(drm_tv_select_enum_list));
for (i = 0; i < ARRAY_SIZE(drm_tv_select_enum_list); i++)
drm_property_add_enum(tv_selector, i,
drm_tv_select_enum_list[i].type,
drm_tv_select_enum_list[i].name);
dev->mode_config.tv_select_subconnector_property = tv_selector;
tv_subconnector =
drm_property_create(dev, DRM_MODE_PROP_ENUM |
DRM_MODE_PROP_IMMUTABLE, "subconnector",
drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
"subconnector",
drm_tv_subconnector_enum_list,
ARRAY_SIZE(drm_tv_subconnector_enum_list));
for (i = 0; i < ARRAY_SIZE(drm_tv_subconnector_enum_list); i++)
drm_property_add_enum(tv_subconnector, i,
drm_tv_subconnector_enum_list[i].type,
drm_tv_subconnector_enum_list[i].name);
dev->mode_config.tv_subconnector_property = tv_subconnector;
/*
* Other, TV specific properties: margins & TV modes.
*/
dev->mode_config.tv_left_margin_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"left margin", 2);
dev->mode_config.tv_left_margin_property->values[0] = 0;
dev->mode_config.tv_left_margin_property->values[1] = 100;
drm_property_create_range(dev, 0, "left margin", 0, 100);
dev->mode_config.tv_right_margin_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"right margin", 2);
dev->mode_config.tv_right_margin_property->values[0] = 0;
dev->mode_config.tv_right_margin_property->values[1] = 100;
drm_property_create_range(dev, 0, "right margin", 0, 100);
dev->mode_config.tv_top_margin_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"top margin", 2);
dev->mode_config.tv_top_margin_property->values[0] = 0;
dev->mode_config.tv_top_margin_property->values[1] = 100;
drm_property_create_range(dev, 0, "top margin", 0, 100);
dev->mode_config.tv_bottom_margin_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"bottom margin", 2);
dev->mode_config.tv_bottom_margin_property->values[0] = 0;
dev->mode_config.tv_bottom_margin_property->values[1] = 100;
drm_property_create_range(dev, 0, "bottom margin", 0, 100);
dev->mode_config.tv_mode_property =
drm_property_create(dev, DRM_MODE_PROP_ENUM,
@ -796,40 +761,22 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
i, modes[i]);
dev->mode_config.tv_brightness_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"brightness", 2);
dev->mode_config.tv_brightness_property->values[0] = 0;
dev->mode_config.tv_brightness_property->values[1] = 100;
drm_property_create_range(dev, 0, "brightness", 0, 100);
dev->mode_config.tv_contrast_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"contrast", 2);
dev->mode_config.tv_contrast_property->values[0] = 0;
dev->mode_config.tv_contrast_property->values[1] = 100;
drm_property_create_range(dev, 0, "contrast", 0, 100);
dev->mode_config.tv_flicker_reduction_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"flicker reduction", 2);
dev->mode_config.tv_flicker_reduction_property->values[0] = 0;
dev->mode_config.tv_flicker_reduction_property->values[1] = 100;
drm_property_create_range(dev, 0, "flicker reduction", 0, 100);
dev->mode_config.tv_overscan_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"overscan", 2);
dev->mode_config.tv_overscan_property->values[0] = 0;
dev->mode_config.tv_overscan_property->values[1] = 100;
drm_property_create_range(dev, 0, "overscan", 0, 100);
dev->mode_config.tv_saturation_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"saturation", 2);
dev->mode_config.tv_saturation_property->values[0] = 0;
dev->mode_config.tv_saturation_property->values[1] = 100;
drm_property_create_range(dev, 0, "saturation", 0, 100);
dev->mode_config.tv_hue_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"hue", 2);
dev->mode_config.tv_hue_property->values[0] = 0;
dev->mode_config.tv_hue_property->values[1] = 100;
drm_property_create_range(dev, 0, "hue", 0, 100);
return 0;
}
@ -845,18 +792,14 @@ EXPORT_SYMBOL(drm_mode_create_tv_properties);
int drm_mode_create_scaling_mode_property(struct drm_device *dev)
{
struct drm_property *scaling_mode;
int i;
if (dev->mode_config.scaling_mode_property)
return 0;
scaling_mode =
drm_property_create(dev, DRM_MODE_PROP_ENUM, "scaling mode",
drm_property_create_enum(dev, 0, "scaling mode",
drm_scaling_mode_enum_list,
ARRAY_SIZE(drm_scaling_mode_enum_list));
for (i = 0; i < ARRAY_SIZE(drm_scaling_mode_enum_list); i++)
drm_property_add_enum(scaling_mode, i,
drm_scaling_mode_enum_list[i].type,
drm_scaling_mode_enum_list[i].name);
dev->mode_config.scaling_mode_property = scaling_mode;
@ -874,18 +817,14 @@ EXPORT_SYMBOL(drm_mode_create_scaling_mode_property);
int drm_mode_create_dithering_property(struct drm_device *dev)
{
struct drm_property *dithering_mode;
int i;
if (dev->mode_config.dithering_mode_property)
return 0;
dithering_mode =
drm_property_create(dev, DRM_MODE_PROP_ENUM, "dithering",
drm_property_create_enum(dev, 0, "dithering",
drm_dithering_mode_enum_list,
ARRAY_SIZE(drm_dithering_mode_enum_list));
for (i = 0; i < ARRAY_SIZE(drm_dithering_mode_enum_list); i++)
drm_property_add_enum(dithering_mode, i,
drm_dithering_mode_enum_list[i].type,
drm_dithering_mode_enum_list[i].name);
dev->mode_config.dithering_mode_property = dithering_mode;
return 0;
@ -902,20 +841,15 @@ EXPORT_SYMBOL(drm_mode_create_dithering_property);
int drm_mode_create_dirty_info_property(struct drm_device *dev)
{
struct drm_property *dirty_info;
int i;
if (dev->mode_config.dirty_info_property)
return 0;
dirty_info =
drm_property_create(dev, DRM_MODE_PROP_ENUM |
DRM_MODE_PROP_IMMUTABLE,
drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE,
"dirty",
drm_dirty_info_enum_list,
ARRAY_SIZE(drm_dirty_info_enum_list));
for (i = 0; i < ARRAY_SIZE(drm_dirty_info_enum_list); i++)
drm_property_add_enum(dirty_info, i,
drm_dirty_info_enum_list[i].type,
drm_dirty_info_enum_list[i].name);
dev->mode_config.dirty_info_property = dirty_info;
return 0;
@ -1048,6 +982,9 @@ void drm_mode_config_cleanup(struct drm_device *dev)
head) {
plane->funcs->destroy(plane);
}
idr_remove_all(&dev->mode_config.crtc_idr);
idr_destroy(&dev->mode_config.crtc_idr);
}
EXPORT_SYMBOL(drm_mode_config_cleanup);
@ -1311,7 +1248,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data,
* @arg: arg from ioctl
*
* LOCKING:
* Caller? (FIXME)
* Takes mode config lock.
*
* Construct a CRTC configuration structure to return to the user.
*
@ -1371,7 +1308,7 @@ int drm_mode_getcrtc(struct drm_device *dev,
* @arg: arg from ioctl
*
* LOCKING:
* Caller? (FIXME)
* Takes mode config lock.
*
* Construct a connector configuration structure to return to the user.
*
@ -1553,6 +1490,9 @@ int drm_mode_getencoder(struct drm_device *dev, void *data,
* @data: ioctl data
* @file_priv: DRM file info
*
* LOCKING:
* Takes mode config lock.
*
* Return an plane count and set of IDs.
*/
int drm_mode_getplane_res(struct drm_device *dev, void *data,
@ -1599,6 +1539,9 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data,
* @data: ioctl data
* @file_priv: DRM file info
*
* LOCKING:
* Takes mode config lock.
*
* Return plane info, including formats supported, gamma size, any
* current fb, etc.
*/
@ -1664,6 +1607,9 @@ int drm_mode_getplane(struct drm_device *dev, void *data,
* @data: ioctl data*
* @file_prive: DRM file info
*
* LOCKING:
* Takes mode config lock.
*
* Set plane info, including placement, fb, scaling, and other factors.
* Or pass a NULL fb to disable.
*/
@ -1794,7 +1740,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data,
* @arg: arg from ioctl
*
* LOCKING:
* Caller? (FIXME)
* Takes mode config lock.
*
* Build a new CRTC configuration based on user request.
*
@ -2275,7 +2221,7 @@ int drm_mode_rmfb(struct drm_device *dev,
* @arg: arg from ioctl
*
* LOCKING:
* Caller? (FIXME)
* Takes mode config lock.
*
* Lookup the FB given its ID and return info about it.
*
@ -2617,6 +2563,53 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
}
EXPORT_SYMBOL(drm_property_create);
struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
const char *name,
const struct drm_prop_enum_list *props,
int num_values)
{
struct drm_property *property;
int i, ret;
flags |= DRM_MODE_PROP_ENUM;
property = drm_property_create(dev, flags, name, num_values);
if (!property)
return NULL;
for (i = 0; i < num_values; i++) {
ret = drm_property_add_enum(property, i,
props[i].type,
props[i].name);
if (ret) {
drm_property_destroy(dev, property);
return NULL;
}
}
return property;
}
EXPORT_SYMBOL(drm_property_create_enum);
struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
const char *name,
uint64_t min, uint64_t max)
{
struct drm_property *property;
flags |= DRM_MODE_PROP_RANGE;
property = drm_property_create(dev, flags, name, 2);
if (!property)
return NULL;
property->values[0] = min;
property->values[1] = max;
return property;
}
EXPORT_SYMBOL(drm_property_create_range);
int drm_property_add_enum(struct drm_property *property, int index,
uint64_t value, const char *name)
{
@ -3021,7 +3014,7 @@ void drm_mode_connector_detach_encoder(struct drm_connector *connector,
}
EXPORT_SYMBOL(drm_mode_connector_detach_encoder);
bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
int gamma_size)
{
crtc->gamma_size = gamma_size;
@ -3029,10 +3022,10 @@ bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL);
if (!crtc->gamma_store) {
crtc->gamma_size = 0;
return false;
return -ENOMEM;
}
return true;
return 0;
}
EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size);

View file

@ -44,12 +44,12 @@ module_param_named(poll, drm_kms_helper_poll, bool, 0600);
static void drm_mode_validate_flag(struct drm_connector *connector,
int flags)
{
struct drm_display_mode *mode, *t;
struct drm_display_mode *mode;
if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE))
return;
list_for_each_entry_safe(mode, t, &connector->modes, head) {
list_for_each_entry(mode, &connector->modes, head) {
if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
!(flags & DRM_MODE_FLAG_INTERLACE))
mode->status = MODE_NO_INTERLACE;
@ -87,7 +87,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
uint32_t maxX, uint32_t maxY)
{
struct drm_device *dev = connector->dev;
struct drm_display_mode *mode, *t;
struct drm_display_mode *mode;
struct drm_connector_helper_funcs *connector_funcs =
connector->helper_private;
int count = 0;
@ -96,7 +96,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
drm_get_connector_name(connector));
/* set all modes to the unverified state */
list_for_each_entry_safe(mode, t, &connector->modes, head)
list_for_each_entry(mode, &connector->modes, head)
mode->status = MODE_UNVERIFIED;
if (connector->force) {
@ -136,7 +136,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
mode_flags |= DRM_MODE_FLAG_DBLSCAN;
drm_mode_validate_flag(connector, mode_flags);
list_for_each_entry_safe(mode, t, &connector->modes, head) {
list_for_each_entry(mode, &connector->modes, head) {
if (mode->status == MODE_OK)
mode->status = connector_funcs->mode_valid(connector,
mode);
@ -152,7 +152,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
drm_get_connector_name(connector));
list_for_each_entry_safe(mode, t, &connector->modes, head) {
list_for_each_entry(mode, &connector->modes, head) {
mode->vrefresh = drm_mode_vrefresh(mode);
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);

View file

@ -135,23 +135,23 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED),

View file

@ -266,6 +266,11 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
}
};
ret = i2c_transfer(adapter, msgs, 2);
if (ret == -ENXIO) {
DRM_DEBUG_KMS("drm: skipping non-existent adapter %s\n",
adapter->name);
break;
}
} while (ret != 2 && --retries);
return ret == 2 ? 0 : -1;
@ -745,7 +750,7 @@ drm_mode_std(struct drm_connector *connector, struct edid *edid,
*/
mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
if (drm_mode_hsync(mode) > drm_gtf2_hbreak(edid)) {
kfree(mode);
drm_mode_destroy(dev, mode);
mode = drm_gtf_mode_complex(dev, hsize, vsize,
vrefresh_rate, 0, 0,
drm_gtf2_m(edid),

View file

@ -306,91 +306,31 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { };
#endif
static void drm_fb_helper_on(struct fb_info *info)
static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
{
struct drm_fb_helper *fb_helper = info->par;
struct drm_device *dev = fb_helper->dev;
struct drm_crtc *crtc;
struct drm_crtc_helper_funcs *crtc_funcs;
struct drm_connector *connector;
struct drm_encoder *encoder;
int i, j;
/*
* For each CRTC in this fb, turn the crtc on then,
* find all associated encoders and turn them on.
* For each CRTC in this fb, turn the connectors on/off.
*/
mutex_lock(&dev->mode_config.mutex);
for (i = 0; i < fb_helper->crtc_count; i++) {
crtc = fb_helper->crtc_info[i].mode_set.crtc;
crtc_funcs = crtc->helper_private;
if (!crtc->enabled)
continue;
crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
/* Walk the connectors & encoders on this fb turning them on */
/* Walk the connectors & encoders on this fb turning them on/off */
for (j = 0; j < fb_helper->connector_count; j++) {
connector = fb_helper->connector_info[j]->connector;
connector->dpms = DRM_MODE_DPMS_ON;
drm_helper_connector_dpms(connector, dpms_mode);
drm_connector_property_set_value(connector,
dev->mode_config.dpms_property,
DRM_MODE_DPMS_ON);
dev->mode_config.dpms_property, dpms_mode);
}
/* Found a CRTC on this fb, now find encoders */
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
if (encoder->crtc == crtc) {
struct drm_encoder_helper_funcs *encoder_funcs;
encoder_funcs = encoder->helper_private;
encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
}
}
}
mutex_unlock(&dev->mode_config.mutex);
}
static void drm_fb_helper_off(struct fb_info *info, int dpms_mode)
{
struct drm_fb_helper *fb_helper = info->par;
struct drm_device *dev = fb_helper->dev;
struct drm_crtc *crtc;
struct drm_crtc_helper_funcs *crtc_funcs;
struct drm_connector *connector;
struct drm_encoder *encoder;
int i, j;
/*
* For each CRTC in this fb, find all associated encoders
* and turn them off, then turn off the CRTC.
*/
mutex_lock(&dev->mode_config.mutex);
for (i = 0; i < fb_helper->crtc_count; i++) {
crtc = fb_helper->crtc_info[i].mode_set.crtc;
crtc_funcs = crtc->helper_private;
if (!crtc->enabled)
continue;
/* Walk the connectors on this fb and mark them off */
for (j = 0; j < fb_helper->connector_count; j++) {
connector = fb_helper->connector_info[j]->connector;
connector->dpms = dpms_mode;
drm_connector_property_set_value(connector,
dev->mode_config.dpms_property,
dpms_mode);
}
/* Found a CRTC on this fb, now find encoders */
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
if (encoder->crtc == crtc) {
struct drm_encoder_helper_funcs *encoder_funcs;
encoder_funcs = encoder->helper_private;
encoder_funcs->dpms(encoder, dpms_mode);
}
}
crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
}
mutex_unlock(&dev->mode_config.mutex);
}
@ -400,23 +340,23 @@ int drm_fb_helper_blank(int blank, struct fb_info *info)
switch (blank) {
/* Display: On; HSync: On, VSync: On */
case FB_BLANK_UNBLANK:
drm_fb_helper_on(info);
drm_fb_helper_dpms(info, DRM_MODE_DPMS_ON);
break;
/* Display: Off; HSync: On, VSync: On */
case FB_BLANK_NORMAL:
drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY);
break;
/* Display: Off; HSync: Off, VSync: On */
case FB_BLANK_HSYNC_SUSPEND:
drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY);
break;
/* Display: Off; HSync: On, VSync: Off */
case FB_BLANK_VSYNC_SUSPEND:
drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND);
drm_fb_helper_dpms(info, DRM_MODE_DPMS_SUSPEND);
break;
/* Display: Off; HSync: Off, VSync: Off */
case FB_BLANK_POWERDOWN:
drm_fb_helper_off(info, DRM_MODE_DPMS_OFF);
drm_fb_helper_dpms(info, DRM_MODE_DPMS_OFF);
break;
}
return 0;
@ -430,8 +370,11 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
for (i = 0; i < helper->connector_count; i++)
kfree(helper->connector_info[i]);
kfree(helper->connector_info);
for (i = 0; i < helper->crtc_count; i++)
for (i = 0; i < helper->crtc_count; i++) {
kfree(helper->crtc_info[i].mode_set.connectors);
if (helper->crtc_info[i].mode_set.mode)
drm_mode_destroy(helper->dev, helper->crtc_info[i].mode_set.mode);
}
kfree(helper->crtc_info);
}
@ -474,11 +417,10 @@ int drm_fb_helper_init(struct drm_device *dev,
i = 0;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
fb_helper->crtc_info[i].crtc_id = crtc->base.id;
fb_helper->crtc_info[i].mode_set.crtc = crtc;
i++;
}
fb_helper->conn_limit = max_conn_count;
return 0;
out_free:
drm_fb_helper_crtc_free(fb_helper);

View file

@ -277,6 +277,12 @@ int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv)
case DRM_CAP_VBLANK_HIGH_CRTC:
req->value = 1;
break;
case DRM_CAP_DUMB_PREFERRED_DEPTH:
req->value = dev->mode_config.preferred_depth;
break;
case DRM_CAP_DUMB_PREFER_SHADOW:
req->value = dev->mode_config.prefer_shadow;
break;
default:
return -EINVAL;
}

View file

@ -686,8 +686,6 @@ void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags)
p->crtc_vsync_end /= 2;
p->crtc_vtotal /= 2;
}
p->crtc_vtotal |= 1;
}
if (p->flags & DRM_MODE_FLAG_DBLSCAN) {

View file

@ -324,8 +324,6 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
if (ret)
goto err_g1;
pci_set_master(pdev);
dev->pdev = pdev;
dev->dev = &pdev->dev;

View file

@ -46,39 +46,13 @@ struct exynos_drm_fbdev {
struct exynos_drm_gem_obj *exynos_gem_obj;
};
static int exynos_drm_fbdev_set_par(struct fb_info *info)
{
struct fb_var_screeninfo *var = &info->var;
switch (var->bits_per_pixel) {
case 32:
case 24:
case 18:
case 16:
case 12:
info->fix.visual = FB_VISUAL_TRUECOLOR;
break;
case 1:
info->fix.visual = FB_VISUAL_MONO01;
break;
default:
info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
break;
}
info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8;
return drm_fb_helper_set_par(info);
}
static struct fb_ops exynos_drm_fb_ops = {
.owner = THIS_MODULE,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = exynos_drm_fbdev_set_par,
.fb_set_par = drm_fb_helper_set_par,
.fb_blank = drm_fb_helper_blank,
.fb_pan_display = drm_fb_helper_pan_display,
.fb_setcmap = drm_fb_helper_setcmap,

View file

@ -507,11 +507,7 @@ static int psbfb_create(struct psb_fbdev *fbdev,
info->fix.mmio_start = pci_resource_start(dev->pdev, 0);
info->fix.mmio_len = pci_resource_len(dev->pdev, 0);
info->pixmap.size = 64 * 1024;
info->pixmap.buf_align = 8;
info->pixmap.access_align = 32;
info->pixmap.flags = FB_PIXMAP_SYSTEM;
info->pixmap.scan_align = 1;
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
dev_info(dev->dev, "allocated %dx%d fb\n",
psbfb->base.width, psbfb->base.height);
@ -725,10 +721,7 @@ static int psb_create_backlight_property(struct drm_device *dev)
if (dev_priv->backlight_property)
return 0;
backlight = drm_property_create(dev, DRM_MODE_PROP_RANGE,
"backlight", 2);
backlight->values[0] = 0;
backlight->values[1] = 100;
backlight = drm_property_create_range(dev, 0, "backlight", 0, 100);
dev_priv->backlight_property = backlight;

View file

@ -395,7 +395,7 @@ int gma_intel_setup_gmbus(struct drm_device *dev)
struct drm_psb_private *dev_priv = dev->dev_private;
int ret, i;
dev_priv->gmbus = kcalloc(sizeof(struct intel_gmbus), GMBUS_NUM_PORTS,
dev_priv->gmbus = kcalloc(GMBUS_NUM_PORTS, sizeof(struct intel_gmbus),
GFP_KERNEL);
if (dev_priv->gmbus == NULL)
return -ENOMEM;

View file

@ -283,6 +283,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
dev_priv->dev = dev;
dev->dev_private = (void *) dev_priv;
pci_set_master(dev->pdev);
if (!IS_PSB(dev)) {
if (pci_enable_msi(dev->pdev))
dev_warn(dev->dev, "Enabling MSI failed!\n");

View file

@ -2312,10 +2312,8 @@ static bool psb_intel_sdvo_tv_create_property(struct psb_intel_sdvo *psb_intel_s
psb_intel_sdvo_connector->max_##name = data_value[0]; \
psb_intel_sdvo_connector->cur_##name = response; \
psb_intel_sdvo_connector->name = \
drm_property_create(dev, DRM_MODE_PROP_RANGE, #name, 2); \
drm_property_create_range(dev, 0, #name, 0, data_value[0]); \
if (!psb_intel_sdvo_connector->name) return false; \
psb_intel_sdvo_connector->name->values[0] = 0; \
psb_intel_sdvo_connector->name->values[1] = data_value[0]; \
drm_connector_attach_property(connector, \
psb_intel_sdvo_connector->name, \
psb_intel_sdvo_connector->cur_##name); \
@ -2349,25 +2347,19 @@ psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo,
psb_intel_sdvo_connector->left_margin = data_value[0] - response;
psb_intel_sdvo_connector->right_margin = psb_intel_sdvo_connector->left_margin;
psb_intel_sdvo_connector->left =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"left_margin", 2);
drm_property_create_range(dev, 0, "left_margin", 0, data_value[0]);
if (!psb_intel_sdvo_connector->left)
return false;
psb_intel_sdvo_connector->left->values[0] = 0;
psb_intel_sdvo_connector->left->values[1] = data_value[0];
drm_connector_attach_property(connector,
psb_intel_sdvo_connector->left,
psb_intel_sdvo_connector->left_margin);
psb_intel_sdvo_connector->right =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"right_margin", 2);
drm_property_create_range(dev, 0, "right_margin", 0, data_value[0]);
if (!psb_intel_sdvo_connector->right)
return false;
psb_intel_sdvo_connector->right->values[0] = 0;
psb_intel_sdvo_connector->right->values[1] = data_value[0];
drm_connector_attach_property(connector,
psb_intel_sdvo_connector->right,
psb_intel_sdvo_connector->right_margin);
@ -2391,25 +2383,19 @@ psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo,
psb_intel_sdvo_connector->top_margin = data_value[0] - response;
psb_intel_sdvo_connector->bottom_margin = psb_intel_sdvo_connector->top_margin;
psb_intel_sdvo_connector->top =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"top_margin", 2);
drm_property_create_range(dev, 0, "top_margin", 0, data_value[0]);
if (!psb_intel_sdvo_connector->top)
return false;
psb_intel_sdvo_connector->top->values[0] = 0;
psb_intel_sdvo_connector->top->values[1] = data_value[0];
drm_connector_attach_property(connector,
psb_intel_sdvo_connector->top,
psb_intel_sdvo_connector->top_margin);
psb_intel_sdvo_connector->bottom =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"bottom_margin", 2);
drm_property_create_range(dev, 0, "bottom_margin", 0, data_value[0]);
if (!psb_intel_sdvo_connector->bottom)
return false;
psb_intel_sdvo_connector->bottom->values[0] = 0;
psb_intel_sdvo_connector->bottom->values[1] = data_value[0];
drm_connector_attach_property(connector,
psb_intel_sdvo_connector->bottom,
psb_intel_sdvo_connector->bottom_margin);
@ -2438,12 +2424,10 @@ psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo,
psb_intel_sdvo_connector->max_dot_crawl = 1;
psb_intel_sdvo_connector->cur_dot_crawl = response & 0x1;
psb_intel_sdvo_connector->dot_crawl =
drm_property_create(dev, DRM_MODE_PROP_RANGE, "dot_crawl", 2);
drm_property_create_range(dev, 0, "dot_crawl", 0, 1);
if (!psb_intel_sdvo_connector->dot_crawl)
return false;
psb_intel_sdvo_connector->dot_crawl->values[0] = 0;
psb_intel_sdvo_connector->dot_crawl->values[1] = 1;
drm_connector_attach_property(connector,
psb_intel_sdvo_connector->dot_crawl,
psb_intel_sdvo_connector->cur_dot_crawl);

View file

@ -252,10 +252,7 @@ static int ch7006_encoder_create_resources(struct drm_encoder *encoder,
drm_mode_create_tv_properties(dev, NUM_TV_NORMS, ch7006_tv_norm_names);
priv->scale_property = drm_property_create(dev, DRM_MODE_PROP_RANGE,
"scale", 2);
priv->scale_property->values[0] = 0;
priv->scale_property->values[1] = 2;
priv->scale_property = drm_property_create_range(dev, 0, "scale", 0, 2);
drm_connector_attach_property(connector, conf->tv_select_subconnector_property,
priv->select_subconnector);

View file

@ -1208,6 +1208,8 @@ int i810_driver_load(struct drm_device *dev, unsigned long flags)
dev->types[8] = _DRM_STAT_SECONDARY;
dev->types[9] = _DRM_STAT_DMA;
pci_set_master(dev->pdev);
return 0;
}

View file

@ -1951,6 +1951,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto free_priv;
}
pci_set_master(dev->pdev);
/* overlay on gen2 is broken and can't address above 1G */
if (IS_GEN2(dev))
dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30));

View file

@ -9098,6 +9098,9 @@ void intel_modeset_init(struct drm_device *dev)
dev->mode_config.min_width = 0;
dev->mode_config.min_height = 0;
dev->mode_config.preferred_depth = 24;
dev->mode_config.prefer_shadow = 1;
dev->mode_config.funcs = (void *)&intel_mode_funcs;
intel_init_quirks(dev);

View file

@ -152,11 +152,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);
info->pixmap.size = 64*1024;
info->pixmap.buf_align = 8;
info->pixmap.access_align = 32;
info->pixmap.flags = FB_PIXMAP_SYSTEM;
info->pixmap.scan_align = 1;
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n",
fb->width, fb->height,

View file

@ -37,7 +37,7 @@
/* Intel GPIO access functions */
#define I2C_RISEFALL_TIME 20
#define I2C_RISEFALL_TIME 10
static inline struct intel_gmbus *
to_intel_gmbus(struct i2c_adapter *i2c)
@ -383,7 +383,7 @@ int intel_setup_gmbus(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
int ret, i;
dev_priv->gmbus = kcalloc(sizeof(struct intel_gmbus), GMBUS_NUM_PORTS,
dev_priv->gmbus = kcalloc(GMBUS_NUM_PORTS, sizeof(struct intel_gmbus),
GFP_KERNEL);
if (dev_priv->gmbus == NULL)
return -ENOMEM;

View file

@ -83,11 +83,11 @@ int intel_ddc_get_modes(struct drm_connector *connector,
return ret;
}
static const char *force_audio_names[] = {
"force-dvi",
"off",
"auto",
"on",
static const struct drm_prop_enum_list force_audio_names[] = {
{ HDMI_AUDIO_OFF_DVI, "force-dvi" },
{ HDMI_AUDIO_OFF, "off" },
{ HDMI_AUDIO_AUTO, "auto" },
{ HDMI_AUDIO_ON, "on" },
};
void
@ -96,28 +96,24 @@ intel_attach_force_audio_property(struct drm_connector *connector)
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_property *prop;
int i;
prop = dev_priv->force_audio_property;
if (prop == NULL) {
prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
prop = drm_property_create_enum(dev, 0,
"audio",
force_audio_names,
ARRAY_SIZE(force_audio_names));
if (prop == NULL)
return;
for (i = 0; i < ARRAY_SIZE(force_audio_names); i++)
drm_property_add_enum(prop, i, i-2,
force_audio_names[i]);
dev_priv->force_audio_property = prop;
}
drm_connector_attach_property(connector, prop, 0);
}
static const char *broadcast_rgb_names[] = {
"Full",
"Limited 16:235",
static const struct drm_prop_enum_list broadcast_rgb_names[] = {
{ 0, "Full" },
{ 1, "Limited 16:235" },
};
void
@ -126,19 +122,16 @@ intel_attach_broadcast_rgb_property(struct drm_connector *connector)
struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_property *prop;
int i;
prop = dev_priv->broadcast_rgb_property;
if (prop == NULL) {
prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,
"Broadcast RGB",
broadcast_rgb_names,
ARRAY_SIZE(broadcast_rgb_names));
if (prop == NULL)
return;
for (i = 0; i < ARRAY_SIZE(broadcast_rgb_names); i++)
drm_property_add_enum(prop, i, i, broadcast_rgb_names[i]);
dev_priv->broadcast_rgb_property = prop;
}

View file

@ -2276,10 +2276,8 @@ static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo,
intel_sdvo_connector->max_##name = data_value[0]; \
intel_sdvo_connector->cur_##name = response; \
intel_sdvo_connector->name = \
drm_property_create(dev, DRM_MODE_PROP_RANGE, #name, 2); \
drm_property_create_range(dev, 0, #name, 0, data_value[0]); \
if (!intel_sdvo_connector->name) return false; \
intel_sdvo_connector->name->values[0] = 0; \
intel_sdvo_connector->name->values[1] = data_value[0]; \
drm_connector_attach_property(connector, \
intel_sdvo_connector->name, \
intel_sdvo_connector->cur_##name); \
@ -2313,25 +2311,19 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo,
intel_sdvo_connector->left_margin = data_value[0] - response;
intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin;
intel_sdvo_connector->left =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"left_margin", 2);
drm_property_create_range(dev, 0, "left_margin", 0, data_value[0]);
if (!intel_sdvo_connector->left)
return false;
intel_sdvo_connector->left->values[0] = 0;
intel_sdvo_connector->left->values[1] = data_value[0];
drm_connector_attach_property(connector,
intel_sdvo_connector->left,
intel_sdvo_connector->left_margin);
intel_sdvo_connector->right =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"right_margin", 2);
drm_property_create_range(dev, 0, "right_margin", 0, data_value[0]);
if (!intel_sdvo_connector->right)
return false;
intel_sdvo_connector->right->values[0] = 0;
intel_sdvo_connector->right->values[1] = data_value[0];
drm_connector_attach_property(connector,
intel_sdvo_connector->right,
intel_sdvo_connector->right_margin);
@ -2355,25 +2347,21 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo,
intel_sdvo_connector->top_margin = data_value[0] - response;
intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin;
intel_sdvo_connector->top =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"top_margin", 2);
drm_property_create_range(dev, 0,
"top_margin", 0, data_value[0]);
if (!intel_sdvo_connector->top)
return false;
intel_sdvo_connector->top->values[0] = 0;
intel_sdvo_connector->top->values[1] = data_value[0];
drm_connector_attach_property(connector,
intel_sdvo_connector->top,
intel_sdvo_connector->top_margin);
intel_sdvo_connector->bottom =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"bottom_margin", 2);
drm_property_create_range(dev, 0,
"bottom_margin", 0, data_value[0]);
if (!intel_sdvo_connector->bottom)
return false;
intel_sdvo_connector->bottom->values[0] = 0;
intel_sdvo_connector->bottom->values[1] = data_value[0];
drm_connector_attach_property(connector,
intel_sdvo_connector->bottom,
intel_sdvo_connector->bottom_margin);
@ -2402,12 +2390,10 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo,
intel_sdvo_connector->max_dot_crawl = 1;
intel_sdvo_connector->cur_dot_crawl = response & 0x1;
intel_sdvo_connector->dot_crawl =
drm_property_create(dev, DRM_MODE_PROP_RANGE, "dot_crawl", 2);
drm_property_create_range(dev, 0, "dot_crawl", 0, 1);
if (!intel_sdvo_connector->dot_crawl)
return false;
intel_sdvo_connector->dot_crawl->values[0] = 0;
intel_sdvo_connector->dot_crawl->values[1] = 1;
drm_connector_attach_property(connector,
intel_sdvo_connector->dot_crawl,
intel_sdvo_connector->cur_dot_crawl);

View file

@ -403,6 +403,8 @@ int mga_driver_load(struct drm_device *dev, unsigned long flags)
dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT;
dev_priv->chipset = flags;
pci_set_master(dev->pdev);
dev_priv->mmio_base = pci_resource_start(dev->pdev, 1);
dev_priv->mmio_size = pci_resource_len(dev->pdev, 1);

View file

@ -155,20 +155,20 @@ static const struct drm_mode_config_funcs nouveau_mode_config_funcs = {
};
struct drm_prop_enum_list {
struct nouveau_drm_prop_enum_list {
u8 gen_mask;
int type;
char *name;
};
static struct drm_prop_enum_list underscan[] = {
static struct nouveau_drm_prop_enum_list underscan[] = {
{ 6, UNDERSCAN_AUTO, "auto" },
{ 6, UNDERSCAN_OFF, "off" },
{ 6, UNDERSCAN_ON, "on" },
{}
};
static struct drm_prop_enum_list dither_mode[] = {
static struct nouveau_drm_prop_enum_list dither_mode[] = {
{ 7, DITHERING_MODE_AUTO, "auto" },
{ 7, DITHERING_MODE_OFF, "off" },
{ 1, DITHERING_MODE_ON, "on" },
@ -178,7 +178,7 @@ static struct drm_prop_enum_list dither_mode[] = {
{}
};
static struct drm_prop_enum_list dither_depth[] = {
static struct nouveau_drm_prop_enum_list dither_depth[] = {
{ 6, DITHERING_DEPTH_AUTO, "auto" },
{ 6, DITHERING_DEPTH_6BPC, "6 bpc" },
{ 6, DITHERING_DEPTH_8BPC, "8 bpc" },
@ -186,7 +186,7 @@ static struct drm_prop_enum_list dither_depth[] = {
};
#define PROP_ENUM(p,gen,n,list) do { \
struct drm_prop_enum_list *l = (list); \
struct nouveau_drm_prop_enum_list *l = (list); \
int c = 0; \
while (l->gen_mask) { \
if (l->gen_mask & (1 << (gen))) \
@ -281,16 +281,10 @@ nouveau_display_create(struct drm_device *dev)
PROP_ENUM(disp->underscan_property, gen, "underscan", underscan);
disp->underscan_hborder_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"underscan hborder", 2);
disp->underscan_hborder_property->values[0] = 0;
disp->underscan_hborder_property->values[1] = 128;
drm_property_create_range(dev, 0, "underscan hborder", 0, 128);
disp->underscan_vborder_property =
drm_property_create(dev, DRM_MODE_PROP_RANGE,
"underscan vborder", 2);
disp->underscan_vborder_property->values[0] = 0;
disp->underscan_vborder_property->values[1] = 128;
drm_property_create_range(dev, 0, "underscan vborder", 0, 128);
dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs;
dev->mode_config.fb_base = pci_resource_start(dev->pdev, 1);

View file

@ -381,11 +381,7 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev,
goto out_unref;
}
info->pixmap.size = 64*1024;
info->pixmap.buf_align = 8;
info->pixmap.access_align = 32;
info->pixmap.flags = FB_PIXMAP_SYSTEM;
info->pixmap.scan_align = 1;
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
mutex_unlock(&dev->struct_mutex);

View file

@ -1002,6 +1002,8 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
dev->dev_private = dev_priv;
dev_priv->dev = dev;
pci_set_master(dev->pdev);
dev_priv->flags = flags & NOUVEAU_FLAGS;
NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",

View file

@ -85,6 +85,7 @@ static struct drm_driver driver = {
int r128_driver_load(struct drm_device *dev, unsigned long flags)
{
pci_set_master(dev->pdev);
return drm_vblank_init(dev, 1);
}

View file

@ -71,7 +71,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \
evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \
radeon_trace_points.o ni.o cayman_blit_shaders.o atombios_encoders.o \
radeon_semaphore.o radeon_sa.o
radeon_semaphore.o radeon_sa.o atombios_i2c.o
radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o

View file

@ -1031,6 +1031,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
struct radeon_bo *rbo;
uint64_t fb_location;
uint32_t fb_format, fb_pitch_pixels, tiling_flags;
unsigned bankw, bankh, mtaspect, tile_split;
u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE);
u32 tmp, viewport_w, viewport_h;
int r;
@ -1121,20 +1122,13 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
break;
}
switch ((tmp & 0xf000) >> 12) {
case 0: /* 1KB rows */
default:
fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_1KB);
break;
case 1: /* 2KB rows */
fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_2KB);
break;
case 2: /* 4KB rows */
fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_4KB);
break;
}
fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1);
evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split);
fb_format |= EVERGREEN_GRPH_TILE_SPLIT(tile_split);
fb_format |= EVERGREEN_GRPH_BANK_WIDTH(bankw);
fb_format |= EVERGREEN_GRPH_BANK_HEIGHT(bankh);
fb_format |= EVERGREEN_GRPH_MACRO_TILE_ASPECT(mtaspect);
} else if (tiling_flags & RADEON_TILING_MICRO)
fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1);

View file

@ -0,0 +1,139 @@
/*
* Copyright 2011 Advanced Micro Devices, Inc.
*
* 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, sublicense,
* 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 above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* 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 NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
*
* Authors: Alex Deucher
*
*/
#include "drmP.h"
#include "radeon_drm.h"
#include "radeon.h"
#include "atom.h"
#define TARGET_HW_I2C_CLOCK 50
/* these are a limitation of ProcessI2cChannelTransaction not the hw */
#define ATOM_MAX_HW_I2C_WRITE 2
#define ATOM_MAX_HW_I2C_READ 255
static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan,
u8 slave_addr, u8 flags,
u8 *buf, u8 num)
{
struct drm_device *dev = chan->dev;
struct radeon_device *rdev = dev->dev_private;
PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION args;
int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction);
unsigned char *base;
u16 out;
memset(&args, 0, sizeof(args));
base = (unsigned char *)rdev->mode_info.atom_context->scratch;
if (flags & HW_I2C_WRITE) {
if (num > ATOM_MAX_HW_I2C_WRITE) {
DRM_ERROR("hw i2c: tried to write too many bytes (%d vs 2)\n", num);
return -EINVAL;
}
memcpy(&out, buf, num);
args.lpI2CDataOut = cpu_to_le16(out);
} else {
if (num > ATOM_MAX_HW_I2C_READ) {
DRM_ERROR("hw i2c: tried to read too many bytes (%d vs 255)\n", num);
return -EINVAL;
}
}
args.ucI2CSpeed = TARGET_HW_I2C_CLOCK;
args.ucRegIndex = 0;
args.ucTransBytes = num;
args.ucSlaveAddr = slave_addr << 1;
args.ucLineNumber = chan->rec.i2c_id;
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
/* error */
if (args.ucStatus != HW_ASSISTED_I2C_STATUS_SUCCESS) {
DRM_DEBUG_KMS("hw_i2c error\n");
return -EIO;
}
if (!(flags & HW_I2C_WRITE))
memcpy(buf, base, num);
return 0;
}
int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg *msgs, int num)
{
struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap);
struct i2c_msg *p;
int i, remaining, current_count, buffer_offset, max_bytes, ret;
u8 buf = 0, flags;
/* check for bus probe */
p = &msgs[0];
if ((num == 1) && (p->len == 0)) {
ret = radeon_process_i2c_ch(i2c,
p->addr, HW_I2C_WRITE,
&buf, 1);
if (ret)
return ret;
else
return num;
}
for (i = 0; i < num; i++) {
p = &msgs[i];
remaining = p->len;
buffer_offset = 0;
/* max_bytes are a limitation of ProcessI2cChannelTransaction not the hw */
if (p->flags & I2C_M_RD) {
max_bytes = ATOM_MAX_HW_I2C_READ;
flags = HW_I2C_READ;
} else {
max_bytes = ATOM_MAX_HW_I2C_WRITE;
flags = HW_I2C_WRITE;
}
while (remaining) {
if (remaining > max_bytes)
current_count = max_bytes;
else
current_count = remaining;
ret = radeon_process_i2c_ch(i2c,
p->addr, flags,
&p->buf[buffer_offset], current_count);
if (ret)
return ret;
remaining -= current_count;
buffer_offset += current_count;
}
}
return num;
}
u32 radeon_atom_hw_i2c_func(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}

View file

@ -43,6 +43,37 @@ void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
int ring, u32 cp_int_cntl);
void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw,
unsigned *bankh, unsigned *mtaspect,
unsigned *tile_split)
{
*bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK;
*bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK;
*mtaspect = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK;
*tile_split = (tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK;
switch (*bankw) {
default:
case 1: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_1; break;
case 2: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_2; break;
case 4: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_4; break;
case 8: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_8; break;
}
switch (*bankh) {
default:
case 1: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_1; break;
case 2: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_2; break;
case 4: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_4; break;
case 8: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_8; break;
}
switch (*mtaspect) {
default:
case 1: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_1; break;
case 2: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_2; break;
case 4: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_4; break;
case 8: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_8; break;
}
}
void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
{
u16 ctl, v;

View file

@ -32,17 +32,7 @@
#include "evergreend.h"
#include "evergreen_blit_shaders.h"
#include "cayman_blit_shaders.h"
#define DI_PT_RECTLIST 0x11
#define DI_INDEX_SIZE_16_BIT 0x0
#define DI_SRC_SEL_AUTO_INDEX 0x2
#define FMT_8 0x1
#define FMT_5_6_5 0x8
#define FMT_8_8_8_8 0x1a
#define COLOR_8 0x1
#define COLOR_5_6_5 0x8
#define COLOR_8_8_8_8 0x1a
#include "radeon_blit_common.h"
/* emits 17 */
static void

File diff suppressed because it is too large Load diff

View file

@ -77,6 +77,7 @@
#define CONFIG_MEMSIZE 0x5428
#define CP_COHER_BASE 0x85F8
#define CP_ME_CNTL 0x86D8
#define CP_ME_HALT (1 << 28)
#define CP_PFP_HALT (1 << 26)
@ -925,7 +926,70 @@
#define DB_DEBUG4 0x983C
#define DB_WATERMARKS 0x9854
#define DB_DEPTH_CONTROL 0x28800
#define R_028800_DB_DEPTH_CONTROL 0x028800
#define S_028800_STENCIL_ENABLE(x) (((x) & 0x1) << 0)
#define G_028800_STENCIL_ENABLE(x) (((x) >> 0) & 0x1)
#define C_028800_STENCIL_ENABLE 0xFFFFFFFE
#define S_028800_Z_ENABLE(x) (((x) & 0x1) << 1)
#define G_028800_Z_ENABLE(x) (((x) >> 1) & 0x1)
#define C_028800_Z_ENABLE 0xFFFFFFFD
#define S_028800_Z_WRITE_ENABLE(x) (((x) & 0x1) << 2)
#define G_028800_Z_WRITE_ENABLE(x) (((x) >> 2) & 0x1)
#define C_028800_Z_WRITE_ENABLE 0xFFFFFFFB
#define S_028800_ZFUNC(x) (((x) & 0x7) << 4)
#define G_028800_ZFUNC(x) (((x) >> 4) & 0x7)
#define C_028800_ZFUNC 0xFFFFFF8F
#define S_028800_BACKFACE_ENABLE(x) (((x) & 0x1) << 7)
#define G_028800_BACKFACE_ENABLE(x) (((x) >> 7) & 0x1)
#define C_028800_BACKFACE_ENABLE 0xFFFFFF7F
#define S_028800_STENCILFUNC(x) (((x) & 0x7) << 8)
#define G_028800_STENCILFUNC(x) (((x) >> 8) & 0x7)
#define C_028800_STENCILFUNC 0xFFFFF8FF
#define V_028800_STENCILFUNC_NEVER 0x00000000
#define V_028800_STENCILFUNC_LESS 0x00000001
#define V_028800_STENCILFUNC_EQUAL 0x00000002
#define V_028800_STENCILFUNC_LEQUAL 0x00000003
#define V_028800_STENCILFUNC_GREATER 0x00000004
#define V_028800_STENCILFUNC_NOTEQUAL 0x00000005
#define V_028800_STENCILFUNC_GEQUAL 0x00000006
#define V_028800_STENCILFUNC_ALWAYS 0x00000007
#define S_028800_STENCILFAIL(x) (((x) & 0x7) << 11)
#define G_028800_STENCILFAIL(x) (((x) >> 11) & 0x7)
#define C_028800_STENCILFAIL 0xFFFFC7FF
#define V_028800_STENCIL_KEEP 0x00000000
#define V_028800_STENCIL_ZERO 0x00000001
#define V_028800_STENCIL_REPLACE 0x00000002
#define V_028800_STENCIL_INCR 0x00000003
#define V_028800_STENCIL_DECR 0x00000004
#define V_028800_STENCIL_INVERT 0x00000005
#define V_028800_STENCIL_INCR_WRAP 0x00000006
#define V_028800_STENCIL_DECR_WRAP 0x00000007
#define S_028800_STENCILZPASS(x) (((x) & 0x7) << 14)
#define G_028800_STENCILZPASS(x) (((x) >> 14) & 0x7)
#define C_028800_STENCILZPASS 0xFFFE3FFF
#define S_028800_STENCILZFAIL(x) (((x) & 0x7) << 17)
#define G_028800_STENCILZFAIL(x) (((x) >> 17) & 0x7)
#define C_028800_STENCILZFAIL 0xFFF1FFFF
#define S_028800_STENCILFUNC_BF(x) (((x) & 0x7) << 20)
#define G_028800_STENCILFUNC_BF(x) (((x) >> 20) & 0x7)
#define C_028800_STENCILFUNC_BF 0xFF8FFFFF
#define S_028800_STENCILFAIL_BF(x) (((x) & 0x7) << 23)
#define G_028800_STENCILFAIL_BF(x) (((x) >> 23) & 0x7)
#define C_028800_STENCILFAIL_BF 0xFC7FFFFF
#define S_028800_STENCILZPASS_BF(x) (((x) & 0x7) << 26)
#define G_028800_STENCILZPASS_BF(x) (((x) >> 26) & 0x7)
#define C_028800_STENCILZPASS_BF 0xE3FFFFFF
#define S_028800_STENCILZFAIL_BF(x) (((x) & 0x7) << 29)
#define G_028800_STENCILZFAIL_BF(x) (((x) >> 29) & 0x7)
#define C_028800_STENCILZFAIL_BF 0x1FFFFFFF
#define DB_DEPTH_VIEW 0x28008
#define R_028008_DB_DEPTH_VIEW 0x00028008
#define S_028008_SLICE_START(x) (((x) & 0x7FF) << 0)
#define G_028008_SLICE_START(x) (((x) >> 0) & 0x7FF)
#define C_028008_SLICE_START 0xFFFFF800
#define S_028008_SLICE_MAX(x) (((x) & 0x7FF) << 13)
#define G_028008_SLICE_MAX(x) (((x) >> 13) & 0x7FF)
#define C_028008_SLICE_MAX 0xFF001FFF
#define DB_HTILE_DATA_BASE 0x28014
#define DB_Z_INFO 0x28040
# define Z_ARRAY_MODE(x) ((x) << 4)
@ -933,12 +997,59 @@
# define DB_NUM_BANKS(x) (((x) & 0x3) << 12)
# define DB_BANK_WIDTH(x) (((x) & 0x3) << 16)
# define DB_BANK_HEIGHT(x) (((x) & 0x3) << 20)
# define DB_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 24)
#define R_028040_DB_Z_INFO 0x028040
#define S_028040_FORMAT(x) (((x) & 0x3) << 0)
#define G_028040_FORMAT(x) (((x) >> 0) & 0x3)
#define C_028040_FORMAT 0xFFFFFFFC
#define V_028040_Z_INVALID 0x00000000
#define V_028040_Z_16 0x00000001
#define V_028040_Z_24 0x00000002
#define V_028040_Z_32_FLOAT 0x00000003
#define S_028040_ARRAY_MODE(x) (((x) & 0xF) << 4)
#define G_028040_ARRAY_MODE(x) (((x) >> 4) & 0xF)
#define C_028040_ARRAY_MODE 0xFFFFFF0F
#define S_028040_READ_SIZE(x) (((x) & 0x1) << 28)
#define G_028040_READ_SIZE(x) (((x) >> 28) & 0x1)
#define C_028040_READ_SIZE 0xEFFFFFFF
#define S_028040_TILE_SURFACE_ENABLE(x) (((x) & 0x1) << 29)
#define G_028040_TILE_SURFACE_ENABLE(x) (((x) >> 29) & 0x1)
#define C_028040_TILE_SURFACE_ENABLE 0xDFFFFFFF
#define S_028040_ZRANGE_PRECISION(x) (((x) & 0x1) << 31)
#define G_028040_ZRANGE_PRECISION(x) (((x) >> 31) & 0x1)
#define C_028040_ZRANGE_PRECISION 0x7FFFFFFF
#define S_028040_TILE_SPLIT(x) (((x) & 0x7) << 8)
#define G_028040_TILE_SPLIT(x) (((x) >> 8) & 0x7)
#define S_028040_NUM_BANKS(x) (((x) & 0x3) << 12)
#define G_028040_NUM_BANKS(x) (((x) >> 12) & 0x3)
#define S_028040_BANK_WIDTH(x) (((x) & 0x3) << 16)
#define G_028040_BANK_WIDTH(x) (((x) >> 16) & 0x3)
#define S_028040_BANK_HEIGHT(x) (((x) & 0x3) << 20)
#define G_028040_BANK_HEIGHT(x) (((x) >> 20) & 0x3)
#define S_028040_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 24)
#define G_028040_MACRO_TILE_ASPECT(x) (((x) >> 24) & 0x3)
#define DB_STENCIL_INFO 0x28044
#define R_028044_DB_STENCIL_INFO 0x028044
#define S_028044_FORMAT(x) (((x) & 0x1) << 0)
#define G_028044_FORMAT(x) (((x) >> 0) & 0x1)
#define C_028044_FORMAT 0xFFFFFFFE
#define G_028044_TILE_SPLIT(x) (((x) >> 8) & 0x7)
#define DB_Z_READ_BASE 0x28048
#define DB_STENCIL_READ_BASE 0x2804c
#define DB_Z_WRITE_BASE 0x28050
#define DB_STENCIL_WRITE_BASE 0x28054
#define DB_DEPTH_SIZE 0x28058
#define R_028058_DB_DEPTH_SIZE 0x028058
#define S_028058_PITCH_TILE_MAX(x) (((x) & 0x7FF) << 0)
#define G_028058_PITCH_TILE_MAX(x) (((x) >> 0) & 0x7FF)
#define C_028058_PITCH_TILE_MAX 0xFFFFF800
#define S_028058_HEIGHT_TILE_MAX(x) (((x) & 0x7FF) << 11)
#define G_028058_HEIGHT_TILE_MAX(x) (((x) >> 11) & 0x7FF)
#define C_028058_HEIGHT_TILE_MAX 0xFFC007FF
#define R_02805C_DB_DEPTH_SLICE 0x02805C
#define S_02805C_SLICE_TILE_MAX(x) (((x) & 0x3FFFFF) << 0)
#define G_02805C_SLICE_TILE_MAX(x) (((x) >> 0) & 0x3FFFFF)
#define C_02805C_SLICE_TILE_MAX 0xFFC00000
#define SQ_PGM_START_PS 0x28840
#define SQ_PGM_START_VS 0x2885c
@ -948,6 +1059,14 @@
#define SQ_PGM_START_HS 0x288b8
#define SQ_PGM_START_LS 0x288d0
#define VGT_STRMOUT_BUFFER_BASE_0 0x28AD8
#define VGT_STRMOUT_BUFFER_BASE_1 0x28AE8
#define VGT_STRMOUT_BUFFER_BASE_2 0x28AF8
#define VGT_STRMOUT_BUFFER_BASE_3 0x28B08
#define VGT_STRMOUT_BUFFER_SIZE_0 0x28AD0
#define VGT_STRMOUT_BUFFER_SIZE_1 0x28AE0
#define VGT_STRMOUT_BUFFER_SIZE_2 0x28AF0
#define VGT_STRMOUT_BUFFER_SIZE_3 0x28B00
#define VGT_STRMOUT_CONFIG 0x28b94
#define VGT_STRMOUT_BUFFER_CONFIG 0x28b98
@ -974,6 +1093,114 @@
#define CB_COLOR0_PITCH 0x28c64
#define CB_COLOR0_SLICE 0x28c68
#define CB_COLOR0_VIEW 0x28c6c
#define R_028C6C_CB_COLOR0_VIEW 0x00028C6C
#define S_028C6C_SLICE_START(x) (((x) & 0x7FF) << 0)
#define G_028C6C_SLICE_START(x) (((x) >> 0) & 0x7FF)
#define C_028C6C_SLICE_START 0xFFFFF800
#define S_028C6C_SLICE_MAX(x) (((x) & 0x7FF) << 13)
#define G_028C6C_SLICE_MAX(x) (((x) >> 13) & 0x7FF)
#define C_028C6C_SLICE_MAX 0xFF001FFF
#define R_028C70_CB_COLOR0_INFO 0x028C70
#define S_028C70_ENDIAN(x) (((x) & 0x3) << 0)
#define G_028C70_ENDIAN(x) (((x) >> 0) & 0x3)
#define C_028C70_ENDIAN 0xFFFFFFFC
#define S_028C70_FORMAT(x) (((x) & 0x3F) << 2)
#define G_028C70_FORMAT(x) (((x) >> 2) & 0x3F)
#define C_028C70_FORMAT 0xFFFFFF03
#define V_028C70_COLOR_INVALID 0x00000000
#define V_028C70_COLOR_8 0x00000001
#define V_028C70_COLOR_4_4 0x00000002
#define V_028C70_COLOR_3_3_2 0x00000003
#define V_028C70_COLOR_16 0x00000005
#define V_028C70_COLOR_16_FLOAT 0x00000006
#define V_028C70_COLOR_8_8 0x00000007
#define V_028C70_COLOR_5_6_5 0x00000008
#define V_028C70_COLOR_6_5_5 0x00000009
#define V_028C70_COLOR_1_5_5_5 0x0000000A
#define V_028C70_COLOR_4_4_4_4 0x0000000B
#define V_028C70_COLOR_5_5_5_1 0x0000000C
#define V_028C70_COLOR_32 0x0000000D
#define V_028C70_COLOR_32_FLOAT 0x0000000E
#define V_028C70_COLOR_16_16 0x0000000F
#define V_028C70_COLOR_16_16_FLOAT 0x00000010
#define V_028C70_COLOR_8_24 0x00000011
#define V_028C70_COLOR_8_24_FLOAT 0x00000012
#define V_028C70_COLOR_24_8 0x00000013
#define V_028C70_COLOR_24_8_FLOAT 0x00000014
#define V_028C70_COLOR_10_11_11 0x00000015
#define V_028C70_COLOR_10_11_11_FLOAT 0x00000016
#define V_028C70_COLOR_11_11_10 0x00000017
#define V_028C70_COLOR_11_11_10_FLOAT 0x00000018
#define V_028C70_COLOR_2_10_10_10 0x00000019
#define V_028C70_COLOR_8_8_8_8 0x0000001A
#define V_028C70_COLOR_10_10_10_2 0x0000001B
#define V_028C70_COLOR_X24_8_32_FLOAT 0x0000001C
#define V_028C70_COLOR_32_32 0x0000001D
#define V_028C70_COLOR_32_32_FLOAT 0x0000001E
#define V_028C70_COLOR_16_16_16_16 0x0000001F
#define V_028C70_COLOR_16_16_16_16_FLOAT 0x00000020
#define V_028C70_COLOR_32_32_32_32 0x00000022
#define V_028C70_COLOR_32_32_32_32_FLOAT 0x00000023
#define V_028C70_COLOR_32_32_32_FLOAT 0x00000030
#define S_028C70_ARRAY_MODE(x) (((x) & 0xF) << 8)
#define G_028C70_ARRAY_MODE(x) (((x) >> 8) & 0xF)
#define C_028C70_ARRAY_MODE 0xFFFFF0FF
#define V_028C70_ARRAY_LINEAR_GENERAL 0x00000000
#define V_028C70_ARRAY_LINEAR_ALIGNED 0x00000001
#define V_028C70_ARRAY_1D_TILED_THIN1 0x00000002
#define V_028C70_ARRAY_2D_TILED_THIN1 0x00000004
#define S_028C70_NUMBER_TYPE(x) (((x) & 0x7) << 12)
#define G_028C70_NUMBER_TYPE(x) (((x) >> 12) & 0x7)
#define C_028C70_NUMBER_TYPE 0xFFFF8FFF
#define V_028C70_NUMBER_UNORM 0x00000000
#define V_028C70_NUMBER_SNORM 0x00000001
#define V_028C70_NUMBER_USCALED 0x00000002
#define V_028C70_NUMBER_SSCALED 0x00000003
#define V_028C70_NUMBER_UINT 0x00000004
#define V_028C70_NUMBER_SINT 0x00000005
#define V_028C70_NUMBER_SRGB 0x00000006
#define V_028C70_NUMBER_FLOAT 0x00000007
#define S_028C70_COMP_SWAP(x) (((x) & 0x3) << 15)
#define G_028C70_COMP_SWAP(x) (((x) >> 15) & 0x3)
#define C_028C70_COMP_SWAP 0xFFFE7FFF
#define V_028C70_SWAP_STD 0x00000000
#define V_028C70_SWAP_ALT 0x00000001
#define V_028C70_SWAP_STD_REV 0x00000002
#define V_028C70_SWAP_ALT_REV 0x00000003
#define S_028C70_FAST_CLEAR(x) (((x) & 0x1) << 17)
#define G_028C70_FAST_CLEAR(x) (((x) >> 17) & 0x1)
#define C_028C70_FAST_CLEAR 0xFFFDFFFF
#define S_028C70_COMPRESSION(x) (((x) & 0x3) << 18)
#define G_028C70_COMPRESSION(x) (((x) >> 18) & 0x3)
#define C_028C70_COMPRESSION 0xFFF3FFFF
#define S_028C70_BLEND_CLAMP(x) (((x) & 0x1) << 19)
#define G_028C70_BLEND_CLAMP(x) (((x) >> 19) & 0x1)
#define C_028C70_BLEND_CLAMP 0xFFF7FFFF
#define S_028C70_BLEND_BYPASS(x) (((x) & 0x1) << 20)
#define G_028C70_BLEND_BYPASS(x) (((x) >> 20) & 0x1)
#define C_028C70_BLEND_BYPASS 0xFFEFFFFF
#define S_028C70_SIMPLE_FLOAT(x) (((x) & 0x1) << 21)
#define G_028C70_SIMPLE_FLOAT(x) (((x) >> 21) & 0x1)
#define C_028C70_SIMPLE_FLOAT 0xFFDFFFFF
#define S_028C70_ROUND_MODE(x) (((x) & 0x1) << 22)
#define G_028C70_ROUND_MODE(x) (((x) >> 22) & 0x1)
#define C_028C70_ROUND_MODE 0xFFBFFFFF
#define S_028C70_TILE_COMPACT(x) (((x) & 0x1) << 23)
#define G_028C70_TILE_COMPACT(x) (((x) >> 23) & 0x1)
#define C_028C70_TILE_COMPACT 0xFF7FFFFF
#define S_028C70_SOURCE_FORMAT(x) (((x) & 0x3) << 24)
#define G_028C70_SOURCE_FORMAT(x) (((x) >> 24) & 0x3)
#define C_028C70_SOURCE_FORMAT 0xFCFFFFFF
#define V_028C70_EXPORT_4C_32BPC 0x0
#define V_028C70_EXPORT_4C_16BPC 0x1
#define V_028C70_EXPORT_2C_32BPC 0x2 /* Do not use */
#define S_028C70_RAT(x) (((x) & 0x1) << 26)
#define G_028C70_RAT(x) (((x) >> 26) & 0x1)
#define C_028C70_RAT 0xFBFFFFFF
#define S_028C70_RESOURCE_TYPE(x) (((x) & 0x7) << 27)
#define G_028C70_RESOURCE_TYPE(x) (((x) >> 27) & 0x7)
#define C_028C70_RESOURCE_TYPE 0xC7FFFFFF
#define CB_COLOR0_INFO 0x28c70
# define CB_FORMAT(x) ((x) << 2)
# define CB_ARRAY_MODE(x) ((x) << 8)
@ -984,6 +1211,20 @@
# define CB_SOURCE_FORMAT(x) ((x) << 24)
# define CB_SF_EXPORT_FULL 0
# define CB_SF_EXPORT_NORM 1
#define R_028C74_CB_COLOR0_ATTRIB 0x028C74
#define S_028C74_NON_DISP_TILING_ORDER(x) (((x) & 0x1) << 4)
#define G_028C74_NON_DISP_TILING_ORDER(x) (((x) >> 4) & 0x1)
#define C_028C74_NON_DISP_TILING_ORDER 0xFFFFFFEF
#define S_028C74_TILE_SPLIT(x) (((x) & 0xf) << 5)
#define G_028C74_TILE_SPLIT(x) (((x) >> 5) & 0xf)
#define S_028C74_NUM_BANKS(x) (((x) & 0x3) << 10)
#define G_028C74_NUM_BANKS(x) (((x) >> 10) & 0x3)
#define S_028C74_BANK_WIDTH(x) (((x) & 0x3) << 13)
#define G_028C74_BANK_WIDTH(x) (((x) >> 13) & 0x3)
#define S_028C74_BANK_HEIGHT(x) (((x) & 0x3) << 16)
#define G_028C74_BANK_HEIGHT(x) (((x) >> 16) & 0x3)
#define S_028C74_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 19)
#define G_028C74_MACRO_TILE_ASPECT(x) (((x) >> 19) & 0x3)
#define CB_COLOR0_ATTRIB 0x28c74
# define CB_TILE_SPLIT(x) (((x) & 0x7) << 5)
# define ADDR_SURF_TILE_SPLIT_64B 0
@ -1008,6 +1249,7 @@
# define ADDR_SURF_BANK_HEIGHT_2 1
# define ADDR_SURF_BANK_HEIGHT_4 2
# define ADDR_SURF_BANK_HEIGHT_8 3
# define CB_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 19)
#define CB_COLOR0_DIM 0x28c78
/* only CB0-7 blocks have these regs */
#define CB_COLOR0_CMASK 0x28c7c
@ -1196,9 +1438,144 @@
#define SQ_TEX_RESOURCE_WORD6_0 0x30018
# define TEX_TILE_SPLIT(x) (((x) & 0x7) << 29)
#define SQ_TEX_RESOURCE_WORD7_0 0x3001c
# define MACRO_TILE_ASPECT(x) (((x) & 0x3) << 6)
# define TEX_BANK_WIDTH(x) (((x) & 0x3) << 8)
# define TEX_BANK_HEIGHT(x) (((x) & 0x3) << 10)
# define TEX_NUM_BANKS(x) (((x) & 0x3) << 16)
#define R_030000_SQ_TEX_RESOURCE_WORD0_0 0x030000
#define S_030000_DIM(x) (((x) & 0x7) << 0)
#define G_030000_DIM(x) (((x) >> 0) & 0x7)
#define C_030000_DIM 0xFFFFFFF8
#define V_030000_SQ_TEX_DIM_1D 0x00000000
#define V_030000_SQ_TEX_DIM_2D 0x00000001
#define V_030000_SQ_TEX_DIM_3D 0x00000002
#define V_030000_SQ_TEX_DIM_CUBEMAP 0x00000003
#define V_030000_SQ_TEX_DIM_1D_ARRAY 0x00000004
#define V_030000_SQ_TEX_DIM_2D_ARRAY 0x00000005
#define V_030000_SQ_TEX_DIM_2D_MSAA 0x00000006
#define V_030000_SQ_TEX_DIM_2D_ARRAY_MSAA 0x00000007
#define S_030000_NON_DISP_TILING_ORDER(x) (((x) & 0x1) << 5)
#define G_030000_NON_DISP_TILING_ORDER(x) (((x) >> 5) & 0x1)
#define C_030000_NON_DISP_TILING_ORDER 0xFFFFFFDF
#define S_030000_PITCH(x) (((x) & 0xFFF) << 6)
#define G_030000_PITCH(x) (((x) >> 6) & 0xFFF)
#define C_030000_PITCH 0xFFFC003F
#define S_030000_TEX_WIDTH(x) (((x) & 0x3FFF) << 18)
#define G_030000_TEX_WIDTH(x) (((x) >> 18) & 0x3FFF)
#define C_030000_TEX_WIDTH 0x0003FFFF
#define R_030004_SQ_TEX_RESOURCE_WORD1_0 0x030004
#define S_030004_TEX_HEIGHT(x) (((x) & 0x3FFF) << 0)
#define G_030004_TEX_HEIGHT(x) (((x) >> 0) & 0x3FFF)
#define C_030004_TEX_HEIGHT 0xFFFFC000
#define S_030004_TEX_DEPTH(x) (((x) & 0x1FFF) << 14)
#define G_030004_TEX_DEPTH(x) (((x) >> 14) & 0x1FFF)
#define C_030004_TEX_DEPTH 0xF8003FFF
#define S_030004_ARRAY_MODE(x) (((x) & 0xF) << 28)
#define G_030004_ARRAY_MODE(x) (((x) >> 28) & 0xF)
#define C_030004_ARRAY_MODE 0x0FFFFFFF
#define R_030008_SQ_TEX_RESOURCE_WORD2_0 0x030008
#define S_030008_BASE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0)
#define G_030008_BASE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF)
#define C_030008_BASE_ADDRESS 0x00000000
#define R_03000C_SQ_TEX_RESOURCE_WORD3_0 0x03000C
#define S_03000C_MIP_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0)
#define G_03000C_MIP_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF)
#define C_03000C_MIP_ADDRESS 0x00000000
#define R_030010_SQ_TEX_RESOURCE_WORD4_0 0x030010
#define S_030010_FORMAT_COMP_X(x) (((x) & 0x3) << 0)
#define G_030010_FORMAT_COMP_X(x) (((x) >> 0) & 0x3)
#define C_030010_FORMAT_COMP_X 0xFFFFFFFC
#define V_030010_SQ_FORMAT_COMP_UNSIGNED 0x00000000
#define V_030010_SQ_FORMAT_COMP_SIGNED 0x00000001
#define V_030010_SQ_FORMAT_COMP_UNSIGNED_BIASED 0x00000002
#define S_030010_FORMAT_COMP_Y(x) (((x) & 0x3) << 2)
#define G_030010_FORMAT_COMP_Y(x) (((x) >> 2) & 0x3)
#define C_030010_FORMAT_COMP_Y 0xFFFFFFF3
#define S_030010_FORMAT_COMP_Z(x) (((x) & 0x3) << 4)
#define G_030010_FORMAT_COMP_Z(x) (((x) >> 4) & 0x3)
#define C_030010_FORMAT_COMP_Z 0xFFFFFFCF
#define S_030010_FORMAT_COMP_W(x) (((x) & 0x3) << 6)
#define G_030010_FORMAT_COMP_W(x) (((x) >> 6) & 0x3)
#define C_030010_FORMAT_COMP_W 0xFFFFFF3F
#define S_030010_NUM_FORMAT_ALL(x) (((x) & 0x3) << 8)
#define G_030010_NUM_FORMAT_ALL(x) (((x) >> 8) & 0x3)
#define C_030010_NUM_FORMAT_ALL 0xFFFFFCFF
#define V_030010_SQ_NUM_FORMAT_NORM 0x00000000
#define V_030010_SQ_NUM_FORMAT_INT 0x00000001
#define V_030010_SQ_NUM_FORMAT_SCALED 0x00000002
#define S_030010_SRF_MODE_ALL(x) (((x) & 0x1) << 10)
#define G_030010_SRF_MODE_ALL(x) (((x) >> 10) & 0x1)
#define C_030010_SRF_MODE_ALL 0xFFFFFBFF
#define V_030010_SRF_MODE_ZERO_CLAMP_MINUS_ONE 0x00000000
#define V_030010_SRF_MODE_NO_ZERO 0x00000001
#define S_030010_FORCE_DEGAMMA(x) (((x) & 0x1) << 11)
#define G_030010_FORCE_DEGAMMA(x) (((x) >> 11) & 0x1)
#define C_030010_FORCE_DEGAMMA 0xFFFFF7FF
#define S_030010_ENDIAN_SWAP(x) (((x) & 0x3) << 12)
#define G_030010_ENDIAN_SWAP(x) (((x) >> 12) & 0x3)
#define C_030010_ENDIAN_SWAP 0xFFFFCFFF
#define S_030010_DST_SEL_X(x) (((x) & 0x7) << 16)
#define G_030010_DST_SEL_X(x) (((x) >> 16) & 0x7)
#define C_030010_DST_SEL_X 0xFFF8FFFF
#define V_030010_SQ_SEL_X 0x00000000
#define V_030010_SQ_SEL_Y 0x00000001
#define V_030010_SQ_SEL_Z 0x00000002
#define V_030010_SQ_SEL_W 0x00000003
#define V_030010_SQ_SEL_0 0x00000004
#define V_030010_SQ_SEL_1 0x00000005
#define S_030010_DST_SEL_Y(x) (((x) & 0x7) << 19)
#define G_030010_DST_SEL_Y(x) (((x) >> 19) & 0x7)
#define C_030010_DST_SEL_Y 0xFFC7FFFF
#define S_030010_DST_SEL_Z(x) (((x) & 0x7) << 22)
#define G_030010_DST_SEL_Z(x) (((x) >> 22) & 0x7)
#define C_030010_DST_SEL_Z 0xFE3FFFFF
#define S_030010_DST_SEL_W(x) (((x) & 0x7) << 25)
#define G_030010_DST_SEL_W(x) (((x) >> 25) & 0x7)
#define C_030010_DST_SEL_W 0xF1FFFFFF
#define S_030010_BASE_LEVEL(x) (((x) & 0xF) << 28)
#define G_030010_BASE_LEVEL(x) (((x) >> 28) & 0xF)
#define C_030010_BASE_LEVEL 0x0FFFFFFF
#define R_030014_SQ_TEX_RESOURCE_WORD5_0 0x030014
#define S_030014_LAST_LEVEL(x) (((x) & 0xF) << 0)
#define G_030014_LAST_LEVEL(x) (((x) >> 0) & 0xF)
#define C_030014_LAST_LEVEL 0xFFFFFFF0
#define S_030014_BASE_ARRAY(x) (((x) & 0x1FFF) << 4)
#define G_030014_BASE_ARRAY(x) (((x) >> 4) & 0x1FFF)
#define C_030014_BASE_ARRAY 0xFFFE000F
#define S_030014_LAST_ARRAY(x) (((x) & 0x1FFF) << 17)
#define G_030014_LAST_ARRAY(x) (((x) >> 17) & 0x1FFF)
#define C_030014_LAST_ARRAY 0xC001FFFF
#define R_030018_SQ_TEX_RESOURCE_WORD6_0 0x030018
#define S_030018_MAX_ANISO(x) (((x) & 0x7) << 0)
#define G_030018_MAX_ANISO(x) (((x) >> 0) & 0x7)
#define C_030018_MAX_ANISO 0xFFFFFFF8
#define S_030018_PERF_MODULATION(x) (((x) & 0x7) << 3)
#define G_030018_PERF_MODULATION(x) (((x) >> 3) & 0x7)
#define C_030018_PERF_MODULATION 0xFFFFFFC7
#define S_030018_INTERLACED(x) (((x) & 0x1) << 6)
#define G_030018_INTERLACED(x) (((x) >> 6) & 0x1)
#define C_030018_INTERLACED 0xFFFFFFBF
#define S_030018_TILE_SPLIT(x) (((x) & 0x7) << 29)
#define G_030018_TILE_SPLIT(x) (((x) >> 29) & 0x7)
#define R_03001C_SQ_TEX_RESOURCE_WORD7_0 0x03001C
#define S_03001C_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 6)
#define G_03001C_MACRO_TILE_ASPECT(x) (((x) >> 6) & 0x3)
#define S_03001C_BANK_WIDTH(x) (((x) & 0x3) << 8)
#define G_03001C_BANK_WIDTH(x) (((x) >> 8) & 0x3)
#define S_03001C_BANK_HEIGHT(x) (((x) & 0x3) << 10)
#define G_03001C_BANK_HEIGHT(x) (((x) >> 10) & 0x3)
#define S_03001C_NUM_BANKS(x) (((x) & 0x3) << 16)
#define G_03001C_NUM_BANKS(x) (((x) >> 16) & 0x3)
#define S_03001C_TYPE(x) (((x) & 0x3) << 30)
#define G_03001C_TYPE(x) (((x) >> 30) & 0x3)
#define C_03001C_TYPE 0x3FFFFFFF
#define V_03001C_SQ_TEX_VTX_INVALID_TEXTURE 0x00000000
#define V_03001C_SQ_TEX_VTX_INVALID_BUFFER 0x00000001
#define V_03001C_SQ_TEX_VTX_VALID_TEXTURE 0x00000002
#define V_03001C_SQ_TEX_VTX_VALID_BUFFER 0x00000003
#define S_03001C_DATA_FORMAT(x) (((x) & 0x3F) << 0)
#define G_03001C_DATA_FORMAT(x) (((x) >> 0) & 0x3F)
#define C_03001C_DATA_FORMAT 0xFFFFFFC0
#define SQ_VTX_CONSTANT_WORD0_0 0x30000
#define SQ_VTX_CONSTANT_WORD1_0 0x30004

View file

@ -87,23 +87,27 @@ int r100_reloc_pitch_offset(struct radeon_cs_parser *p,
r100_cs_dump_packet(p, pkt);
return r;
}
value = radeon_get_ib_value(p, idx);
tmp = value & 0x003fffff;
tmp += (((u32)reloc->lobj.gpu_offset) >> 10);
if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
tile_flags |= RADEON_DST_TILE_MACRO;
if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
if (reg == RADEON_SRC_PITCH_OFFSET) {
DRM_ERROR("Cannot src blit from microtiled surface\n");
r100_cs_dump_packet(p, pkt);
return -EINVAL;
if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
tile_flags |= RADEON_DST_TILE_MACRO;
if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) {
if (reg == RADEON_SRC_PITCH_OFFSET) {
DRM_ERROR("Cannot src blit from microtiled surface\n");
r100_cs_dump_packet(p, pkt);
return -EINVAL;
}
tile_flags |= RADEON_DST_TILE_MICRO;
}
tile_flags |= RADEON_DST_TILE_MICRO;
}
tmp |= tile_flags;
p->ib->ptr[idx] = (value & 0x3fc00000) | tmp;
tmp |= tile_flags;
p->ib->ptr[idx] = (value & 0x3fc00000) | tmp;
} else
p->ib->ptr[idx] = (value & 0xffc00000) | tmp;
return 0;
}
@ -1554,7 +1558,17 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
r100_cs_dump_packet(p, pkt);
return r;
}
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
tile_flags |= RADEON_TXO_MACRO_TILE;
if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
tile_flags |= RADEON_TXO_MICRO_TILE_X2;
tmp = idx_value & ~(0x7 << 2);
tmp |= tile_flags;
ib[idx] = tmp + ((u32)reloc->lobj.gpu_offset);
} else
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
track->textures[i].robj = reloc->robj;
track->tex_dirty = true;
break;
@ -1625,15 +1639,17 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
r100_cs_dump_packet(p, pkt);
return r;
}
if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
tile_flags |= RADEON_COLOR_TILE_ENABLE;
if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
tile_flags |= RADEON_COLOR_TILE_ENABLE;
if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
tmp = idx_value & ~(0x7 << 16);
tmp |= tile_flags;
ib[idx] = tmp;
tmp = idx_value & ~(0x7 << 16);
tmp |= tile_flags;
ib[idx] = tmp;
} else
ib[idx] = idx_value;
track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK;
track->cb_dirty = true;

View file

@ -215,7 +215,17 @@ int r200_packet0_check(struct radeon_cs_parser *p,
r100_cs_dump_packet(p, pkt);
return r;
}
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
tile_flags |= R200_TXO_MACRO_TILE;
if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
tile_flags |= R200_TXO_MICRO_TILE;
tmp = idx_value & ~(0x7 << 2);
tmp |= tile_flags;
ib[idx] = tmp + ((u32)reloc->lobj.gpu_offset);
} else
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
track->textures[i].robj = reloc->robj;
track->tex_dirty = true;
break;
@ -277,14 +287,17 @@ int r200_packet0_check(struct radeon_cs_parser *p,
return r;
}
if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
tile_flags |= RADEON_COLOR_TILE_ENABLE;
if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) {
if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO)
tile_flags |= RADEON_COLOR_TILE_ENABLE;
if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
tmp = idx_value & ~(0x7 << 16);
tmp |= tile_flags;
ib[idx] = tmp;
tmp = idx_value & ~(0x7 << 16);
tmp |= tile_flags;
ib[idx] = tmp;
} else
ib[idx] = idx_value;
track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK;
track->cb_dirty = true;

View file

@ -30,20 +30,7 @@
#include "r600d.h"
#include "r600_blit_shaders.h"
#define DI_PT_RECTLIST 0x11
#define DI_INDEX_SIZE_16_BIT 0x0
#define DI_SRC_SEL_AUTO_INDEX 0x2
#define FMT_8 0x1
#define FMT_5_6_5 0x8
#define FMT_8_8_8_8 0x1a
#define COLOR_8 0x1
#define COLOR_5_6_5 0x8
#define COLOR_8_8_8_8 0x1a
#define RECT_UNIT_H 32
#define RECT_UNIT_W (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H)
#include "radeon_blit_common.h"
/* emits 21 on rv770+, 23 on r600 */
static void

View file

@ -55,12 +55,17 @@ struct r600_cs_track {
struct radeon_bo *cb_color_frag_bo[8];
struct radeon_bo *cb_color_tile_bo[8];
u32 cb_color_info[8];
u32 cb_color_view[8];
u32 cb_color_size_idx[8];
u32 cb_target_mask;
u32 cb_shader_mask;
u32 cb_color_size[8];
u32 vgt_strmout_en;
u32 vgt_strmout_buffer_en;
struct radeon_bo *vgt_strmout_bo[4];
u64 vgt_strmout_bo_mc[4];
u32 vgt_strmout_bo_offset[4];
u32 vgt_strmout_size[4];
u32 db_depth_control;
u32 db_depth_info;
u32 db_depth_size_idx;
@ -73,9 +78,9 @@ struct r600_cs_track {
#define FMT_8_BIT(fmt, vc) [fmt] = { 1, 1, 1, vc, CHIP_R600 }
#define FMT_16_BIT(fmt, vc) [fmt] = { 1, 1, 2, vc, CHIP_R600 }
#define FMT_24_BIT(fmt) [fmt] = { 1, 1, 3, 0, CHIP_R600 }
#define FMT_24_BIT(fmt) [fmt] = { 1, 1, 4, 0, CHIP_R600 }
#define FMT_32_BIT(fmt, vc) [fmt] = { 1, 1, 4, vc, CHIP_R600 }
#define FMT_48_BIT(fmt) [fmt] = { 1, 1, 6, 0, CHIP_R600 }
#define FMT_48_BIT(fmt) [fmt] = { 1, 1, 8, 0, CHIP_R600 }
#define FMT_64_BIT(fmt, vc) [fmt] = { 1, 1, 8, vc, CHIP_R600 }
#define FMT_96_BIT(fmt) [fmt] = { 1, 1, 12, 0, CHIP_R600 }
#define FMT_128_BIT(fmt, vc) [fmt] = { 1, 1, 16,vc, CHIP_R600 }
@ -107,7 +112,7 @@ static const struct gpu_formats color_formats_table[] = {
/* 24-bit */
FMT_24_BIT(V_038004_FMT_8_8_8),
/* 32-bit */
FMT_32_BIT(V_038004_COLOR_32, 1),
FMT_32_BIT(V_038004_COLOR_32_FLOAT, 1),
@ -162,22 +167,22 @@ static const struct gpu_formats color_formats_table[] = {
[V_038004_FMT_32_AS_32_32_32_32] = { 1, 1, 4, 0, CHIP_CEDAR},
};
static bool fmt_is_valid_color(u32 format)
bool r600_fmt_is_valid_color(u32 format)
{
if (format >= ARRAY_SIZE(color_formats_table))
return false;
if (color_formats_table[format].valid_color)
return true;
return false;
}
static bool fmt_is_valid_texture(u32 format, enum radeon_family family)
bool r600_fmt_is_valid_texture(u32 format, enum radeon_family family)
{
if (format >= ARRAY_SIZE(color_formats_table))
return false;
if (family < color_formats_table[format].min_family)
return false;
@ -187,7 +192,7 @@ static bool fmt_is_valid_texture(u32 format, enum radeon_family family)
return false;
}
static int fmt_get_blocksize(u32 format)
int r600_fmt_get_blocksize(u32 format)
{
if (format >= ARRAY_SIZE(color_formats_table))
return 0;
@ -195,7 +200,7 @@ static int fmt_get_blocksize(u32 format)
return color_formats_table[format].blocksize;
}
static int fmt_get_nblocksx(u32 format, u32 w)
int r600_fmt_get_nblocksx(u32 format, u32 w)
{
unsigned bw;
@ -209,7 +214,7 @@ static int fmt_get_nblocksx(u32 format, u32 w)
return (w + bw - 1) / bw;
}
static int fmt_get_nblocksy(u32 format, u32 h)
int r600_fmt_get_nblocksy(u32 format, u32 h)
{
unsigned bh;
@ -256,7 +261,7 @@ static int r600_get_array_mode_alignment(struct array_mode_checker *values,
break;
case ARRAY_LINEAR_ALIGNED:
*pitch_align = max((u32)64, (u32)(values->group_size / values->blocksize));
*height_align = tile_height;
*height_align = 1;
*depth_align = 1;
*base_align = values->group_size;
break;
@ -269,10 +274,9 @@ static int r600_get_array_mode_alignment(struct array_mode_checker *values,
*base_align = values->group_size;
break;
case ARRAY_2D_TILED_THIN1:
*pitch_align = max((u32)macro_tile_width,
(u32)(((values->group_size / tile_height) /
(values->blocksize * values->nsamples)) *
values->nbanks)) * tile_width;
*pitch_align = max((u32)macro_tile_width * tile_width,
(u32)((values->group_size * values->nbanks) /
(values->blocksize * values->nsamples * tile_width)));
*height_align = macro_tile_height * tile_height;
*depth_align = 1;
*base_align = max(macro_tile_bytes,
@ -296,6 +300,7 @@ static void r600_cs_track_init(struct r600_cs_track *track)
track->cb_color_size[i] = 0;
track->cb_color_size_idx[i] = 0;
track->cb_color_info[i] = 0;
track->cb_color_view[i] = 0xFFFFFFFF;
track->cb_color_bo[i] = NULL;
track->cb_color_bo_offset[i] = 0xFFFFFFFF;
track->cb_color_bo_mc[i] = 0xFFFFFFFF;
@ -310,6 +315,13 @@ static void r600_cs_track_init(struct r600_cs_track *track)
track->db_depth_size = 0xFFFFFFFF;
track->db_depth_size_idx = 0;
track->db_depth_control = 0xFFFFFFFF;
for (i = 0; i < 4; i++) {
track->vgt_strmout_size[i] = 0;
track->vgt_strmout_bo[i] = NULL;
track->vgt_strmout_bo_offset[i] = 0xFFFFFFFF;
track->vgt_strmout_bo_mc[i] = 0xFFFFFFFF;
}
}
static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
@ -322,13 +334,14 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
volatile u32 *ib = p->ib->ptr;
unsigned array_mode;
u32 format;
if (G_0280A0_TILE_MODE(track->cb_color_info[i])) {
dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n");
return -EINVAL;
}
size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i];
format = G_0280A0_FORMAT(track->cb_color_info[i]);
if (!fmt_is_valid_color(format)) {
if (!r600_fmt_is_valid_color(format)) {
dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08X)\n",
__func__, __LINE__, format,
i, track->cb_color_info[i]);
@ -349,7 +362,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
array_check.nbanks = track->nbanks;
array_check.npipes = track->npipes;
array_check.nsamples = track->nsamples;
array_check.blocksize = fmt_get_blocksize(format);
array_check.blocksize = r600_fmt_get_blocksize(format);
if (r600_get_array_mode_alignment(&array_check,
&pitch_align, &height_align, &depth_align, &base_align)) {
dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__,
@ -393,7 +406,18 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
}
/* check offset */
tmp = fmt_get_nblocksy(format, height) * fmt_get_nblocksx(format, pitch) * fmt_get_blocksize(format);
tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * r600_fmt_get_blocksize(format);
switch (array_mode) {
default:
case V_0280A0_ARRAY_LINEAR_GENERAL:
case V_0280A0_ARRAY_LINEAR_ALIGNED:
tmp += track->cb_color_view[i] & 0xFF;
break;
case V_0280A0_ARRAY_1D_TILED_THIN1:
case V_0280A0_ARRAY_2D_TILED_THIN1:
tmp += G_028080_SLICE_MAX(track->cb_color_view[i]) * tmp;
break;
}
if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) {
if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) {
/* the initial DDX does bad things with the CB size occasionally */
@ -403,10 +427,13 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
* broken userspace.
*/
} else {
dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big\n", __func__, i,
array_mode,
dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big (%d %d) (%d %d %d)\n",
__func__, i, array_mode,
track->cb_color_bo_offset[i], tmp,
radeon_bo_size(track->cb_color_bo[i]));
radeon_bo_size(track->cb_color_bo[i]),
pitch, height, r600_fmt_get_nblocksx(format, pitch),
r600_fmt_get_nblocksy(format, height),
r600_fmt_get_blocksize(format));
return -EINVAL;
}
}
@ -430,11 +457,28 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
/* on legacy kernel we don't perform advanced check */
if (p->rdev == NULL)
return 0;
/* we don't support out buffer yet */
if (track->vgt_strmout_en || track->vgt_strmout_buffer_en) {
dev_warn(p->dev, "this kernel doesn't support SMX output buffer\n");
return -EINVAL;
/* check streamout */
if (track->vgt_strmout_en) {
for (i = 0; i < 4; i++) {
if (track->vgt_strmout_buffer_en & (1 << i)) {
if (track->vgt_strmout_bo[i]) {
u64 offset = (u64)track->vgt_strmout_bo_offset[i] +
(u64)track->vgt_strmout_size[i];
if (offset > radeon_bo_size(track->vgt_strmout_bo[i])) {
DRM_ERROR("streamout %d bo too small: 0x%llx, 0x%lx\n",
i, offset,
radeon_bo_size(track->vgt_strmout_bo[i]));
return -EINVAL;
}
} else {
dev_warn(p->dev, "No buffer for streamout %d\n", i);
return -EINVAL;
}
}
}
}
/* check that we have a cb for each enabled target, we don't check
* shader_mask because it seems mesa isn't always setting it :(
*/
@ -975,6 +1019,39 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
case R_028B20_VGT_STRMOUT_BUFFER_EN:
track->vgt_strmout_buffer_en = radeon_get_ib_value(p, idx);
break;
case VGT_STRMOUT_BUFFER_BASE_0:
case VGT_STRMOUT_BUFFER_BASE_1:
case VGT_STRMOUT_BUFFER_BASE_2:
case VGT_STRMOUT_BUFFER_BASE_3:
r = r600_cs_packet_next_reloc(p, &reloc);
if (r) {
dev_warn(p->dev, "bad SET_CONTEXT_REG "
"0x%04X\n", reg);
return -EINVAL;
}
tmp = (reg - VGT_STRMOUT_BUFFER_BASE_0) / 16;
track->vgt_strmout_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8;
ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
track->vgt_strmout_bo[tmp] = reloc->robj;
track->vgt_strmout_bo_mc[tmp] = reloc->lobj.gpu_offset;
break;
case VGT_STRMOUT_BUFFER_SIZE_0:
case VGT_STRMOUT_BUFFER_SIZE_1:
case VGT_STRMOUT_BUFFER_SIZE_2:
case VGT_STRMOUT_BUFFER_SIZE_3:
tmp = (reg - VGT_STRMOUT_BUFFER_SIZE_0) / 16;
/* size in register is DWs, convert to bytes */
track->vgt_strmout_size[tmp] = radeon_get_ib_value(p, idx) * 4;
break;
case CP_COHER_BASE:
r = r600_cs_packet_next_reloc(p, &reloc);
if (r) {
dev_warn(p->dev, "missing reloc for CP_COHER_BASE "
"0x%04X\n", reg);
return -EINVAL;
}
ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff);
break;
case R_028238_CB_TARGET_MASK:
track->cb_target_mask = radeon_get_ib_value(p, idx);
break;
@ -1014,6 +1091,17 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
track->cb_color_info[tmp] = radeon_get_ib_value(p, idx);
}
break;
case R_028080_CB_COLOR0_VIEW:
case R_028084_CB_COLOR1_VIEW:
case R_028088_CB_COLOR2_VIEW:
case R_02808C_CB_COLOR3_VIEW:
case R_028090_CB_COLOR4_VIEW:
case R_028094_CB_COLOR5_VIEW:
case R_028098_CB_COLOR6_VIEW:
case R_02809C_CB_COLOR7_VIEW:
tmp = (reg - R_028080_CB_COLOR0_VIEW) / 4;
track->cb_color_view[tmp] = radeon_get_ib_value(p, idx);
break;
case R_028060_CB_COLOR0_SIZE:
case R_028064_CB_COLOR1_SIZE:
case R_028068_CB_COLOR2_SIZE:
@ -1198,7 +1286,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
return 0;
}
static unsigned mip_minify(unsigned size, unsigned level)
unsigned r600_mip_minify(unsigned size, unsigned level)
{
unsigned val;
@ -1220,22 +1308,22 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel,
unsigned nlevels = llevel - blevel + 1;
*l0_size = -1;
blocksize = fmt_get_blocksize(format);
blocksize = r600_fmt_get_blocksize(format);
w0 = mip_minify(w0, 0);
h0 = mip_minify(h0, 0);
d0 = mip_minify(d0, 0);
w0 = r600_mip_minify(w0, 0);
h0 = r600_mip_minify(h0, 0);
d0 = r600_mip_minify(d0, 0);
for(i = 0, offset = 0, level = blevel; i < nlevels; i++, level++) {
width = mip_minify(w0, i);
nbx = fmt_get_nblocksx(format, width);
width = r600_mip_minify(w0, i);
nbx = r600_fmt_get_nblocksx(format, width);
nbx = round_up(nbx, block_align);
height = mip_minify(h0, i);
nby = fmt_get_nblocksy(format, height);
height = r600_mip_minify(h0, i);
nby = r600_fmt_get_nblocksy(format, height);
nby = round_up(nby, height_align);
depth = mip_minify(d0, i);
depth = r600_mip_minify(d0, i);
size = nbx * nby * blocksize;
if (nfaces)
@ -1326,7 +1414,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx,
return -EINVAL;
}
format = G_038004_DATA_FORMAT(word1);
if (!fmt_is_valid_texture(format, p->family)) {
if (!r600_fmt_is_valid_texture(format, p->family)) {
dev_warn(p->dev, "%s:%d texture invalid format %d\n",
__func__, __LINE__, format);
return -EINVAL;
@ -1339,7 +1427,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx,
array_check.nbanks = track->nbanks;
array_check.npipes = track->npipes;
array_check.nsamples = 1;
array_check.blocksize = fmt_get_blocksize(format);
array_check.blocksize = r600_fmt_get_blocksize(format);
if (r600_get_array_mode_alignment(&array_check,
&pitch_align, &height_align, &depth_align, &base_align)) {
dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n",
@ -1372,6 +1460,10 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx,
word1 = radeon_get_ib_value(p, idx + 5);
blevel = G_038010_BASE_LEVEL(word0);
llevel = G_038014_LAST_LEVEL(word1);
if (blevel > llevel) {
dev_warn(p->dev, "texture blevel %d > llevel %d\n",
blevel, llevel);
}
if (array == 1) {
barray = G_038014_BASE_ARRAY(word1);
larray = G_038014_LAST_ARRAY(word1);
@ -1383,8 +1475,10 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx,
&l0_size, &mipmap_size);
/* using get ib will give us the offset into the texture bo */
if ((l0_size + word2) > radeon_bo_size(texture)) {
dev_warn(p->dev, "texture bo too small (%d %d %d %d -> %d have %ld)\n",
w0, h0, format, word2, l0_size, radeon_bo_size(texture));
dev_warn(p->dev, "texture bo too small ((%d %d) (%d %d) %d %d %d -> %d have %ld)\n",
w0, h0, pitch_align, height_align,
array_check.array_mode, format, word2,
l0_size, radeon_bo_size(texture));
dev_warn(p->dev, "alignments %d %d %d %lld\n", pitch, pitch_align, height_align, base_align);
return -EINVAL;
}
@ -1397,6 +1491,22 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx,
return 0;
}
static bool r600_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
{
u32 m, i;
i = (reg >> 7);
if (i >= ARRAY_SIZE(r600_reg_safe_bm)) {
dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
return false;
}
m = 1 << ((reg >> 2) & 31);
if (!(r600_reg_safe_bm[i] & m))
return true;
dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx);
return false;
}
static int r600_packet3_check(struct radeon_cs_parser *p,
struct radeon_cs_packet *pkt)
{
@ -1742,6 +1852,100 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
return -EINVAL;
}
break;
case PACKET3_STRMOUT_BUFFER_UPDATE:
if (pkt->count != 4) {
DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (invalid count)\n");
return -EINVAL;
}
/* Updating memory at DST_ADDRESS. */
if (idx_value & 0x1) {
u64 offset;
r = r600_cs_packet_next_reloc(p, &reloc);
if (r) {
DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing dst reloc)\n");
return -EINVAL;
}
offset = radeon_get_ib_value(p, idx+1);
offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32;
if ((offset + 4) > radeon_bo_size(reloc->robj)) {
DRM_ERROR("bad STRMOUT_BUFFER_UPDATE dst bo too small: 0x%llx, 0x%lx\n",
offset + 4, radeon_bo_size(reloc->robj));
return -EINVAL;
}
ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
}
/* Reading data from SRC_ADDRESS. */
if (((idx_value >> 1) & 0x3) == 2) {
u64 offset;
r = r600_cs_packet_next_reloc(p, &reloc);
if (r) {
DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing src reloc)\n");
return -EINVAL;
}
offset = radeon_get_ib_value(p, idx+3);
offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
if ((offset + 4) > radeon_bo_size(reloc->robj)) {
DRM_ERROR("bad STRMOUT_BUFFER_UPDATE src bo too small: 0x%llx, 0x%lx\n",
offset + 4, radeon_bo_size(reloc->robj));
return -EINVAL;
}
ib[idx+3] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
ib[idx+4] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
}
break;
case PACKET3_COPY_DW:
if (pkt->count != 4) {
DRM_ERROR("bad COPY_DW (invalid count)\n");
return -EINVAL;
}
if (idx_value & 0x1) {
u64 offset;
/* SRC is memory. */
r = r600_cs_packet_next_reloc(p, &reloc);
if (r) {
DRM_ERROR("bad COPY_DW (missing src reloc)\n");
return -EINVAL;
}
offset = radeon_get_ib_value(p, idx+1);
offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32;
if ((offset + 4) > radeon_bo_size(reloc->robj)) {
DRM_ERROR("bad COPY_DW src bo too small: 0x%llx, 0x%lx\n",
offset + 4, radeon_bo_size(reloc->robj));
return -EINVAL;
}
ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
} else {
/* SRC is a reg. */
reg = radeon_get_ib_value(p, idx+1) << 2;
if (!r600_is_safe_reg(p, reg, idx+1))
return -EINVAL;
}
if (idx_value & 0x2) {
u64 offset;
/* DST is memory. */
r = r600_cs_packet_next_reloc(p, &reloc);
if (r) {
DRM_ERROR("bad COPY_DW (missing dst reloc)\n");
return -EINVAL;
}
offset = radeon_get_ib_value(p, idx+3);
offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
if ((offset + 4) > radeon_bo_size(reloc->robj)) {
DRM_ERROR("bad COPY_DW dst bo too small: 0x%llx, 0x%lx\n",
offset + 4, radeon_bo_size(reloc->robj));
return -EINVAL;
}
ib[idx+3] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
ib[idx+4] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
} else {
/* DST is a reg. */
reg = radeon_get_ib_value(p, idx+3) << 2;
if (!r600_is_safe_reg(p, reg, idx+3))
return -EINVAL;
}
break;
case PACKET3_NOP:
break;
default:

View file

@ -78,6 +78,20 @@
#define CB_COLOR0_SIZE 0x28060
#define CB_COLOR0_VIEW 0x28080
#define R_028080_CB_COLOR0_VIEW 0x028080
#define S_028080_SLICE_START(x) (((x) & 0x7FF) << 0)
#define G_028080_SLICE_START(x) (((x) >> 0) & 0x7FF)
#define C_028080_SLICE_START 0xFFFFF800
#define S_028080_SLICE_MAX(x) (((x) & 0x7FF) << 13)
#define G_028080_SLICE_MAX(x) (((x) >> 13) & 0x7FF)
#define C_028080_SLICE_MAX 0xFF001FFF
#define R_028084_CB_COLOR1_VIEW 0x028084
#define R_028088_CB_COLOR2_VIEW 0x028088
#define R_02808C_CB_COLOR3_VIEW 0x02808C
#define R_028090_CB_COLOR4_VIEW 0x028090
#define R_028094_CB_COLOR5_VIEW 0x028094
#define R_028098_CB_COLOR6_VIEW 0x028098
#define R_02809C_CB_COLOR7_VIEW 0x02809C
#define CB_COLOR0_INFO 0x280a0
# define CB_FORMAT(x) ((x) << 2)
# define CB_ARRAY_MODE(x) ((x) << 8)
@ -493,6 +507,11 @@
#define VGT_STRMOUT_BUFFER_OFFSET_1 0x28AEC
#define VGT_STRMOUT_BUFFER_OFFSET_2 0x28AFC
#define VGT_STRMOUT_BUFFER_OFFSET_3 0x28B0C
#define VGT_STRMOUT_BUFFER_SIZE_0 0x28AD0
#define VGT_STRMOUT_BUFFER_SIZE_1 0x28AE0
#define VGT_STRMOUT_BUFFER_SIZE_2 0x28AF0
#define VGT_STRMOUT_BUFFER_SIZE_3 0x28B00
#define VGT_STRMOUT_EN 0x28AB0
#define VGT_VERTEX_REUSE_BLOCK_CNTL 0x28C58
#define VTX_REUSE_DEPTH_MASK 0x000000FF
@ -834,6 +853,7 @@
# define PACKET3_SEM_SEL_SIGNAL (0x6 << 29)
# define PACKET3_SEM_SEL_WAIT (0x7 << 29)
#define PACKET3_MPEG_INDEX 0x3A
#define PACKET3_COPY_DW 0x3B
#define PACKET3_WAIT_REG_MEM 0x3C
#define PACKET3_MEM_WRITE 0x3D
#define PACKET3_INDIRECT_BUFFER 0x32

View file

@ -242,6 +242,9 @@ extern int rv6xx_get_temp(struct radeon_device *rdev);
extern int rv770_get_temp(struct radeon_device *rdev);
extern int evergreen_get_temp(struct radeon_device *rdev);
extern int sumo_get_temp(struct radeon_device *rdev);
extern void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw,
unsigned *bankh, unsigned *mtaspect,
unsigned *tile_split);
/*
* Fences.
@ -1749,6 +1752,16 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev,
int r600_vram_scratch_init(struct radeon_device *rdev);
void r600_vram_scratch_fini(struct radeon_device *rdev);
/*
* r600 cs checking helper
*/
unsigned r600_mip_minify(unsigned size, unsigned level);
bool r600_fmt_is_valid_color(u32 format);
bool r600_fmt_is_valid_texture(u32 format, enum radeon_family family);
int r600_fmt_get_blocksize(u32 format);
int r600_fmt_get_nblocksx(u32 format, u32 w);
int r600_fmt_get_nblocksy(u32 format, u32 h);
/*
* r600 functions used by radeon_encoder.c
*/

View file

@ -208,22 +208,22 @@ void radeon_benchmark(struct radeon_device *rdev, int test_number)
break;
case 3:
/* GTT to VRAM, buffer size sweep, powers of 2 */
for (i = 1; i <= 65536; i <<= 1)
radeon_benchmark_move(rdev, i*1024,
for (i = 1; i <= 16384; i <<= 1)
radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE,
RADEON_GEM_DOMAIN_GTT,
RADEON_GEM_DOMAIN_VRAM);
break;
case 4:
/* VRAM to GTT, buffer size sweep, powers of 2 */
for (i = 1; i <= 65536; i <<= 1)
radeon_benchmark_move(rdev, i*1024,
for (i = 1; i <= 16384; i <<= 1)
radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE,
RADEON_GEM_DOMAIN_VRAM,
RADEON_GEM_DOMAIN_GTT);
break;
case 5:
/* VRAM to VRAM, buffer size sweep, powers of 2 */
for (i = 1; i <= 65536; i <<= 1)
radeon_benchmark_move(rdev, i*1024,
for (i = 1; i <= 16384; i <<= 1)
radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE,
RADEON_GEM_DOMAIN_VRAM,
RADEON_GEM_DOMAIN_VRAM);
break;

View file

@ -0,0 +1,44 @@
/*
* Copyright 2009 Advanced Micro Devices, Inc.
* Copyright 2009 Red Hat Inc.
* Copyright 2012 Alcatel-Lucent, Inc.
*
* 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, sublicense,
* 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 above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* 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 NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) 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.
*
*/
#ifndef __RADEON_BLIT_COMMON_H__
#define DI_PT_RECTLIST 0x11
#define DI_INDEX_SIZE_16_BIT 0x0
#define DI_SRC_SEL_AUTO_INDEX 0x2
#define FMT_8 0x1
#define FMT_5_6_5 0x8
#define FMT_8_8_8_8 0x1a
#define COLOR_8 0x1
#define COLOR_5_6_5 0x8
#define COLOR_8_8_8_8 0x1a
#define RECT_UNIT_H 32
#define RECT_UNIT_W (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H)
#define __RADEON_BLIT_COMMON_H__
#endif

View file

@ -2115,6 +2115,8 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
break;
}
pci_set_master(dev->pdev);
if (drm_pci_device_is_agp(dev))
dev_priv->flags |= RADEON_IS_AGP;
else if (pci_is_pcie(dev->pdev))

View file

@ -1124,11 +1124,6 @@ static const struct drm_mode_config_funcs radeon_mode_funcs = {
.output_poll_changed = radeon_output_poll_changed
};
struct drm_prop_enum_list {
int type;
char *name;
};
static struct drm_prop_enum_list radeon_tmds_pll_enum_list[] =
{ { 0, "driver" },
{ 1, "bios" },
@ -1153,86 +1148,53 @@ static struct drm_prop_enum_list radeon_underscan_enum_list[] =
static int radeon_modeset_create_props(struct radeon_device *rdev)
{
int i, sz;
int sz;
if (rdev->is_atom_bios) {
rdev->mode_info.coherent_mode_property =
drm_property_create(rdev->ddev,
DRM_MODE_PROP_RANGE,
"coherent", 2);
drm_property_create_range(rdev->ddev, 0 , "coherent", 0, 1);
if (!rdev->mode_info.coherent_mode_property)
return -ENOMEM;
rdev->mode_info.coherent_mode_property->values[0] = 0;
rdev->mode_info.coherent_mode_property->values[1] = 1;
}
if (!ASIC_IS_AVIVO(rdev)) {
sz = ARRAY_SIZE(radeon_tmds_pll_enum_list);
rdev->mode_info.tmds_pll_property =
drm_property_create(rdev->ddev,
DRM_MODE_PROP_ENUM,
"tmds_pll", sz);
for (i = 0; i < sz; i++) {
drm_property_add_enum(rdev->mode_info.tmds_pll_property,
i,
radeon_tmds_pll_enum_list[i].type,
radeon_tmds_pll_enum_list[i].name);
}
drm_property_create_enum(rdev->ddev, 0,
"tmds_pll",
radeon_tmds_pll_enum_list, sz);
}
rdev->mode_info.load_detect_property =
drm_property_create(rdev->ddev,
DRM_MODE_PROP_RANGE,
"load detection", 2);
drm_property_create_range(rdev->ddev, 0, "load detection", 0, 1);
if (!rdev->mode_info.load_detect_property)
return -ENOMEM;
rdev->mode_info.load_detect_property->values[0] = 0;
rdev->mode_info.load_detect_property->values[1] = 1;
drm_mode_create_scaling_mode_property(rdev->ddev);
sz = ARRAY_SIZE(radeon_tv_std_enum_list);
rdev->mode_info.tv_std_property =
drm_property_create(rdev->ddev,
DRM_MODE_PROP_ENUM,
"tv standard", sz);
for (i = 0; i < sz; i++) {
drm_property_add_enum(rdev->mode_info.tv_std_property,
i,
radeon_tv_std_enum_list[i].type,
radeon_tv_std_enum_list[i].name);
}
drm_property_create_enum(rdev->ddev, 0,
"tv standard",
radeon_tv_std_enum_list, sz);
sz = ARRAY_SIZE(radeon_underscan_enum_list);
rdev->mode_info.underscan_property =
drm_property_create(rdev->ddev,
DRM_MODE_PROP_ENUM,
"underscan", sz);
for (i = 0; i < sz; i++) {
drm_property_add_enum(rdev->mode_info.underscan_property,
i,
radeon_underscan_enum_list[i].type,
radeon_underscan_enum_list[i].name);
}
drm_property_create_enum(rdev->ddev, 0,
"underscan",
radeon_underscan_enum_list, sz);
rdev->mode_info.underscan_hborder_property =
drm_property_create(rdev->ddev,
DRM_MODE_PROP_RANGE,
"underscan hborder", 2);
drm_property_create_range(rdev->ddev, 0,
"underscan hborder", 0, 128);
if (!rdev->mode_info.underscan_hborder_property)
return -ENOMEM;
rdev->mode_info.underscan_hborder_property->values[0] = 0;
rdev->mode_info.underscan_hborder_property->values[1] = 128;
rdev->mode_info.underscan_vborder_property =
drm_property_create(rdev->ddev,
DRM_MODE_PROP_RANGE,
"underscan vborder", 2);
drm_property_create_range(rdev->ddev, 0,
"underscan vborder", 0, 128);
if (!rdev->mode_info.underscan_vborder_property)
return -ENOMEM;
rdev->mode_info.underscan_vborder_property->values[0] = 0;
rdev->mode_info.underscan_vborder_property->values[1] = 128;
return 0;
}
@ -1278,6 +1240,9 @@ int radeon_modeset_init(struct radeon_device *rdev)
rdev->ddev->mode_config.max_height = 4096;
}
rdev->ddev->mode_config.preferred_depth = 24;
rdev->ddev->mode_config.prefer_shadow = 1;
rdev->ddev->mode_config.fb_base = rdev->mc.aper_base;
ret = radeon_modeset_create_props(rdev);

View file

@ -54,10 +54,11 @@
* 2.10.0 - fusion 2D tiling
* 2.11.0 - backend map, initial compute support for the CS checker
* 2.12.0 - RADEON_CS_KEEP_TILING_FLAGS
* 2.13.0 - virtual memory support
* 2.13.0 - virtual memory support, streamout
* 2.14.0 - add evergreen tiling informations
*/
#define KMS_DRIVER_MAJOR 2
#define KMS_DRIVER_MINOR 13
#define KMS_DRIVER_MINOR 14
#define KMS_DRIVER_PATCHLEVEL 0
int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
int radeon_driver_unload_kms(struct drm_device *dev);

View file

@ -254,11 +254,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base;
info->apertures->ranges[0].size = rdev->mc.aper_size;
info->pixmap.size = 64*1024;
info->pixmap.buf_align = 8;
info->pixmap.access_align = 32;
info->pixmap.flags = FB_PIXMAP_SYSTEM;
info->pixmap.scan_align = 1;
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
if (info->screen_base == NULL) {
ret = -ENOSPC;

View file

@ -30,6 +30,10 @@
#include "radeon.h"
#include "atom.h"
extern int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg *msgs, int num);
extern u32 radeon_atom_hw_i2c_func(struct i2c_adapter *adap);
/**
* radeon_ddc_probe
*
@ -882,6 +886,11 @@ static const struct i2c_algorithm radeon_i2c_algo = {
.functionality = radeon_hw_i2c_func,
};
static const struct i2c_algorithm radeon_atom_i2c_algo = {
.master_xfer = radeon_atom_hw_i2c_xfer,
.functionality = radeon_atom_hw_i2c_func,
};
struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
struct radeon_i2c_bus_rec *rec,
const char *name)
@ -914,6 +923,18 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
DRM_ERROR("Failed to register hw i2c %s\n", name);
goto out_free;
}
} else if (rec->hw_capable &&
radeon_hw_i2c &&
ASIC_IS_DCE3(rdev)) {
/* hw i2c using atom */
snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
"Radeon i2c hw bus %s", name);
i2c->adapter.algo = &radeon_atom_i2c_algo;
ret = i2c_add_adapter(&i2c->adapter);
if (ret) {
DRM_ERROR("Failed to register hw i2c %s\n", name);
goto out_free;
}
} else {
/* set the radeon bit adapter */
snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
@ -925,10 +946,8 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
i2c->algo.bit.setscl = set_clock;
i2c->algo.bit.getsda = get_data;
i2c->algo.bit.getscl = get_clock;
i2c->algo.bit.udelay = 20;
/* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always
* make this, 2 jiffies is a lot more reliable */
i2c->algo.bit.timeout = 2;
i2c->algo.bit.udelay = 10;
i2c->algo.bit.timeout = usecs_to_jiffies(2200); /* from VESA */
i2c->algo.bit.data = i2c;
ret = i2c_bit_add_bus(&i2c->adapter);
if (ret) {

View file

@ -57,6 +57,8 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
}
dev->dev_private = (void *)rdev;
pci_set_master(dev->pdev);
/* update BUS flag */
if (drm_pci_device_is_agp(dev)) {
flags |= RADEON_IS_AGP;

View file

@ -445,8 +445,54 @@ static void radeon_bo_clear_surface_reg(struct radeon_bo *bo)
int radeon_bo_set_tiling_flags(struct radeon_bo *bo,
uint32_t tiling_flags, uint32_t pitch)
{
struct radeon_device *rdev = bo->rdev;
int r;
if (rdev->family >= CHIP_CEDAR) {
unsigned bankw, bankh, mtaspect, tilesplit, stilesplit;
bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK;
bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK;
mtaspect = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK;
tilesplit = (tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK;
stilesplit = (tiling_flags >> RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK;
switch (bankw) {
case 0:
case 1:
case 2:
case 4:
case 8:
break;
default:
return -EINVAL;
}
switch (bankh) {
case 0:
case 1:
case 2:
case 4:
case 8:
break;
default:
return -EINVAL;
}
switch (mtaspect) {
case 0:
case 1:
case 2:
case 4:
case 8:
break;
default:
return -EINVAL;
}
if (tilesplit > 6) {
return -EINVAL;
}
if (stilesplit > 6) {
return -EINVAL;
}
}
r = radeon_bo_reserve(bo, false);
if (unlikely(r != 0))
return r;

View file

@ -1,5 +1,8 @@
cayman 0x9400
0x0000802C GRBM_GFX_INDEX
0x000084FC CP_STRMOUT_CNTL
0x000085F0 CP_COHER_CNTL
0x000085F4 CP_COHER_SIZE
0x000088B0 VGT_VTX_VECT_EJECT_REG
0x000088C4 VGT_CACHE_INVALIDATION
0x000088D4 VGT_GS_VERTEX_REUSE
@ -77,7 +80,6 @@ cayman 0x9400
0x0002802C DB_DEPTH_CLEAR
0x00028030 PA_SC_SCREEN_SCISSOR_TL
0x00028034 PA_SC_SCREEN_SCISSOR_BR
0x0002805C DB_DEPTH_SLICE
0x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0
0x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1
0x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2
@ -512,6 +514,13 @@ cayman 0x9400
0x00028AC0 DB_SRESULTS_COMPARE_STATE0
0x00028AC4 DB_SRESULTS_COMPARE_STATE1
0x00028AC8 DB_PRELOAD_CONTROL
0x00028AD4 VGT_STRMOUT_VTX_STRIDE_0
0x00028AE4 VGT_STRMOUT_VTX_STRIDE_1
0x00028AF4 VGT_STRMOUT_VTX_STRIDE_2
0x00028B04 VGT_STRMOUT_VTX_STRIDE_3
0x00028B28 VGT_STRMOUT_DRAW_OPAQUE_OFFSET
0x00028B2C VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE
0x00028B30 VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE
0x00028B38 VGT_GS_MAX_VERT_OUT
0x00028B54 VGT_SHADER_STAGES_EN
0x00028B58 VGT_LS_HS_CONFIG

View file

@ -4,6 +4,9 @@ evergreen 0x9400
0x00008044 WAIT_UNTIL_POLL_CNTL
0x00008048 WAIT_UNTIL_POLL_MASK
0x0000804c WAIT_UNTIL_POLL_REFDATA
0x000084FC CP_STRMOUT_CNTL
0x000085F0 CP_COHER_CNTL
0x000085F4 CP_COHER_SIZE
0x000088B0 VGT_VTX_VECT_EJECT_REG
0x000088C4 VGT_CACHE_INVALIDATION
0x000088D4 VGT_GS_VERTEX_REUSE
@ -93,7 +96,6 @@ evergreen 0x9400
0x0002802C DB_DEPTH_CLEAR
0x00028030 PA_SC_SCREEN_SCISSOR_TL
0x00028034 PA_SC_SCREEN_SCISSOR_BR
0x0002805C DB_DEPTH_SLICE
0x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0
0x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1
0x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2
@ -522,6 +524,13 @@ evergreen 0x9400
0x00028AC0 DB_SRESULTS_COMPARE_STATE0
0x00028AC4 DB_SRESULTS_COMPARE_STATE1
0x00028AC8 DB_PRELOAD_CONTROL
0x00028AD4 VGT_STRMOUT_VTX_STRIDE_0
0x00028AE4 VGT_STRMOUT_VTX_STRIDE_1
0x00028AF4 VGT_STRMOUT_VTX_STRIDE_2
0x00028B04 VGT_STRMOUT_VTX_STRIDE_3
0x00028B28 VGT_STRMOUT_DRAW_OPAQUE_OFFSET
0x00028B2C VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE
0x00028B30 VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE
0x00028B38 VGT_GS_MAX_VERT_OUT
0x00028B54 VGT_SHADER_STAGES_EN
0x00028B58 VGT_LS_HS_CONFIG

View file

@ -3,6 +3,9 @@ r600 0x9400
0x00028230 R7xx_PA_SC_EDGERULE
0x000286C8 R7xx_SPI_THREAD_GROUPING
0x00008D8C R7xx_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ
0x00008490 CP_STRMOUT_CNTL
0x000085F0 CP_COHER_CNTL
0x000085F4 CP_COHER_SIZE
0x000088C4 VGT_CACHE_INVALIDATION
0x00028A50 VGT_ENHANCE
0x000088CC VGT_ES_PER_GS
@ -38,6 +41,13 @@ r600 0x9400
0x00028AB4 VGT_REUSE_OFF
0x00028AB8 VGT_VTX_CNT_EN
0x000088B0 VGT_VTX_VECT_EJECT_REG
0x00028AD4 VGT_STRMOUT_VTX_STRIDE_0
0x00028AE4 VGT_STRMOUT_VTX_STRIDE_1
0x00028AF4 VGT_STRMOUT_VTX_STRIDE_2
0x00028B04 VGT_STRMOUT_VTX_STRIDE_3
0x00028B28 VGT_STRMOUT_DRAW_OPAQUE_OFFSET
0x00028B2C VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE
0x00028B30 VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE
0x00028810 PA_CL_CLIP_CNTL
0x00008A14 PA_CL_ENHANCE
0x00028C14 PA_CL_GB_HORZ_CLIP_ADJ
@ -429,6 +439,7 @@ r600 0x9400
0x00028438 SX_ALPHA_REF
0x00028410 SX_ALPHA_TEST_CONTROL
0x00028350 SX_MISC
0x00028354 SX_SURFACE_SYNC
0x00009014 SX_MEMORY_EXPORT_SIZE
0x00009604 TC_INVALIDATE
0x00009400 TD_FILTER4
@ -743,14 +754,6 @@ r600 0x9400
0x00028114 CB_COLOR5_MASK
0x00028118 CB_COLOR6_MASK
0x0002811C CB_COLOR7_MASK
0x00028080 CB_COLOR0_VIEW
0x00028084 CB_COLOR1_VIEW
0x00028088 CB_COLOR2_VIEW
0x0002808C CB_COLOR3_VIEW
0x00028090 CB_COLOR4_VIEW
0x00028094 CB_COLOR5_VIEW
0x00028098 CB_COLOR6_VIEW
0x0002809C CB_COLOR7_VIEW
0x00028808 CB_COLOR_CONTROL
0x0002842C CB_FOG_BLUE
0x00028428 CB_FOG_GREEN

View file

@ -41,6 +41,8 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset)
{
drm_sis_private_t *dev_priv;
pci_set_master(dev->pdev);
dev_priv = kzalloc(sizeof(drm_sis_private_t), GFP_KERNEL);
if (dev_priv == NULL)
return -ENOMEM;

View file

@ -106,6 +106,8 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset)
idr_init(&dev->object_name_idr);
pci_set_master(dev->pdev);
ret = drm_vblank_init(dev, 1);
if (ret) {
kfree(dev_priv);

View file

@ -38,6 +38,10 @@
#define VMWGFX_CHIP_SVGAII 0
#define VMW_FB_RESERVATION 0
#define VMW_MIN_INITIAL_WIDTH 800
#define VMW_MIN_INITIAL_HEIGHT 600
/**
* Fully encoded drm commands. Might move to vmw_drm.h
*/
@ -387,6 +391,41 @@ void vmw_3d_resource_dec(struct vmw_private *dev_priv,
BUG_ON(n3d < 0);
}
/**
* Sets the initial_[width|height] fields on the given vmw_private.
*
* It does so by reading SVGA_REG_[WIDTH|HEIGHT] regs and then
* clamping the value to fb_max_[width|height] fields and the
* VMW_MIN_INITIAL_[WIDTH|HEIGHT].
* If the values appear to be invalid, set them to
* VMW_MIN_INITIAL_[WIDTH|HEIGHT].
*/
static void vmw_get_initial_size(struct vmw_private *dev_priv)
{
uint32_t width;
uint32_t height;
width = vmw_read(dev_priv, SVGA_REG_WIDTH);
height = vmw_read(dev_priv, SVGA_REG_HEIGHT);
width = max_t(uint32_t, width, VMW_MIN_INITIAL_WIDTH);
height = max_t(uint32_t, height, VMW_MIN_INITIAL_HEIGHT);
if (width > dev_priv->fb_max_width ||
height > dev_priv->fb_max_height) {
/*
* This is a host error and shouldn't occur.
*/
width = VMW_MIN_INITIAL_WIDTH;
height = VMW_MIN_INITIAL_HEIGHT;
}
dev_priv->initial_width = width;
dev_priv->initial_height = height;
}
static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
{
struct vmw_private *dev_priv;
@ -400,6 +439,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
}
memset(dev_priv, 0, sizeof(*dev_priv));
pci_set_master(dev->pdev);
dev_priv->dev = dev;
dev_priv->vmw_chipset = chipset;
dev_priv->last_read_seqno = (uint32_t) -100;
@ -441,6 +482,9 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
dev_priv->mmio_size = vmw_read(dev_priv, SVGA_REG_MEM_SIZE);
dev_priv->fb_max_width = vmw_read(dev_priv, SVGA_REG_MAX_WIDTH);
dev_priv->fb_max_height = vmw_read(dev_priv, SVGA_REG_MAX_HEIGHT);
vmw_get_initial_size(dev_priv);
if (dev_priv->capabilities & SVGA_CAP_GMR) {
dev_priv->max_gmr_descriptors =
vmw_read(dev_priv,
@ -688,6 +732,15 @@ static int vmw_driver_unload(struct drm_device *dev)
return 0;
}
static void vmw_preclose(struct drm_device *dev,
struct drm_file *file_priv)
{
struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
struct vmw_private *dev_priv = vmw_priv(dev);
vmw_event_fence_fpriv_gone(dev_priv->fman, &vmw_fp->fence_events);
}
static void vmw_postclose(struct drm_device *dev,
struct drm_file *file_priv)
{
@ -710,6 +763,7 @@ static int vmw_driver_open(struct drm_device *dev, struct drm_file *file_priv)
if (unlikely(vmw_fp == NULL))
return ret;
INIT_LIST_HEAD(&vmw_fp->fence_events);
vmw_fp->tfile = ttm_object_file_init(dev_priv->tdev, 10);
if (unlikely(vmw_fp->tfile == NULL))
goto out_no_tfile;
@ -1102,6 +1156,7 @@ static struct drm_driver driver = {
.master_set = vmw_master_set,
.master_drop = vmw_master_drop,
.open = vmw_driver_open,
.preclose = vmw_preclose,
.postclose = vmw_postclose,
.fops = &vmwgfx_driver_fops,
.name = VMWGFX_DRIVER_NAME,

View file

@ -40,9 +40,9 @@
#include "ttm/ttm_module.h"
#include "vmwgfx_fence.h"
#define VMWGFX_DRIVER_DATE "20111025"
#define VMWGFX_DRIVER_DATE "20120209"
#define VMWGFX_DRIVER_MAJOR 2
#define VMWGFX_DRIVER_MINOR 3
#define VMWGFX_DRIVER_MINOR 4
#define VMWGFX_DRIVER_PATCHLEVEL 0
#define VMWGFX_FILE_PAGE_OFFSET 0x00100000
#define VMWGFX_FIFO_STATIC_SIZE (1024*1024)
@ -62,6 +62,7 @@
struct vmw_fpriv {
struct drm_master *locked_master;
struct ttm_object_file *tfile;
struct list_head fence_events;
};
struct vmw_dma_buffer {
@ -202,6 +203,8 @@ struct vmw_private {
uint32_t mmio_size;
uint32_t fb_max_width;
uint32_t fb_max_height;
uint32_t initial_width;
uint32_t initial_height;
__le32 __iomem *mmio_virt;
int mmio_mtrr;
uint32_t capabilities;
@ -533,7 +536,8 @@ extern int vmw_execbuf_process(struct drm_file *file_priv,
uint32_t command_size,
uint64_t throttle_us,
struct drm_vmw_fence_rep __user
*user_fence_rep);
*user_fence_rep,
struct vmw_fence_obj **out_fence);
extern void
vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv,

View file

@ -1109,10 +1109,11 @@ int vmw_execbuf_process(struct drm_file *file_priv,
void *kernel_commands,
uint32_t command_size,
uint64_t throttle_us,
struct drm_vmw_fence_rep __user *user_fence_rep)
struct drm_vmw_fence_rep __user *user_fence_rep,
struct vmw_fence_obj **out_fence)
{
struct vmw_sw_context *sw_context = &dev_priv->ctx;
struct vmw_fence_obj *fence;
struct vmw_fence_obj *fence = NULL;
uint32_t handle;
void *cmd;
int ret;
@ -1208,8 +1209,13 @@ int vmw_execbuf_process(struct drm_file *file_priv,
vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret,
user_fence_rep, fence, handle);
if (likely(fence != NULL))
/* Don't unreference when handing fence out */
if (unlikely(out_fence != NULL)) {
*out_fence = fence;
fence = NULL;
} else if (likely(fence != NULL)) {
vmw_fence_obj_unreference(&fence);
}
mutex_unlock(&dev_priv->cmdbuf_mutex);
return 0;
@ -1362,7 +1368,8 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data,
ret = vmw_execbuf_process(file_priv, dev_priv,
(void __user *)(unsigned long)arg->commands,
NULL, arg->command_size, arg->throttle_us,
(void __user *)(unsigned long)arg->fence_rep);
(void __user *)(unsigned long)arg->fence_rep,
NULL);
if (unlikely(ret != 0))
goto out_unlock;

View file

@ -414,10 +414,6 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
unsigned fb_bpp, fb_depth, fb_offset, fb_pitch, fb_size;
int ret;
/* XXX These shouldn't be hardcoded. */
initial_width = 800;
initial_height = 600;
fb_bpp = 32;
fb_depth = 24;
@ -425,8 +421,8 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
fb_width = min(vmw_priv->fb_max_width, (unsigned)2048);
fb_height = min(vmw_priv->fb_max_height, (unsigned)2048);
initial_width = min(fb_width, initial_width);
initial_height = min(fb_height, initial_height);
initial_width = min(vmw_priv->initial_width, fb_width);
initial_height = min(vmw_priv->initial_height, fb_height);
fb_pitch = fb_width * fb_bpp / 8;
fb_size = fb_pitch * fb_height;
@ -515,19 +511,7 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
info->var.xres = initial_width;
info->var.yres = initial_height;
#if 0
info->pixmap.size = 64*1024;
info->pixmap.buf_align = 8;
info->pixmap.access_align = 32;
info->pixmap.flags = FB_PIXMAP_SYSTEM;
info->pixmap.scan_align = 1;
#else
info->pixmap.size = 0;
info->pixmap.buf_align = 8;
info->pixmap.access_align = 32;
info->pixmap.flags = FB_PIXMAP_SYSTEM;
info->pixmap.scan_align = 1;
#endif
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
info->apertures = alloc_apertures(1);
if (!info->apertures) {

View file

@ -69,12 +69,13 @@ struct vmw_user_fence {
* be assigned the current time tv_usec val when the fence signals.
*/
struct vmw_event_fence_action {
struct drm_pending_event e;
struct vmw_fence_action action;
struct list_head fpriv_head;
struct drm_pending_event *event;
struct vmw_fence_obj *fence;
struct drm_device *dev;
struct kref kref;
uint32_t size;
uint32_t *tv_sec;
uint32_t *tv_usec;
};
@ -784,46 +785,40 @@ int vmw_fence_obj_unref_ioctl(struct drm_device *dev, void *data,
}
/**
* vmw_event_fence_action_destroy
* vmw_event_fence_fpriv_gone - Remove references to struct drm_file objects
*
* @kref: The struct kref embedded in a struct vmw_event_fence_action.
* @fman: Pointer to a struct vmw_fence_manager
* @event_list: Pointer to linked list of struct vmw_event_fence_action objects
* with pointers to a struct drm_file object about to be closed.
*
* The vmw_event_fence_action destructor that may be called either after
* the fence action cleanup, or when the event is delivered.
* It frees both the vmw_event_fence_action struct and the actual
* event structure copied to user-space.
* This function removes all pending fence events with references to a
* specific struct drm_file object about to be closed. The caller is required
* to pass a list of all struct vmw_event_fence_action objects with such
* events attached. This function is typically called before the
* struct drm_file object's event management is taken down.
*/
static void vmw_event_fence_action_destroy(struct kref *kref)
void vmw_event_fence_fpriv_gone(struct vmw_fence_manager *fman,
struct list_head *event_list)
{
struct vmw_event_fence_action *eaction =
container_of(kref, struct vmw_event_fence_action, kref);
struct ttm_mem_global *mem_glob =
vmw_mem_glob(vmw_priv(eaction->dev));
uint32_t size = eaction->size;
struct vmw_event_fence_action *eaction;
struct drm_pending_event *event;
unsigned long irq_flags;
kfree(eaction->e.event);
kfree(eaction);
ttm_mem_global_free(mem_glob, size);
}
/**
* vmw_event_fence_action_delivered
*
* @e: The struct drm_pending_event embedded in a struct
* vmw_event_fence_action.
*
* The struct drm_pending_event destructor that is called by drm
* once the event is delivered. Since we don't know whether this function
* will be called before or after the fence action destructor, we
* free a refcount and destroy if it becomes zero.
*/
static void vmw_event_fence_action_delivered(struct drm_pending_event *e)
{
struct vmw_event_fence_action *eaction =
container_of(e, struct vmw_event_fence_action, e);
kref_put(&eaction->kref, vmw_event_fence_action_destroy);
while (1) {
spin_lock_irqsave(&fman->lock, irq_flags);
if (list_empty(event_list))
goto out_unlock;
eaction = list_first_entry(event_list,
struct vmw_event_fence_action,
fpriv_head);
list_del_init(&eaction->fpriv_head);
event = eaction->event;
eaction->event = NULL;
spin_unlock_irqrestore(&fman->lock, irq_flags);
event->destroy(event);
}
out_unlock:
spin_unlock_irqrestore(&fman->lock, irq_flags);
}
@ -836,18 +831,21 @@ static void vmw_event_fence_action_delivered(struct drm_pending_event *e)
* This function is called when the seqno of the fence where @action is
* attached has passed. It queues the event on the submitter's event list.
* This function is always called from atomic context, and may be called
* from irq context. It ups a refcount reflecting that we now have two
* destructors.
* from irq context.
*/
static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action)
{
struct vmw_event_fence_action *eaction =
container_of(action, struct vmw_event_fence_action, action);
struct drm_device *dev = eaction->dev;
struct drm_file *file_priv = eaction->e.file_priv;
struct drm_pending_event *event = eaction->event;
struct drm_file *file_priv;
unsigned long irq_flags;
kref_get(&eaction->kref);
if (unlikely(event == NULL))
return;
file_priv = event->file_priv;
spin_lock_irqsave(&dev->event_lock, irq_flags);
if (likely(eaction->tv_sec != NULL)) {
@ -858,7 +856,9 @@ static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action)
*eaction->tv_usec = tv.tv_usec;
}
list_add_tail(&eaction->e.link, &file_priv->event_list);
list_del_init(&eaction->fpriv_head);
list_add_tail(&eaction->event->link, &file_priv->event_list);
eaction->event = NULL;
wake_up_all(&file_priv->event_wait);
spin_unlock_irqrestore(&dev->event_lock, irq_flags);
}
@ -876,9 +876,15 @@ static void vmw_event_fence_action_cleanup(struct vmw_fence_action *action)
{
struct vmw_event_fence_action *eaction =
container_of(action, struct vmw_event_fence_action, action);
struct vmw_fence_manager *fman = eaction->fence->fman;
unsigned long irq_flags;
spin_lock_irqsave(&fman->lock, irq_flags);
list_del(&eaction->fpriv_head);
spin_unlock_irqrestore(&fman->lock, irq_flags);
vmw_fence_obj_unreference(&eaction->fence);
kref_put(&eaction->kref, vmw_event_fence_action_destroy);
kfree(eaction);
}
@ -946,39 +952,23 @@ void vmw_fence_obj_add_action(struct vmw_fence_obj *fence,
* an error code, the caller needs to free that object.
*/
int vmw_event_fence_action_create(struct drm_file *file_priv,
struct vmw_fence_obj *fence,
struct drm_event *event,
uint32_t *tv_sec,
uint32_t *tv_usec,
bool interruptible)
int vmw_event_fence_action_queue(struct drm_file *file_priv,
struct vmw_fence_obj *fence,
struct drm_pending_event *event,
uint32_t *tv_sec,
uint32_t *tv_usec,
bool interruptible)
{
struct vmw_event_fence_action *eaction;
struct ttm_mem_global *mem_glob =
vmw_mem_glob(fence->fman->dev_priv);
struct vmw_fence_manager *fman = fence->fman;
uint32_t size = fman->event_fence_action_size +
ttm_round_pot(event->length);
int ret;
/*
* Account for internal structure size as well as the
* event size itself.
*/
ret = ttm_mem_global_alloc(mem_glob, size, false, interruptible);
if (unlikely(ret != 0))
return ret;
struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv);
unsigned long irq_flags;
eaction = kzalloc(sizeof(*eaction), GFP_KERNEL);
if (unlikely(eaction == NULL)) {
ttm_mem_global_free(mem_glob, size);
if (unlikely(eaction == NULL))
return -ENOMEM;
}
eaction->e.event = event;
eaction->e.file_priv = file_priv;
eaction->e.destroy = vmw_event_fence_action_delivered;
eaction->event = event;
eaction->action.seq_passed = vmw_event_fence_action_seq_passed;
eaction->action.cleanup = vmw_event_fence_action_cleanup;
@ -986,16 +976,89 @@ int vmw_event_fence_action_create(struct drm_file *file_priv,
eaction->fence = vmw_fence_obj_reference(fence);
eaction->dev = fman->dev_priv->dev;
eaction->size = size;
eaction->tv_sec = tv_sec;
eaction->tv_usec = tv_usec;
kref_init(&eaction->kref);
spin_lock_irqsave(&fman->lock, irq_flags);
list_add_tail(&eaction->fpriv_head, &vmw_fp->fence_events);
spin_unlock_irqrestore(&fman->lock, irq_flags);
vmw_fence_obj_add_action(fence, &eaction->action);
return 0;
}
struct vmw_event_fence_pending {
struct drm_pending_event base;
struct drm_vmw_event_fence event;
};
int vmw_event_fence_action_create(struct drm_file *file_priv,
struct vmw_fence_obj *fence,
uint32_t flags,
uint64_t user_data,
bool interruptible)
{
struct vmw_event_fence_pending *event;
struct drm_device *dev = fence->fman->dev_priv->dev;
unsigned long irq_flags;
int ret;
spin_lock_irqsave(&dev->event_lock, irq_flags);
ret = (file_priv->event_space < sizeof(event->event)) ? -EBUSY : 0;
if (likely(ret == 0))
file_priv->event_space -= sizeof(event->event);
spin_unlock_irqrestore(&dev->event_lock, irq_flags);
if (unlikely(ret != 0)) {
DRM_ERROR("Failed to allocate event space for this file.\n");
goto out_no_space;
}
event = kzalloc(sizeof(event->event), GFP_KERNEL);
if (unlikely(event == NULL)) {
DRM_ERROR("Failed to allocate an event.\n");
ret = -ENOMEM;
goto out_no_event;
}
event->event.base.type = DRM_VMW_EVENT_FENCE_SIGNALED;
event->event.base.length = sizeof(*event);
event->event.user_data = user_data;
event->base.event = &event->event.base;
event->base.file_priv = file_priv;
event->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
if (flags & DRM_VMW_FE_FLAG_REQ_TIME)
ret = vmw_event_fence_action_queue(file_priv, fence,
&event->base,
&event->event.tv_sec,
&event->event.tv_usec,
interruptible);
else
ret = vmw_event_fence_action_queue(file_priv, fence,
&event->base,
NULL,
NULL,
interruptible);
if (ret != 0)
goto out_no_queue;
out_no_queue:
event->base.destroy(&event->base);
out_no_event:
spin_lock_irqsave(&dev->event_lock, irq_flags);
file_priv->event_space += sizeof(*event);
spin_unlock_irqrestore(&dev->event_lock, irq_flags);
out_no_space:
return ret;
}
int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
@ -1008,8 +1071,6 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
(struct drm_vmw_fence_rep __user *)(unsigned long)
arg->fence_rep;
uint32_t handle;
unsigned long irq_flags;
struct drm_vmw_event_fence *event;
int ret;
/*
@ -1062,59 +1123,28 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
BUG_ON(fence == NULL);
spin_lock_irqsave(&dev->event_lock, irq_flags);
ret = (file_priv->event_space < sizeof(*event)) ? -EBUSY : 0;
if (likely(ret == 0))
file_priv->event_space -= sizeof(*event);
spin_unlock_irqrestore(&dev->event_lock, irq_flags);
if (unlikely(ret != 0)) {
DRM_ERROR("Failed to allocate event space for this file.\n");
goto out_no_event_space;
}
event = kzalloc(sizeof(*event), GFP_KERNEL);
if (unlikely(event == NULL)) {
DRM_ERROR("Failed to allocate an event.\n");
goto out_no_event;
}
event->base.type = DRM_VMW_EVENT_FENCE_SIGNALED;
event->base.length = sizeof(*event);
event->user_data = arg->user_data;
if (arg->flags & DRM_VMW_FE_FLAG_REQ_TIME)
ret = vmw_event_fence_action_create(file_priv, fence,
&event->base,
&event->tv_sec,
&event->tv_usec,
arg->flags,
arg->user_data,
true);
else
ret = vmw_event_fence_action_create(file_priv, fence,
&event->base,
NULL,
NULL,
arg->flags,
arg->user_data,
true);
if (unlikely(ret != 0)) {
if (ret != -ERESTARTSYS)
DRM_ERROR("Failed to attach event to fence.\n");
goto out_no_attach;
goto out_no_create;
}
vmw_execbuf_copy_fence_user(dev_priv, vmw_fp, 0, user_fence_rep, fence,
handle);
vmw_fence_obj_unreference(&fence);
return 0;
out_no_attach:
kfree(event);
out_no_event:
spin_lock_irqsave(&dev->event_lock, irq_flags);
file_priv->event_space += sizeof(*event);
spin_unlock_irqrestore(&dev->event_lock, irq_flags);
out_no_event_space:
out_no_create:
if (user_fence_rep != NULL)
ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile,
handle, TTM_REF_USAGE);

View file

@ -109,5 +109,12 @@ extern int vmw_fence_obj_unref_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern void vmw_event_fence_fpriv_gone(struct vmw_fence_manager *fman,
struct list_head *event_list);
extern int vmw_event_fence_action_queue(struct drm_file *filee_priv,
struct vmw_fence_obj *fence,
struct drm_pending_event *event,
uint32_t *tv_sec,
uint32_t *tv_usec,
bool interruptible);
#endif /* _VMWGFX_FENCE_H_ */

View file

@ -422,7 +422,8 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv,
struct vmw_framebuffer *framebuffer,
unsigned flags, unsigned color,
struct drm_clip_rect *clips,
unsigned num_clips, int inc)
unsigned num_clips, int inc,
struct vmw_fence_obj **out_fence)
{
struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
struct drm_clip_rect *clips_ptr;
@ -542,12 +543,15 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv,
if (num == 0)
continue;
/* only return the last fence */
if (out_fence && *out_fence)
vmw_fence_obj_unreference(out_fence);
/* recalculate package length */
fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num;
cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header));
ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd,
fifo_size, 0, NULL);
fifo_size, 0, NULL, out_fence);
if (unlikely(ret != 0))
break;
@ -598,7 +602,7 @@ int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer,
ret = do_surface_dirty_sou(dev_priv, file_priv, &vfbs->base,
flags, color,
clips, num_clips, inc);
clips, num_clips, inc, NULL);
ttm_read_unlock(&vmaster->lock);
return 0;
@ -809,7 +813,7 @@ static int do_dmabuf_define_gmrfb(struct drm_file *file_priv,
cmd->body.ptr.offset = 0;
ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd,
fifo_size, 0, NULL);
fifo_size, 0, NULL, NULL);
kfree(cmd);
@ -821,7 +825,8 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv,
struct vmw_framebuffer *framebuffer,
unsigned flags, unsigned color,
struct drm_clip_rect *clips,
unsigned num_clips, int increment)
unsigned num_clips, int increment,
struct vmw_fence_obj **out_fence)
{
struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS];
struct drm_clip_rect *clips_ptr;
@ -894,9 +899,13 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv,
if (hit_num == 0)
continue;
/* only return the last fence */
if (out_fence && *out_fence)
vmw_fence_obj_unreference(out_fence);
fifo_size = sizeof(*blits) * hit_num;
ret = vmw_execbuf_process(file_priv, dev_priv, NULL, blits,
fifo_size, 0, NULL);
fifo_size, 0, NULL, out_fence);
if (unlikely(ret != 0))
break;
@ -942,7 +951,7 @@ int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer,
} else {
ret = do_dmabuf_dirty_sou(file_priv, dev_priv, &vfbd->base,
flags, color,
clips, num_clips, increment);
clips, num_clips, increment, NULL);
}
ttm_read_unlock(&vmaster->lock);
@ -1296,7 +1305,7 @@ int vmw_kms_present(struct vmw_private *dev_priv,
fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num;
cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header));
ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd,
fifo_size, 0, NULL);
fifo_size, 0, NULL, NULL);
if (unlikely(ret != 0))
break;
@ -1409,7 +1418,7 @@ int vmw_kms_readback(struct vmw_private *dev_priv,
fifo_size = sizeof(*cmd) + sizeof(*blits) * blits_pos;
ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, fifo_size,
0, user_fence_rep);
0, user_fence_rep, NULL);
kfree(cmd);
@ -1672,6 +1681,70 @@ int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num,
return 0;
}
int vmw_du_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event)
{
struct vmw_private *dev_priv = vmw_priv(crtc->dev);
struct drm_framebuffer *old_fb = crtc->fb;
struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb);
struct drm_file *file_priv = event->base.file_priv;
struct vmw_fence_obj *fence = NULL;
struct drm_clip_rect clips;
int ret;
/* require ScreenObject support for page flipping */
if (!dev_priv->sou_priv)
return -ENOSYS;
if (!vmw_kms_screen_object_flippable(dev_priv, crtc))
return -EINVAL;
crtc->fb = fb;
/* do a full screen dirty update */
clips.x1 = clips.y1 = 0;
clips.x2 = fb->width;
clips.y2 = fb->height;
if (vfb->dmabuf)
ret = do_dmabuf_dirty_sou(file_priv, dev_priv, vfb,
0, 0, &clips, 1, 1, &fence);
else
ret = do_surface_dirty_sou(dev_priv, file_priv, vfb,
0, 0, &clips, 1, 1, &fence);
if (ret != 0)
goto out_no_fence;
if (!fence) {
ret = -EINVAL;
goto out_no_fence;
}
ret = vmw_event_fence_action_queue(file_priv, fence,
&event->base,
&event->event.tv_sec,
&event->event.tv_usec,
true);
/*
* No need to hold on to this now. The only cleanup
* we need to do if we fail is unref the fence.
*/
vmw_fence_obj_unreference(&fence);
if (vmw_crtc_to_du(crtc)->is_implicit)
vmw_kms_screen_object_update_implicit_fb(dev_priv, crtc);
return ret;
out_no_fence:
crtc->fb = old_fb;
return ret;
}
void vmw_du_crtc_save(struct drm_crtc *crtc)
{
}

View file

@ -121,6 +121,9 @@ struct vmw_display_unit {
* Shared display unit functions - vmwgfx_kms.c
*/
void vmw_display_unit_cleanup(struct vmw_display_unit *du);
int vmw_du_page_flip(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event);
void vmw_du_crtc_save(struct drm_crtc *crtc);
void vmw_du_crtc_restore(struct drm_crtc *crtc);
void vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
@ -154,5 +157,10 @@ int vmw_kms_init_screen_object_display(struct vmw_private *dev_priv);
int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv);
int vmw_kms_sou_update_layout(struct vmw_private *dev_priv, unsigned num,
struct drm_vmw_rect *rects);
bool vmw_kms_screen_object_flippable(struct vmw_private *dev_priv,
struct drm_crtc *crtc);
void vmw_kms_screen_object_update_implicit_fb(struct vmw_private *dev_priv,
struct drm_crtc *crtc);
#endif

View file

@ -354,8 +354,8 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit)
INIT_LIST_HEAD(&ldu->active);
ldu->base.pref_active = (unit == 0);
ldu->base.pref_width = 800;
ldu->base.pref_height = 600;
ldu->base.pref_width = dev_priv->initial_width;
ldu->base.pref_height = dev_priv->initial_height;
ldu->base.pref_mode = NULL;
ldu->base.is_implicit = true;

View file

@ -394,6 +394,7 @@ static struct drm_crtc_funcs vmw_screen_object_crtc_funcs = {
.gamma_set = vmw_du_crtc_gamma_set,
.destroy = vmw_sou_crtc_destroy,
.set_config = vmw_sou_crtc_set_config,
.page_flip = vmw_du_page_flip,
};
/*
@ -448,8 +449,8 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit)
sou->active_implicit = false;
sou->base.pref_active = (unit == 0);
sou->base.pref_width = 800;
sou->base.pref_height = 600;
sou->base.pref_width = dev_priv->initial_width;
sou->base.pref_height = dev_priv->initial_height;
sou->base.pref_mode = NULL;
sou->base.is_implicit = true;
@ -535,3 +536,36 @@ int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv)
return 0;
}
/**
* Returns if this unit can be page flipped.
* Must be called with the mode_config mutex held.
*/
bool vmw_kms_screen_object_flippable(struct vmw_private *dev_priv,
struct drm_crtc *crtc)
{
struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc);
if (!sou->base.is_implicit)
return true;
if (dev_priv->sou_priv->num_implicit != 1)
return false;
return true;
}
/**
* Update the implicit fb to the current fb of this crtc.
* Must be called with the mode_config mutex held.
*/
void vmw_kms_screen_object_update_implicit_fb(struct vmw_private *dev_priv,
struct drm_crtc *crtc)
{
struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc);
BUG_ON(!sou->base.is_implicit);
dev_priv->sou_priv->implicit_fb =
vmw_framebuffer_to_vfb(sou->base.crtc.fb);
}

View file

@ -761,6 +761,8 @@ struct drm_event_vblank {
#define DRM_CAP_DUMB_BUFFER 0x1
#define DRM_CAP_VBLANK_HIGH_CRTC 0x2
#define DRM_CAP_DUMB_PREFERRED_DEPTH 0x3
#define DRM_CAP_DUMB_PREFER_SHADOW 0x4
/* typedef area */
#ifndef __KERNEL__

View file

@ -796,6 +796,9 @@ struct drm_mode_config {
struct drm_property *scaling_mode_property;
struct drm_property *dithering_mode_property;
struct drm_property *dirty_info_property;
/* dumb ioctl parameters */
uint32_t preferred_depth, prefer_shadow;
};
#define obj_to_crtc(x) container_of(x, struct drm_crtc, base)
@ -807,6 +810,10 @@ struct drm_mode_config {
#define obj_to_blob(x) container_of(x, struct drm_property_blob, base)
#define obj_to_plane(x) container_of(x, struct drm_plane, base)
struct drm_prop_enum_list {
int type;
char *name;
};
extern void drm_crtc_init(struct drm_device *dev,
struct drm_crtc *crtc,
@ -904,6 +911,13 @@ extern int drm_connector_attach_property(struct drm_connector *connector,
struct drm_property *property, uint64_t init_val);
extern struct drm_property *drm_property_create(struct drm_device *dev, int flags,
const char *name, int num_values);
extern struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags,
const char *name,
const struct drm_prop_enum_list *props,
int num_values);
struct drm_property *drm_property_create_range(struct drm_device *dev, int flags,
const char *name,
uint64_t min, uint64_t max);
extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property);
extern int drm_property_add_enum(struct drm_property *property, int index,
uint64_t value, const char *name);
@ -919,7 +933,7 @@ extern int drm_mode_connector_attach_encoder(struct drm_connector *connector,
struct drm_encoder *encoder);
extern void drm_mode_connector_detach_encoder(struct drm_connector *connector,
struct drm_encoder *encoder);
extern bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
extern int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
int gamma_size);
extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev,
uint32_t id, uint32_t type);

View file

@ -35,7 +35,6 @@ struct drm_fb_helper;
#include <linux/kgdb.h>
struct drm_fb_helper_crtc {
uint32_t crtc_id;
struct drm_mode_set mode_set;
struct drm_display_mode *desired_mode;
};
@ -74,7 +73,6 @@ struct drm_fb_helper {
int connector_count;
struct drm_fb_helper_connector **connector_info;
struct drm_fb_helper_funcs *funcs;
int conn_limit;
struct fb_info *fbdev;
u32 pseudo_palette[17];
struct list_head kernel_fb_list;

View file

@ -804,13 +804,23 @@ struct drm_radeon_gem_create {
uint32_t flags;
};
#define RADEON_TILING_MACRO 0x1
#define RADEON_TILING_MICRO 0x2
#define RADEON_TILING_SWAP_16BIT 0x4
#define RADEON_TILING_SWAP_32BIT 0x8
#define RADEON_TILING_SURFACE 0x10 /* this object requires a surface
* when mapped - i.e. front buffer */
#define RADEON_TILING_MICRO_SQUARE 0x20
#define RADEON_TILING_MACRO 0x1
#define RADEON_TILING_MICRO 0x2
#define RADEON_TILING_SWAP_16BIT 0x4
#define RADEON_TILING_SWAP_32BIT 0x8
/* this object requires a surface when mapped - i.e. front buffer */
#define RADEON_TILING_SURFACE 0x10
#define RADEON_TILING_MICRO_SQUARE 0x20
#define RADEON_TILING_EG_BANKW_SHIFT 8
#define RADEON_TILING_EG_BANKW_MASK 0xf
#define RADEON_TILING_EG_BANKH_SHIFT 12
#define RADEON_TILING_EG_BANKH_MASK 0xf
#define RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT 16
#define RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK 0xf
#define RADEON_TILING_EG_TILE_SPLIT_SHIFT 24
#define RADEON_TILING_EG_TILE_SPLIT_MASK 0xf
#define RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT 28
#define RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK 0xf
struct drm_radeon_gem_set_tiling {
uint32_t handle;