mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 16:54:20 +08:00
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:
commit
ff5f4b0585
@ -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 @@ out:
|
||||
* @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 @@ out:
|
||||
* @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 @@ out:
|
||||
* @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 @@ out:
|
||||
* @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 @@ out:
|
||||
* @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 @@ out:
|
||||
* @arg: arg from ioctl
|
||||
*
|
||||
* LOCKING:
|
||||
* Caller? (FIXME)
|
||||
* Takes mode config lock.
|
||||
*
|
||||
* Build a new CRTC configuration based on user request.
|
||||
*
|
||||
@ -2275,7 +2221,7 @@ out:
|
||||
* @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 @@ fail:
|
||||
}
|
||||
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);
|
||||
|
||||
|
@ -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 @@ prune:
|
||||
|
||||
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);
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
139
drivers/gpu/drm/radeon/atombios_i2c.c
Normal file
139
drivers/gpu/drm/radeon/atombios_i2c.c
Normal 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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
|
44
drivers/gpu/drm/radeon/radeon_blit_common.h
Normal file
44
drivers/gpu/drm/radeon/radeon_blit_common.h
Normal 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
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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_ */
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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__
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user