mirror of https://gitee.com/openkylin/linux.git
Merge branch 'drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (25 commits) drm/radeon/kms: Convert R520 to new init path and associated cleanup drm/radeon/kms: Convert RV515 to new init path and associated cleanup drm: fix radeon DRM warnings when !CONFIG_DEBUG_FS drm: fix drm_fb_helper warning when !CONFIG_MAGIC_SYSRQ drm/r600: fix memory leak introduced with 64k malloc avoidance fix. drm/kms: make fb helper work for all drivers. drm/radeon/r600: fix offset handling in CS parser drm/radeon/kms/r600: fix forcing pci mode on agp cards drm/radeon/kms: fix for the extra pages copying. drm/radeon/kms/r600: add support for vline relocs drm/radeon/kms: fix some bugs in vline reloc drm/radeon/kms/r600: clamp vram to aperture size drm/kms: protect against fb helper not being created. drm/r600: get values from the passed in IB not the copy. drm: create gitignore file for radeon drm/radeon/kms: remove unneeded master create/destroy functions. drm/kms: start adding command line interface using fb. fb: change rules for global rules match. drm/radeon/kms: don't require up to 64k allocations. (v2) drm/radeon/kms: enable dac load detection by default. ... Trivial conflicts in drivers/gpu/drm/radeon/radeon_asic.h due to adding '->vga_set_state' function pointers.
This commit is contained in:
commit
e15daf6cdf
|
@ -482,6 +482,7 @@ void drm_connector_cleanup(struct drm_connector *connector)
|
|||
list_for_each_entry_safe(mode, t, &connector->user_modes, head)
|
||||
drm_mode_remove(connector, mode);
|
||||
|
||||
kfree(connector->fb_helper_private);
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
drm_mode_object_put(dev, &connector->base);
|
||||
list_del(&connector->head);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "drmP.h"
|
||||
#include "drm_crtc.h"
|
||||
#include "drm_crtc_helper.h"
|
||||
#include "drm_fb_helper.h"
|
||||
|
||||
static void drm_mode_validate_flag(struct drm_connector *connector,
|
||||
int flags)
|
||||
|
@ -90,7 +91,15 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
|
|||
list_for_each_entry_safe(mode, t, &connector->modes, head)
|
||||
mode->status = MODE_UNVERIFIED;
|
||||
|
||||
connector->status = connector->funcs->detect(connector);
|
||||
if (connector->force) {
|
||||
if (connector->force == DRM_FORCE_ON)
|
||||
connector->status = connector_status_connected;
|
||||
else
|
||||
connector->status = connector_status_disconnected;
|
||||
if (connector->funcs->force)
|
||||
connector->funcs->force(connector);
|
||||
} else
|
||||
connector->status = connector->funcs->detect(connector);
|
||||
|
||||
if (connector->status == connector_status_disconnected) {
|
||||
DRM_DEBUG_KMS("%s is disconnected\n",
|
||||
|
@ -267,6 +276,65 @@ static struct drm_display_mode *drm_has_preferred_mode(struct drm_connector *con
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static bool drm_has_cmdline_mode(struct drm_connector *connector)
|
||||
{
|
||||
struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private;
|
||||
struct drm_fb_helper_cmdline_mode *cmdline_mode;
|
||||
|
||||
if (!fb_help_conn)
|
||||
return false;
|
||||
|
||||
cmdline_mode = &fb_help_conn->cmdline_mode;
|
||||
return cmdline_mode->specified;
|
||||
}
|
||||
|
||||
static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_connector *connector, int width, int height)
|
||||
{
|
||||
struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private;
|
||||
struct drm_fb_helper_cmdline_mode *cmdline_mode;
|
||||
struct drm_display_mode *mode = NULL;
|
||||
|
||||
if (!fb_help_conn)
|
||||
return mode;
|
||||
|
||||
cmdline_mode = &fb_help_conn->cmdline_mode;
|
||||
if (cmdline_mode->specified == false)
|
||||
return mode;
|
||||
|
||||
/* attempt to find a matching mode in the list of modes
|
||||
* we have gotten so far, if not add a CVT mode that conforms
|
||||
*/
|
||||
if (cmdline_mode->rb || cmdline_mode->margins)
|
||||
goto create_mode;
|
||||
|
||||
list_for_each_entry(mode, &connector->modes, head) {
|
||||
/* check width/height */
|
||||
if (mode->hdisplay != cmdline_mode->xres ||
|
||||
mode->vdisplay != cmdline_mode->yres)
|
||||
continue;
|
||||
|
||||
if (cmdline_mode->refresh_specified) {
|
||||
if (mode->vrefresh != cmdline_mode->refresh)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cmdline_mode->interlace) {
|
||||
if (!(mode->flags & DRM_MODE_FLAG_INTERLACE))
|
||||
continue;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
create_mode:
|
||||
mode = drm_cvt_mode(connector->dev, cmdline_mode->xres,
|
||||
cmdline_mode->yres,
|
||||
cmdline_mode->refresh_specified ? cmdline_mode->refresh : 60,
|
||||
cmdline_mode->rb, cmdline_mode->interlace,
|
||||
cmdline_mode->margins);
|
||||
list_add(&mode->head, &connector->modes);
|
||||
return mode;
|
||||
}
|
||||
|
||||
static bool drm_connector_enabled(struct drm_connector *connector, bool strict)
|
||||
{
|
||||
bool enable;
|
||||
|
@ -317,10 +385,16 @@ static bool drm_target_preferred(struct drm_device *dev,
|
|||
continue;
|
||||
}
|
||||
|
||||
DRM_DEBUG_KMS("looking for preferred mode on connector %d\n",
|
||||
connector->base.id);
|
||||
DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n",
|
||||
connector->base.id);
|
||||
|
||||
modes[i] = drm_has_preferred_mode(connector, width, height);
|
||||
/* got for command line mode first */
|
||||
modes[i] = drm_pick_cmdline_mode(connector, width, height);
|
||||
if (!modes[i]) {
|
||||
DRM_DEBUG_KMS("looking for preferred mode on connector %d\n",
|
||||
connector->base.id);
|
||||
modes[i] = drm_has_preferred_mode(connector, width, height);
|
||||
}
|
||||
/* No preferred modes, pick one off the list */
|
||||
if (!modes[i] && !list_empty(&connector->modes)) {
|
||||
list_for_each_entry(modes[i], &connector->modes, head)
|
||||
|
@ -369,6 +443,8 @@ static int drm_pick_crtcs(struct drm_device *dev,
|
|||
my_score = 1;
|
||||
if (connector->status == connector_status_connected)
|
||||
my_score++;
|
||||
if (drm_has_cmdline_mode(connector))
|
||||
my_score++;
|
||||
if (drm_has_preferred_mode(connector, width, height))
|
||||
my_score++;
|
||||
|
||||
|
@ -943,6 +1019,8 @@ bool drm_helper_initial_config(struct drm_device *dev)
|
|||
{
|
||||
int count = 0;
|
||||
|
||||
drm_fb_helper_parse_command_line(dev);
|
||||
|
||||
count = drm_helper_probe_connector_modes(dev,
|
||||
dev->mode_config.max_width,
|
||||
dev->mode_config.max_height);
|
||||
|
@ -950,7 +1028,7 @@ bool drm_helper_initial_config(struct drm_device *dev)
|
|||
/*
|
||||
* we shouldn't end up with no modes here.
|
||||
*/
|
||||
WARN(!count, "Connected connector with 0 modes\n");
|
||||
WARN(!count, "No connectors reported connected with modes\n");
|
||||
|
||||
drm_setup_crtcs(dev);
|
||||
|
||||
|
|
|
@ -109,7 +109,9 @@ static struct edid_quirk {
|
|||
|
||||
|
||||
/* Valid EDID header has these bytes */
|
||||
static u8 edid_header[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
|
||||
static const u8 edid_header[] = {
|
||||
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
|
||||
};
|
||||
|
||||
/**
|
||||
* edid_is_valid - sanity check EDID data
|
||||
|
@ -500,6 +502,19 @@ static struct drm_display_mode *drm_find_dmt(struct drm_device *dev,
|
|||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
/*
|
||||
* 0 is reserved. The spec says 0x01 fill for unused timings. Some old
|
||||
* monitors fill with ascii space (0x20) instead.
|
||||
*/
|
||||
static int
|
||||
bad_std_timing(u8 a, u8 b)
|
||||
{
|
||||
return (a == 0x00 && b == 0x00) ||
|
||||
(a == 0x01 && b == 0x01) ||
|
||||
(a == 0x20 && b == 0x20);
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_mode_std - convert standard mode info (width, height, refresh) into mode
|
||||
* @t: standard timing params
|
||||
|
@ -513,6 +528,7 @@ static struct drm_display_mode *drm_find_dmt(struct drm_device *dev,
|
|||
*/
|
||||
struct drm_display_mode *drm_mode_std(struct drm_device *dev,
|
||||
struct std_timing *t,
|
||||
int revision,
|
||||
int timing_level)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
|
@ -523,14 +539,20 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev,
|
|||
unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK)
|
||||
>> EDID_TIMING_VFREQ_SHIFT;
|
||||
|
||||
if (bad_std_timing(t->hsize, t->vfreq_aspect))
|
||||
return NULL;
|
||||
|
||||
/* According to the EDID spec, the hdisplay = hsize * 8 + 248 */
|
||||
hsize = t->hsize * 8 + 248;
|
||||
/* vrefresh_rate = vfreq + 60 */
|
||||
vrefresh_rate = vfreq + 60;
|
||||
/* the vdisplay is calculated based on the aspect ratio */
|
||||
if (aspect_ratio == 0)
|
||||
vsize = (hsize * 10) / 16;
|
||||
else if (aspect_ratio == 1)
|
||||
if (aspect_ratio == 0) {
|
||||
if (revision < 3)
|
||||
vsize = hsize;
|
||||
else
|
||||
vsize = (hsize * 10) / 16;
|
||||
} else if (aspect_ratio == 1)
|
||||
vsize = (hsize * 3) / 4;
|
||||
else if (aspect_ratio == 2)
|
||||
vsize = (hsize * 4) / 5;
|
||||
|
@ -538,7 +560,8 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev,
|
|||
vsize = (hsize * 9) / 16;
|
||||
/* HDTV hack */
|
||||
if (hsize == 1360 && vsize == 765 && vrefresh_rate == 60) {
|
||||
mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
|
||||
mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0,
|
||||
false);
|
||||
mode->hdisplay = 1366;
|
||||
mode->vsync_start = mode->vsync_start - 1;
|
||||
mode->vsync_end = mode->vsync_end - 1;
|
||||
|
@ -557,7 +580,8 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev,
|
|||
mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
|
||||
break;
|
||||
case LEVEL_CVT:
|
||||
mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0);
|
||||
mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0,
|
||||
false);
|
||||
break;
|
||||
}
|
||||
return mode;
|
||||
|
@ -779,7 +803,7 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid
|
|||
continue;
|
||||
|
||||
newmode = drm_mode_std(dev, &edid->standard_timings[i],
|
||||
timing_level);
|
||||
edid->revision, timing_level);
|
||||
if (newmode) {
|
||||
drm_mode_probed_add(connector, newmode);
|
||||
modes++;
|
||||
|
@ -829,13 +853,13 @@ static int add_detailed_info(struct drm_connector *connector,
|
|||
case EDID_DETAIL_MONITOR_CPDATA:
|
||||
break;
|
||||
case EDID_DETAIL_STD_MODES:
|
||||
/* Five modes per detailed section */
|
||||
for (j = 0; j < 5; i++) {
|
||||
for (j = 0; j < 6; i++) {
|
||||
struct std_timing *std;
|
||||
struct drm_display_mode *newmode;
|
||||
|
||||
std = &data->data.timings[j];
|
||||
newmode = drm_mode_std(dev, std,
|
||||
edid->revision,
|
||||
timing_level);
|
||||
if (newmode) {
|
||||
drm_mode_probed_add(connector, newmode);
|
||||
|
@ -964,7 +988,9 @@ static int add_detailed_info_eedid(struct drm_connector *connector,
|
|||
struct drm_display_mode *newmode;
|
||||
|
||||
std = &data->data.timings[j];
|
||||
newmode = drm_mode_std(dev, std, timing_level);
|
||||
newmode = drm_mode_std(dev, std,
|
||||
edid->revision,
|
||||
timing_level);
|
||||
if (newmode) {
|
||||
drm_mode_probed_add(connector, newmode);
|
||||
modes++;
|
||||
|
|
|
@ -40,6 +40,199 @@ MODULE_LICENSE("GPL and additional rights");
|
|||
|
||||
static LIST_HEAD(kernel_fb_helper_list);
|
||||
|
||||
int drm_fb_helper_add_connector(struct drm_connector *connector)
|
||||
{
|
||||
connector->fb_helper_private = kzalloc(sizeof(struct drm_fb_helper_connector), GFP_KERNEL);
|
||||
if (!connector->fb_helper_private)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_fb_helper_add_connector);
|
||||
|
||||
static int my_atoi(const char *name)
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
for (;; name++) {
|
||||
switch (*name) {
|
||||
case '0' ... '9':
|
||||
val = 10*val+(*name-'0');
|
||||
break;
|
||||
default:
|
||||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_fb_helper_connector_parse_command_line - parse command line for connector
|
||||
* @connector - connector to parse line for
|
||||
* @mode_option - per connector mode option
|
||||
*
|
||||
* This parses the connector specific then generic command lines for
|
||||
* modes and options to configure the connector.
|
||||
*
|
||||
* This uses the same parameters as the fb modedb.c, except for extra
|
||||
* <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
|
||||
*
|
||||
* enable/enable Digital/disable bit at the end
|
||||
*/
|
||||
static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *connector,
|
||||
const char *mode_option)
|
||||
{
|
||||
const char *name;
|
||||
unsigned int namelen;
|
||||
int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
|
||||
unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0;
|
||||
int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0;
|
||||
int i;
|
||||
enum drm_connector_force force = DRM_FORCE_UNSPECIFIED;
|
||||
struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private;
|
||||
struct drm_fb_helper_cmdline_mode *cmdline_mode;
|
||||
|
||||
if (!fb_help_conn)
|
||||
return false;
|
||||
|
||||
cmdline_mode = &fb_help_conn->cmdline_mode;
|
||||
if (!mode_option)
|
||||
mode_option = fb_mode_option;
|
||||
|
||||
if (!mode_option) {
|
||||
cmdline_mode->specified = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
name = mode_option;
|
||||
namelen = strlen(name);
|
||||
for (i = namelen-1; i >= 0; i--) {
|
||||
switch (name[i]) {
|
||||
case '@':
|
||||
namelen = i;
|
||||
if (!refresh_specified && !bpp_specified &&
|
||||
!yres_specified) {
|
||||
refresh = my_atoi(&name[i+1]);
|
||||
refresh_specified = 1;
|
||||
if (cvt || rb)
|
||||
cvt = 0;
|
||||
} else
|
||||
goto done;
|
||||
break;
|
||||
case '-':
|
||||
namelen = i;
|
||||
if (!bpp_specified && !yres_specified) {
|
||||
bpp = my_atoi(&name[i+1]);
|
||||
bpp_specified = 1;
|
||||
if (cvt || rb)
|
||||
cvt = 0;
|
||||
} else
|
||||
goto done;
|
||||
break;
|
||||
case 'x':
|
||||
if (!yres_specified) {
|
||||
yres = my_atoi(&name[i+1]);
|
||||
yres_specified = 1;
|
||||
} else
|
||||
goto done;
|
||||
case '0' ... '9':
|
||||
break;
|
||||
case 'M':
|
||||
if (!yres_specified)
|
||||
cvt = 1;
|
||||
break;
|
||||
case 'R':
|
||||
if (!cvt)
|
||||
rb = 1;
|
||||
break;
|
||||
case 'm':
|
||||
if (!cvt)
|
||||
margins = 1;
|
||||
break;
|
||||
case 'i':
|
||||
if (!cvt)
|
||||
interlace = 1;
|
||||
break;
|
||||
case 'e':
|
||||
force = DRM_FORCE_ON;
|
||||
break;
|
||||
case 'D':
|
||||
if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) ||
|
||||
(connector->connector_type != DRM_MODE_CONNECTOR_HDMIB))
|
||||
force = DRM_FORCE_ON;
|
||||
else
|
||||
force = DRM_FORCE_ON_DIGITAL;
|
||||
break;
|
||||
case 'd':
|
||||
force = DRM_FORCE_OFF;
|
||||
break;
|
||||
default:
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if (i < 0 && yres_specified) {
|
||||
xres = my_atoi(name);
|
||||
res_specified = 1;
|
||||
}
|
||||
done:
|
||||
|
||||
DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
|
||||
drm_get_connector_name(connector), xres, yres,
|
||||
(refresh) ? refresh : 60, (rb) ? " reduced blanking" :
|
||||
"", (margins) ? " with margins" : "", (interlace) ?
|
||||
" interlaced" : "");
|
||||
|
||||
if (force) {
|
||||
const char *s;
|
||||
switch (force) {
|
||||
case DRM_FORCE_OFF: s = "OFF"; break;
|
||||
case DRM_FORCE_ON_DIGITAL: s = "ON - dig"; break;
|
||||
default:
|
||||
case DRM_FORCE_ON: s = "ON"; break;
|
||||
}
|
||||
|
||||
DRM_INFO("forcing %s connector %s\n",
|
||||
drm_get_connector_name(connector), s);
|
||||
connector->force = force;
|
||||
}
|
||||
|
||||
if (res_specified) {
|
||||
cmdline_mode->specified = true;
|
||||
cmdline_mode->xres = xres;
|
||||
cmdline_mode->yres = yres;
|
||||
}
|
||||
|
||||
if (refresh_specified) {
|
||||
cmdline_mode->refresh_specified = true;
|
||||
cmdline_mode->refresh = refresh;
|
||||
}
|
||||
|
||||
if (bpp_specified) {
|
||||
cmdline_mode->bpp_specified = true;
|
||||
cmdline_mode->bpp = bpp;
|
||||
}
|
||||
cmdline_mode->rb = rb ? true : false;
|
||||
cmdline_mode->cvt = cvt ? true : false;
|
||||
cmdline_mode->interlace = interlace ? true : false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int drm_fb_helper_parse_command_line(struct drm_device *dev)
|
||||
{
|
||||
struct drm_connector *connector;
|
||||
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
char *option = NULL;
|
||||
|
||||
/* do something on return - turn off connector maybe */
|
||||
if (fb_get_options(drm_get_connector_name(connector), &option))
|
||||
continue;
|
||||
|
||||
drm_fb_helper_connector_parse_command_line(connector, option);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool drm_fb_helper_force_kernel_mode(void)
|
||||
{
|
||||
int i = 0;
|
||||
|
@ -87,6 +280,7 @@ void drm_fb_helper_restore(void)
|
|||
}
|
||||
EXPORT_SYMBOL(drm_fb_helper_restore);
|
||||
|
||||
#ifdef CONFIG_MAGIC_SYSRQ
|
||||
static void drm_fb_helper_restore_work_fn(struct work_struct *ignored)
|
||||
{
|
||||
drm_fb_helper_restore();
|
||||
|
@ -103,6 +297,7 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = {
|
|||
.help_msg = "force-fb(V)",
|
||||
.action_msg = "Restore framebuffer console",
|
||||
};
|
||||
#endif
|
||||
|
||||
static void drm_fb_helper_on(struct fb_info *info)
|
||||
{
|
||||
|
@ -484,6 +679,8 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev,
|
|||
uint32_t fb_height,
|
||||
uint32_t surface_width,
|
||||
uint32_t surface_height,
|
||||
uint32_t surface_depth,
|
||||
uint32_t surface_bpp,
|
||||
struct drm_framebuffer **fb_ptr))
|
||||
{
|
||||
struct drm_crtc *crtc;
|
||||
|
@ -497,8 +694,43 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev,
|
|||
struct drm_framebuffer *fb;
|
||||
struct drm_mode_set *modeset = NULL;
|
||||
struct drm_fb_helper *fb_helper;
|
||||
uint32_t surface_depth = 24, surface_bpp = 32;
|
||||
|
||||
/* first up get a count of crtcs now in use and new min/maxes width/heights */
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private;
|
||||
|
||||
struct drm_fb_helper_cmdline_mode *cmdline_mode;
|
||||
|
||||
if (!fb_help_conn)
|
||||
continue;
|
||||
|
||||
cmdline_mode = &fb_help_conn->cmdline_mode;
|
||||
|
||||
if (cmdline_mode->bpp_specified) {
|
||||
switch (cmdline_mode->bpp) {
|
||||
case 8:
|
||||
surface_depth = surface_bpp = 8;
|
||||
break;
|
||||
case 15:
|
||||
surface_depth = 15;
|
||||
surface_bpp = 16;
|
||||
break;
|
||||
case 16:
|
||||
surface_depth = surface_bpp = 16;
|
||||
break;
|
||||
case 24:
|
||||
surface_depth = surface_bpp = 24;
|
||||
break;
|
||||
case 32:
|
||||
surface_depth = 24;
|
||||
surface_bpp = 32;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
if (drm_helper_crtc_in_use(crtc)) {
|
||||
if (crtc->desired_mode) {
|
||||
|
@ -527,7 +759,8 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev,
|
|||
/* do we have an fb already? */
|
||||
if (list_empty(&dev->mode_config.fb_kernel_list)) {
|
||||
ret = (*fb_create)(dev, fb_width, fb_height, surface_width,
|
||||
surface_height, &fb);
|
||||
surface_height, surface_depth, surface_bpp,
|
||||
&fb);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
new_fb = 1;
|
||||
|
|
|
@ -88,7 +88,7 @@ EXPORT_SYMBOL(drm_mode_debug_printmodeline);
|
|||
#define HV_FACTOR 1000
|
||||
struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay,
|
||||
int vdisplay, int vrefresh,
|
||||
bool reduced, bool interlaced)
|
||||
bool reduced, bool interlaced, bool margins)
|
||||
{
|
||||
/* 1) top/bottom margin size (% of height) - default: 1.8, */
|
||||
#define CVT_MARGIN_PERCENTAGE 18
|
||||
|
@ -101,7 +101,6 @@ struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay,
|
|||
/* Pixel Clock step (kHz) */
|
||||
#define CVT_CLOCK_STEP 250
|
||||
struct drm_display_mode *drm_mode;
|
||||
bool margins = false;
|
||||
unsigned int vfieldrate, hperiod;
|
||||
int hdisplay_rnd, hmargin, vdisplay_rnd, vmargin, vsync;
|
||||
int interlace;
|
||||
|
|
|
@ -110,6 +110,7 @@ EXPORT_SYMBOL(intelfb_resize);
|
|||
static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
|
||||
uint32_t fb_height, uint32_t surface_width,
|
||||
uint32_t surface_height,
|
||||
uint32_t surface_depth, uint32_t surface_bpp,
|
||||
struct drm_framebuffer **fb_p)
|
||||
{
|
||||
struct fb_info *info;
|
||||
|
@ -125,9 +126,9 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width,
|
|||
mode_cmd.width = surface_width;
|
||||
mode_cmd.height = surface_height;
|
||||
|
||||
mode_cmd.bpp = 32;
|
||||
mode_cmd.bpp = surface_bpp;
|
||||
mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 1) / 8), 64);
|
||||
mode_cmd.depth = 24;
|
||||
mode_cmd.depth = surface_depth;
|
||||
|
||||
size = mode_cmd.pitch * mode_cmd.height;
|
||||
size = ALIGN(size, PAGE_SIZE);
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
mkregtable
|
||||
*_reg_safe.h
|
||||
|
|
@ -57,13 +57,4 @@
|
|||
#define VGA_RENDER_CONTROL 0x0300
|
||||
#define VGA_VSTATUS_CNTL_MASK 0x00030000
|
||||
|
||||
/* AVIVO disable VGA rendering */
|
||||
static inline void radeon_avivo_vga_render_disable(struct radeon_device *rdev)
|
||||
{
|
||||
u32 vga_render;
|
||||
vga_render = RREG32(VGA_RENDER_CONTROL);
|
||||
vga_render &= ~VGA_VSTATUS_CNTL_MASK;
|
||||
WREG32(VGA_RENDER_CONTROL, vga_render);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -863,13 +863,11 @@ int r100_cs_parse_packet0(struct radeon_cs_parser *p,
|
|||
void r100_cs_dump_packet(struct radeon_cs_parser *p,
|
||||
struct radeon_cs_packet *pkt)
|
||||
{
|
||||
struct radeon_cs_chunk *ib_chunk;
|
||||
volatile uint32_t *ib;
|
||||
unsigned i;
|
||||
unsigned idx;
|
||||
|
||||
ib = p->ib->ptr;
|
||||
ib_chunk = &p->chunks[p->chunk_ib_idx];
|
||||
idx = pkt->idx;
|
||||
for (i = 0; i <= (pkt->count + 1); i++, idx++) {
|
||||
DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]);
|
||||
|
@ -896,7 +894,7 @@ int r100_cs_packet_parse(struct radeon_cs_parser *p,
|
|||
idx, ib_chunk->length_dw);
|
||||
return -EINVAL;
|
||||
}
|
||||
header = ib_chunk->kdata[idx];
|
||||
header = radeon_get_ib_value(p, idx);
|
||||
pkt->idx = idx;
|
||||
pkt->type = CP_PACKET_GET_TYPE(header);
|
||||
pkt->count = CP_PACKET_GET_COUNT(header);
|
||||
|
@ -939,7 +937,6 @@ int r100_cs_packet_parse(struct radeon_cs_parser *p,
|
|||
*/
|
||||
int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
|
||||
{
|
||||
struct radeon_cs_chunk *ib_chunk;
|
||||
struct drm_mode_object *obj;
|
||||
struct drm_crtc *crtc;
|
||||
struct radeon_crtc *radeon_crtc;
|
||||
|
@ -947,8 +944,9 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
|
|||
int crtc_id;
|
||||
int r;
|
||||
uint32_t header, h_idx, reg;
|
||||
volatile uint32_t *ib;
|
||||
|
||||
ib_chunk = &p->chunks[p->chunk_ib_idx];
|
||||
ib = p->ib->ptr;
|
||||
|
||||
/* parse the wait until */
|
||||
r = r100_cs_packet_parse(p, &waitreloc, p->idx);
|
||||
|
@ -963,24 +961,24 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
|
|||
return r;
|
||||
}
|
||||
|
||||
if (ib_chunk->kdata[waitreloc.idx + 1] != RADEON_WAIT_CRTC_VLINE) {
|
||||
if (radeon_get_ib_value(p, waitreloc.idx + 1) != RADEON_WAIT_CRTC_VLINE) {
|
||||
DRM_ERROR("vline wait had illegal wait until\n");
|
||||
r = -EINVAL;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* jump over the NOP */
|
||||
r = r100_cs_packet_parse(p, &p3reloc, p->idx);
|
||||
r = r100_cs_packet_parse(p, &p3reloc, p->idx + waitreloc.count + 2);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
h_idx = p->idx - 2;
|
||||
p->idx += waitreloc.count;
|
||||
p->idx += p3reloc.count;
|
||||
p->idx += waitreloc.count + 2;
|
||||
p->idx += p3reloc.count + 2;
|
||||
|
||||
header = ib_chunk->kdata[h_idx];
|
||||
crtc_id = ib_chunk->kdata[h_idx + 5];
|
||||
reg = ib_chunk->kdata[h_idx] >> 2;
|
||||
header = radeon_get_ib_value(p, h_idx);
|
||||
crtc_id = radeon_get_ib_value(p, h_idx + 5);
|
||||
reg = header >> 2;
|
||||
mutex_lock(&p->rdev->ddev->mode_config.mutex);
|
||||
obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
|
||||
if (!obj) {
|
||||
|
@ -994,16 +992,16 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
|
|||
|
||||
if (!crtc->enabled) {
|
||||
/* if the CRTC isn't enabled - we need to nop out the wait until */
|
||||
ib_chunk->kdata[h_idx + 2] = PACKET2(0);
|
||||
ib_chunk->kdata[h_idx + 3] = PACKET2(0);
|
||||
ib[h_idx + 2] = PACKET2(0);
|
||||
ib[h_idx + 3] = PACKET2(0);
|
||||
} else if (crtc_id == 1) {
|
||||
switch (reg) {
|
||||
case AVIVO_D1MODE_VLINE_START_END:
|
||||
header &= R300_CP_PACKET0_REG_MASK;
|
||||
header &= ~R300_CP_PACKET0_REG_MASK;
|
||||
header |= AVIVO_D2MODE_VLINE_START_END >> 2;
|
||||
break;
|
||||
case RADEON_CRTC_GUI_TRIG_VLINE:
|
||||
header &= R300_CP_PACKET0_REG_MASK;
|
||||
header &= ~R300_CP_PACKET0_REG_MASK;
|
||||
header |= RADEON_CRTC2_GUI_TRIG_VLINE >> 2;
|
||||
break;
|
||||
default:
|
||||
|
@ -1011,8 +1009,8 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
|
|||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
ib_chunk->kdata[h_idx] = header;
|
||||
ib_chunk->kdata[h_idx + 3] |= RADEON_ENG_DISPLAY_SELECT_CRTC1;
|
||||
ib[h_idx] = header;
|
||||
ib[h_idx + 3] |= RADEON_ENG_DISPLAY_SELECT_CRTC1;
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&p->rdev->ddev->mode_config.mutex);
|
||||
|
@ -1033,7 +1031,6 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p)
|
|||
int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
|
||||
struct radeon_cs_reloc **cs_reloc)
|
||||
{
|
||||
struct radeon_cs_chunk *ib_chunk;
|
||||
struct radeon_cs_chunk *relocs_chunk;
|
||||
struct radeon_cs_packet p3reloc;
|
||||
unsigned idx;
|
||||
|
@ -1044,7 +1041,6 @@ int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
|
|||
return -EINVAL;
|
||||
}
|
||||
*cs_reloc = NULL;
|
||||
ib_chunk = &p->chunks[p->chunk_ib_idx];
|
||||
relocs_chunk = &p->chunks[p->chunk_relocs_idx];
|
||||
r = r100_cs_packet_parse(p, &p3reloc, p->idx);
|
||||
if (r) {
|
||||
|
@ -1057,7 +1053,7 @@ int r100_cs_packet_next_reloc(struct radeon_cs_parser *p,
|
|||
r100_cs_dump_packet(p, &p3reloc);
|
||||
return -EINVAL;
|
||||
}
|
||||
idx = ib_chunk->kdata[p3reloc.idx + 1];
|
||||
idx = radeon_get_ib_value(p, p3reloc.idx + 1);
|
||||
if (idx >= relocs_chunk->length_dw) {
|
||||
DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
|
||||
idx, relocs_chunk->length_dw);
|
||||
|
@ -1126,7 +1122,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
|
|||
struct radeon_cs_packet *pkt,
|
||||
unsigned idx, unsigned reg)
|
||||
{
|
||||
struct radeon_cs_chunk *ib_chunk;
|
||||
struct radeon_cs_reloc *reloc;
|
||||
struct r100_cs_track *track;
|
||||
volatile uint32_t *ib;
|
||||
|
@ -1134,11 +1129,13 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
|
|||
int r;
|
||||
int i, face;
|
||||
u32 tile_flags = 0;
|
||||
u32 idx_value;
|
||||
|
||||
ib = p->ib->ptr;
|
||||
ib_chunk = &p->chunks[p->chunk_ib_idx];
|
||||
track = (struct r100_cs_track *)p->track;
|
||||
|
||||
idx_value = radeon_get_ib_value(p, idx);
|
||||
|
||||
switch (reg) {
|
||||
case RADEON_CRTC_GUI_TRIG_VLINE:
|
||||
r = r100_cs_packet_parse_vline(p);
|
||||
|
@ -1166,8 +1163,8 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
|
|||
return r;
|
||||
}
|
||||
track->zb.robj = reloc->robj;
|
||||
track->zb.offset = ib_chunk->kdata[idx];
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
track->zb.offset = idx_value;
|
||||
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
|
||||
break;
|
||||
case RADEON_RB3D_COLOROFFSET:
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
|
@ -1178,8 +1175,8 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
|
|||
return r;
|
||||
}
|
||||
track->cb[0].robj = reloc->robj;
|
||||
track->cb[0].offset = ib_chunk->kdata[idx];
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
track->cb[0].offset = idx_value;
|
||||
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
|
||||
break;
|
||||
case RADEON_PP_TXOFFSET_0:
|
||||
case RADEON_PP_TXOFFSET_1:
|
||||
|
@ -1192,7 +1189,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
|
|||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
|
||||
track->textures[i].robj = reloc->robj;
|
||||
break;
|
||||
case RADEON_PP_CUBIC_OFFSET_T0_0:
|
||||
|
@ -1208,8 +1205,8 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
|
|||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
track->textures[0].cube_info[i].offset = ib_chunk->kdata[idx];
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
track->textures[0].cube_info[i].offset = idx_value;
|
||||
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
|
||||
track->textures[0].cube_info[i].robj = reloc->robj;
|
||||
break;
|
||||
case RADEON_PP_CUBIC_OFFSET_T1_0:
|
||||
|
@ -1225,8 +1222,8 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
|
|||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
track->textures[1].cube_info[i].offset = ib_chunk->kdata[idx];
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
track->textures[1].cube_info[i].offset = idx_value;
|
||||
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
|
||||
track->textures[1].cube_info[i].robj = reloc->robj;
|
||||
break;
|
||||
case RADEON_PP_CUBIC_OFFSET_T2_0:
|
||||
|
@ -1242,12 +1239,12 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
|
|||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
track->textures[2].cube_info[i].offset = ib_chunk->kdata[idx];
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
track->textures[2].cube_info[i].offset = idx_value;
|
||||
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
|
||||
track->textures[2].cube_info[i].robj = reloc->robj;
|
||||
break;
|
||||
case RADEON_RE_WIDTH_HEIGHT:
|
||||
track->maxy = ((ib_chunk->kdata[idx] >> 16) & 0x7FF);
|
||||
track->maxy = ((idx_value >> 16) & 0x7FF);
|
||||
break;
|
||||
case RADEON_RB3D_COLORPITCH:
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
|
@ -1263,17 +1260,17 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
|
|||
if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
|
||||
tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
|
||||
|
||||
tmp = ib_chunk->kdata[idx] & ~(0x7 << 16);
|
||||
tmp = idx_value & ~(0x7 << 16);
|
||||
tmp |= tile_flags;
|
||||
ib[idx] = tmp;
|
||||
|
||||
track->cb[0].pitch = ib_chunk->kdata[idx] & RADEON_COLORPITCH_MASK;
|
||||
track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK;
|
||||
break;
|
||||
case RADEON_RB3D_DEPTHPITCH:
|
||||
track->zb.pitch = ib_chunk->kdata[idx] & RADEON_DEPTHPITCH_MASK;
|
||||
track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK;
|
||||
break;
|
||||
case RADEON_RB3D_CNTL:
|
||||
switch ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
|
||||
switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
|
@ -1291,13 +1288,13 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
|
|||
break;
|
||||
default:
|
||||
DRM_ERROR("Invalid color buffer format (%d) !\n",
|
||||
((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f));
|
||||
((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f));
|
||||
return -EINVAL;
|
||||
}
|
||||
track->z_enabled = !!(ib_chunk->kdata[idx] & RADEON_Z_ENABLE);
|
||||
track->z_enabled = !!(idx_value & RADEON_Z_ENABLE);
|
||||
break;
|
||||
case RADEON_RB3D_ZSTENCILCNTL:
|
||||
switch (ib_chunk->kdata[idx] & 0xf) {
|
||||
switch (idx_value & 0xf) {
|
||||
case 0:
|
||||
track->zb.cpp = 2;
|
||||
break;
|
||||
|
@ -1321,44 +1318,44 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
|
|||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
|
||||
break;
|
||||
case RADEON_PP_CNTL:
|
||||
{
|
||||
uint32_t temp = ib_chunk->kdata[idx] >> 4;
|
||||
uint32_t temp = idx_value >> 4;
|
||||
for (i = 0; i < track->num_texture; i++)
|
||||
track->textures[i].enabled = !!(temp & (1 << i));
|
||||
}
|
||||
break;
|
||||
case RADEON_SE_VF_CNTL:
|
||||
track->vap_vf_cntl = ib_chunk->kdata[idx];
|
||||
track->vap_vf_cntl = idx_value;
|
||||
break;
|
||||
case RADEON_SE_VTX_FMT:
|
||||
track->vtx_size = r100_get_vtx_size(ib_chunk->kdata[idx]);
|
||||
track->vtx_size = r100_get_vtx_size(idx_value);
|
||||
break;
|
||||
case RADEON_PP_TEX_SIZE_0:
|
||||
case RADEON_PP_TEX_SIZE_1:
|
||||
case RADEON_PP_TEX_SIZE_2:
|
||||
i = (reg - RADEON_PP_TEX_SIZE_0) / 8;
|
||||
track->textures[i].width = (ib_chunk->kdata[idx] & RADEON_TEX_USIZE_MASK) + 1;
|
||||
track->textures[i].height = ((ib_chunk->kdata[idx] & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
|
||||
track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1;
|
||||
track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
|
||||
break;
|
||||
case RADEON_PP_TEX_PITCH_0:
|
||||
case RADEON_PP_TEX_PITCH_1:
|
||||
case RADEON_PP_TEX_PITCH_2:
|
||||
i = (reg - RADEON_PP_TEX_PITCH_0) / 8;
|
||||
track->textures[i].pitch = ib_chunk->kdata[idx] + 32;
|
||||
track->textures[i].pitch = idx_value + 32;
|
||||
break;
|
||||
case RADEON_PP_TXFILTER_0:
|
||||
case RADEON_PP_TXFILTER_1:
|
||||
case RADEON_PP_TXFILTER_2:
|
||||
i = (reg - RADEON_PP_TXFILTER_0) / 24;
|
||||
track->textures[i].num_levels = ((ib_chunk->kdata[idx] & RADEON_MAX_MIP_LEVEL_MASK)
|
||||
track->textures[i].num_levels = ((idx_value & RADEON_MAX_MIP_LEVEL_MASK)
|
||||
>> RADEON_MAX_MIP_LEVEL_SHIFT);
|
||||
tmp = (ib_chunk->kdata[idx] >> 23) & 0x7;
|
||||
tmp = (idx_value >> 23) & 0x7;
|
||||
if (tmp == 2 || tmp == 6)
|
||||
track->textures[i].roundup_w = false;
|
||||
tmp = (ib_chunk->kdata[idx] >> 27) & 0x7;
|
||||
tmp = (idx_value >> 27) & 0x7;
|
||||
if (tmp == 2 || tmp == 6)
|
||||
track->textures[i].roundup_h = false;
|
||||
break;
|
||||
|
@ -1366,16 +1363,16 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
|
|||
case RADEON_PP_TXFORMAT_1:
|
||||
case RADEON_PP_TXFORMAT_2:
|
||||
i = (reg - RADEON_PP_TXFORMAT_0) / 24;
|
||||
if (ib_chunk->kdata[idx] & RADEON_TXFORMAT_NON_POWER2) {
|
||||
if (idx_value & RADEON_TXFORMAT_NON_POWER2) {
|
||||
track->textures[i].use_pitch = 1;
|
||||
} else {
|
||||
track->textures[i].use_pitch = 0;
|
||||
track->textures[i].width = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
|
||||
track->textures[i].height = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
|
||||
track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
|
||||
track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
|
||||
}
|
||||
if (ib_chunk->kdata[idx] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE)
|
||||
if (idx_value & RADEON_TXFORMAT_CUBIC_MAP_ENABLE)
|
||||
track->textures[i].tex_coord_type = 2;
|
||||
switch ((ib_chunk->kdata[idx] & RADEON_TXFORMAT_FORMAT_MASK)) {
|
||||
switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) {
|
||||
case RADEON_TXFORMAT_I8:
|
||||
case RADEON_TXFORMAT_RGB332:
|
||||
case RADEON_TXFORMAT_Y8:
|
||||
|
@ -1402,13 +1399,13 @@ static int r100_packet0_check(struct radeon_cs_parser *p,
|
|||
track->textures[i].cpp = 4;
|
||||
break;
|
||||
}
|
||||
track->textures[i].cube_info[4].width = 1 << ((ib_chunk->kdata[idx] >> 16) & 0xf);
|
||||
track->textures[i].cube_info[4].height = 1 << ((ib_chunk->kdata[idx] >> 20) & 0xf);
|
||||
track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf);
|
||||
track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf);
|
||||
break;
|
||||
case RADEON_PP_CUBIC_FACES_0:
|
||||
case RADEON_PP_CUBIC_FACES_1:
|
||||
case RADEON_PP_CUBIC_FACES_2:
|
||||
tmp = ib_chunk->kdata[idx];
|
||||
tmp = idx_value;
|
||||
i = (reg - RADEON_PP_CUBIC_FACES_0) / 4;
|
||||
for (face = 0; face < 4; face++) {
|
||||
track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf);
|
||||
|
@ -1427,15 +1424,14 @@ int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
|
|||
struct radeon_cs_packet *pkt,
|
||||
struct radeon_object *robj)
|
||||
{
|
||||
struct radeon_cs_chunk *ib_chunk;
|
||||
unsigned idx;
|
||||
|
||||
ib_chunk = &p->chunks[p->chunk_ib_idx];
|
||||
u32 value;
|
||||
idx = pkt->idx + 1;
|
||||
if ((ib_chunk->kdata[idx+2] + 1) > radeon_object_size(robj)) {
|
||||
value = radeon_get_ib_value(p, idx + 2);
|
||||
if ((value + 1) > radeon_object_size(robj)) {
|
||||
DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER "
|
||||
"(need %u have %lu) !\n",
|
||||
ib_chunk->kdata[idx+2] + 1,
|
||||
value + 1,
|
||||
radeon_object_size(robj));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -1445,59 +1441,20 @@ int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p,
|
|||
static int r100_packet3_check(struct radeon_cs_parser *p,
|
||||
struct radeon_cs_packet *pkt)
|
||||
{
|
||||
struct radeon_cs_chunk *ib_chunk;
|
||||
struct radeon_cs_reloc *reloc;
|
||||
struct r100_cs_track *track;
|
||||
unsigned idx;
|
||||
unsigned i, c;
|
||||
volatile uint32_t *ib;
|
||||
int r;
|
||||
|
||||
ib = p->ib->ptr;
|
||||
ib_chunk = &p->chunks[p->chunk_ib_idx];
|
||||
idx = pkt->idx + 1;
|
||||
track = (struct r100_cs_track *)p->track;
|
||||
switch (pkt->opcode) {
|
||||
case PACKET3_3D_LOAD_VBPNTR:
|
||||
c = ib_chunk->kdata[idx++];
|
||||
track->num_arrays = c;
|
||||
for (i = 0; i < (c - 1); i += 2, idx += 3) {
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
DRM_ERROR("No reloc for packet3 %d\n",
|
||||
pkt->opcode);
|
||||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset);
|
||||
track->arrays[i + 0].robj = reloc->robj;
|
||||
track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8;
|
||||
track->arrays[i + 0].esize &= 0x7F;
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
DRM_ERROR("No reloc for packet3 %d\n",
|
||||
pkt->opcode);
|
||||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
ib[idx+2] = ib_chunk->kdata[idx+2] + ((u32)reloc->lobj.gpu_offset);
|
||||
track->arrays[i + 1].robj = reloc->robj;
|
||||
track->arrays[i + 1].esize = ib_chunk->kdata[idx] >> 24;
|
||||
track->arrays[i + 1].esize &= 0x7F;
|
||||
}
|
||||
if (c & 1) {
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
DRM_ERROR("No reloc for packet3 %d\n",
|
||||
pkt->opcode);
|
||||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset);
|
||||
track->arrays[i + 0].robj = reloc->robj;
|
||||
track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8;
|
||||
track->arrays[i + 0].esize &= 0x7F;
|
||||
}
|
||||
r = r100_packet3_load_vbpntr(p, pkt, idx);
|
||||
if (r)
|
||||
return r;
|
||||
break;
|
||||
case PACKET3_INDX_BUFFER:
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
|
@ -1506,7 +1463,7 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
|
|||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset);
|
||||
ib[idx+1] = radeon_get_ib_value(p, idx+1) + ((u32)reloc->lobj.gpu_offset);
|
||||
r = r100_cs_track_check_pkt3_indx_buffer(p, pkt, reloc->robj);
|
||||
if (r) {
|
||||
return r;
|
||||
|
@ -1520,27 +1477,27 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
|
|||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
ib[idx] = radeon_get_ib_value(p, idx) + ((u32)reloc->lobj.gpu_offset);
|
||||
track->num_arrays = 1;
|
||||
track->vtx_size = r100_get_vtx_size(ib_chunk->kdata[idx+2]);
|
||||
track->vtx_size = r100_get_vtx_size(radeon_get_ib_value(p, idx + 2));
|
||||
|
||||
track->arrays[0].robj = reloc->robj;
|
||||
track->arrays[0].esize = track->vtx_size;
|
||||
|
||||
track->max_indx = ib_chunk->kdata[idx+1];
|
||||
track->max_indx = radeon_get_ib_value(p, idx+1);
|
||||
|
||||
track->vap_vf_cntl = ib_chunk->kdata[idx+3];
|
||||
track->vap_vf_cntl = radeon_get_ib_value(p, idx+3);
|
||||
track->immd_dwords = pkt->count - 1;
|
||||
r = r100_cs_track_check(p->rdev, track);
|
||||
if (r)
|
||||
return r;
|
||||
break;
|
||||
case PACKET3_3D_DRAW_IMMD:
|
||||
if (((ib_chunk->kdata[idx+1] >> 4) & 0x3) != 3) {
|
||||
if (((radeon_get_ib_value(p, idx + 1) >> 4) & 0x3) != 3) {
|
||||
DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
track->vap_vf_cntl = ib_chunk->kdata[idx+1];
|
||||
track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1);
|
||||
track->immd_dwords = pkt->count - 1;
|
||||
r = r100_cs_track_check(p->rdev, track);
|
||||
if (r)
|
||||
|
@ -1548,11 +1505,11 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
|
|||
break;
|
||||
/* triggers drawing using in-packet vertex data */
|
||||
case PACKET3_3D_DRAW_IMMD_2:
|
||||
if (((ib_chunk->kdata[idx] >> 4) & 0x3) != 3) {
|
||||
if (((radeon_get_ib_value(p, idx) >> 4) & 0x3) != 3) {
|
||||
DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
track->vap_vf_cntl = ib_chunk->kdata[idx];
|
||||
track->vap_vf_cntl = radeon_get_ib_value(p, idx);
|
||||
track->immd_dwords = pkt->count;
|
||||
r = r100_cs_track_check(p->rdev, track);
|
||||
if (r)
|
||||
|
@ -1560,28 +1517,28 @@ static int r100_packet3_check(struct radeon_cs_parser *p,
|
|||
break;
|
||||
/* triggers drawing using in-packet vertex data */
|
||||
case PACKET3_3D_DRAW_VBUF_2:
|
||||
track->vap_vf_cntl = ib_chunk->kdata[idx];
|
||||
track->vap_vf_cntl = radeon_get_ib_value(p, idx);
|
||||
r = r100_cs_track_check(p->rdev, track);
|
||||
if (r)
|
||||
return r;
|
||||
break;
|
||||
/* triggers drawing of vertex buffers setup elsewhere */
|
||||
case PACKET3_3D_DRAW_INDX_2:
|
||||
track->vap_vf_cntl = ib_chunk->kdata[idx];
|
||||
track->vap_vf_cntl = radeon_get_ib_value(p, idx);
|
||||
r = r100_cs_track_check(p->rdev, track);
|
||||
if (r)
|
||||
return r;
|
||||
break;
|
||||
/* triggers drawing using indices to vertex buffer */
|
||||
case PACKET3_3D_DRAW_VBUF:
|
||||
track->vap_vf_cntl = ib_chunk->kdata[idx + 1];
|
||||
track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1);
|
||||
r = r100_cs_track_check(p->rdev, track);
|
||||
if (r)
|
||||
return r;
|
||||
break;
|
||||
/* triggers drawing of vertex buffers setup elsewhere */
|
||||
case PACKET3_3D_DRAW_INDX:
|
||||
track->vap_vf_cntl = ib_chunk->kdata[idx + 1];
|
||||
track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1);
|
||||
r = r100_cs_track_check(p->rdev, track);
|
||||
if (r)
|
||||
return r;
|
||||
|
|
|
@ -84,6 +84,8 @@ int r200_packet0_check(struct radeon_cs_parser *p,
|
|||
struct radeon_cs_packet *pkt,
|
||||
unsigned idx, unsigned reg);
|
||||
|
||||
|
||||
|
||||
static inline int r100_reloc_pitch_offset(struct radeon_cs_parser *p,
|
||||
struct radeon_cs_packet *pkt,
|
||||
unsigned idx,
|
||||
|
@ -93,9 +95,7 @@ static inline int r100_reloc_pitch_offset(struct radeon_cs_parser *p,
|
|||
u32 tile_flags = 0;
|
||||
u32 tmp;
|
||||
struct radeon_cs_reloc *reloc;
|
||||
struct radeon_cs_chunk *ib_chunk;
|
||||
|
||||
ib_chunk = &p->chunks[p->chunk_ib_idx];
|
||||
u32 value;
|
||||
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
|
@ -104,7 +104,8 @@ static inline int r100_reloc_pitch_offset(struct radeon_cs_parser *p,
|
|||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
tmp = ib_chunk->kdata[idx] & 0x003fffff;
|
||||
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)
|
||||
|
@ -119,6 +120,64 @@ static inline int r100_reloc_pitch_offset(struct radeon_cs_parser *p,
|
|||
}
|
||||
|
||||
tmp |= tile_flags;
|
||||
p->ib->ptr[idx] = (ib_chunk->kdata[idx] & 0x3fc00000) | tmp;
|
||||
p->ib->ptr[idx] = (value & 0x3fc00000) | tmp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int r100_packet3_load_vbpntr(struct radeon_cs_parser *p,
|
||||
struct radeon_cs_packet *pkt,
|
||||
int idx)
|
||||
{
|
||||
unsigned c, i;
|
||||
struct radeon_cs_reloc *reloc;
|
||||
struct r100_cs_track *track;
|
||||
int r = 0;
|
||||
volatile uint32_t *ib;
|
||||
u32 idx_value;
|
||||
|
||||
ib = p->ib->ptr;
|
||||
track = (struct r100_cs_track *)p->track;
|
||||
c = radeon_get_ib_value(p, idx++) & 0x1F;
|
||||
track->num_arrays = c;
|
||||
for (i = 0; i < (c - 1); i+=2, idx+=3) {
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
DRM_ERROR("No reloc for packet3 %d\n",
|
||||
pkt->opcode);
|
||||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
idx_value = radeon_get_ib_value(p, idx);
|
||||
ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset);
|
||||
|
||||
track->arrays[i + 0].esize = idx_value >> 8;
|
||||
track->arrays[i + 0].robj = reloc->robj;
|
||||
track->arrays[i + 0].esize &= 0x7F;
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
DRM_ERROR("No reloc for packet3 %d\n",
|
||||
pkt->opcode);
|
||||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
ib[idx+2] = radeon_get_ib_value(p, idx + 2) + ((u32)reloc->lobj.gpu_offset);
|
||||
track->arrays[i + 1].robj = reloc->robj;
|
||||
track->arrays[i + 1].esize = idx_value >> 24;
|
||||
track->arrays[i + 1].esize &= 0x7F;
|
||||
}
|
||||
if (c & 1) {
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
DRM_ERROR("No reloc for packet3 %d\n",
|
||||
pkt->opcode);
|
||||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
idx_value = radeon_get_ib_value(p, idx);
|
||||
ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset);
|
||||
track->arrays[i + 0].robj = reloc->robj;
|
||||
track->arrays[i + 0].esize = idx_value >> 8;
|
||||
track->arrays[i + 0].esize &= 0x7F;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -96,7 +96,6 @@ int r200_packet0_check(struct radeon_cs_parser *p,
|
|||
struct radeon_cs_packet *pkt,
|
||||
unsigned idx, unsigned reg)
|
||||
{
|
||||
struct radeon_cs_chunk *ib_chunk;
|
||||
struct radeon_cs_reloc *reloc;
|
||||
struct r100_cs_track *track;
|
||||
volatile uint32_t *ib;
|
||||
|
@ -105,11 +104,11 @@ int r200_packet0_check(struct radeon_cs_parser *p,
|
|||
int i;
|
||||
int face;
|
||||
u32 tile_flags = 0;
|
||||
u32 idx_value;
|
||||
|
||||
ib = p->ib->ptr;
|
||||
ib_chunk = &p->chunks[p->chunk_ib_idx];
|
||||
track = (struct r100_cs_track *)p->track;
|
||||
|
||||
idx_value = radeon_get_ib_value(p, idx);
|
||||
switch (reg) {
|
||||
case RADEON_CRTC_GUI_TRIG_VLINE:
|
||||
r = r100_cs_packet_parse_vline(p);
|
||||
|
@ -137,8 +136,8 @@ int r200_packet0_check(struct radeon_cs_parser *p,
|
|||
return r;
|
||||
}
|
||||
track->zb.robj = reloc->robj;
|
||||
track->zb.offset = ib_chunk->kdata[idx];
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
track->zb.offset = idx_value;
|
||||
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
|
||||
break;
|
||||
case RADEON_RB3D_COLOROFFSET:
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
|
@ -149,8 +148,8 @@ int r200_packet0_check(struct radeon_cs_parser *p,
|
|||
return r;
|
||||
}
|
||||
track->cb[0].robj = reloc->robj;
|
||||
track->cb[0].offset = ib_chunk->kdata[idx];
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
track->cb[0].offset = idx_value;
|
||||
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
|
||||
break;
|
||||
case R200_PP_TXOFFSET_0:
|
||||
case R200_PP_TXOFFSET_1:
|
||||
|
@ -166,7 +165,7 @@ int r200_packet0_check(struct radeon_cs_parser *p,
|
|||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
|
||||
track->textures[i].robj = reloc->robj;
|
||||
break;
|
||||
case R200_PP_CUBIC_OFFSET_F1_0:
|
||||
|
@ -208,12 +207,12 @@ int r200_packet0_check(struct radeon_cs_parser *p,
|
|||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
track->textures[i].cube_info[face - 1].offset = ib_chunk->kdata[idx];
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
track->textures[i].cube_info[face - 1].offset = idx_value;
|
||||
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
|
||||
track->textures[i].cube_info[face - 1].robj = reloc->robj;
|
||||
break;
|
||||
case RADEON_RE_WIDTH_HEIGHT:
|
||||
track->maxy = ((ib_chunk->kdata[idx] >> 16) & 0x7FF);
|
||||
track->maxy = ((idx_value >> 16) & 0x7FF);
|
||||
break;
|
||||
case RADEON_RB3D_COLORPITCH:
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
|
@ -229,17 +228,17 @@ int r200_packet0_check(struct radeon_cs_parser *p,
|
|||
if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
|
||||
tile_flags |= RADEON_COLOR_MICROTILE_ENABLE;
|
||||
|
||||
tmp = ib_chunk->kdata[idx] & ~(0x7 << 16);
|
||||
tmp = idx_value & ~(0x7 << 16);
|
||||
tmp |= tile_flags;
|
||||
ib[idx] = tmp;
|
||||
|
||||
track->cb[0].pitch = ib_chunk->kdata[idx] & RADEON_COLORPITCH_MASK;
|
||||
track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK;
|
||||
break;
|
||||
case RADEON_RB3D_DEPTHPITCH:
|
||||
track->zb.pitch = ib_chunk->kdata[idx] & RADEON_DEPTHPITCH_MASK;
|
||||
track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK;
|
||||
break;
|
||||
case RADEON_RB3D_CNTL:
|
||||
switch ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
|
||||
switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) {
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
|
@ -257,18 +256,18 @@ int r200_packet0_check(struct radeon_cs_parser *p,
|
|||
break;
|
||||
default:
|
||||
DRM_ERROR("Invalid color buffer format (%d) !\n",
|
||||
((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f));
|
||||
((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f));
|
||||
return -EINVAL;
|
||||
}
|
||||
if (ib_chunk->kdata[idx] & RADEON_DEPTHXY_OFFSET_ENABLE) {
|
||||
if (idx_value & RADEON_DEPTHXY_OFFSET_ENABLE) {
|
||||
DRM_ERROR("No support for depth xy offset in kms\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
track->z_enabled = !!(ib_chunk->kdata[idx] & RADEON_Z_ENABLE);
|
||||
track->z_enabled = !!(idx_value & RADEON_Z_ENABLE);
|
||||
break;
|
||||
case RADEON_RB3D_ZSTENCILCNTL:
|
||||
switch (ib_chunk->kdata[idx] & 0xf) {
|
||||
switch (idx_value & 0xf) {
|
||||
case 0:
|
||||
track->zb.cpp = 2;
|
||||
break;
|
||||
|
@ -292,27 +291,27 @@ int r200_packet0_check(struct radeon_cs_parser *p,
|
|||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
|
||||
break;
|
||||
case RADEON_PP_CNTL:
|
||||
{
|
||||
uint32_t temp = ib_chunk->kdata[idx] >> 4;
|
||||
uint32_t temp = idx_value >> 4;
|
||||
for (i = 0; i < track->num_texture; i++)
|
||||
track->textures[i].enabled = !!(temp & (1 << i));
|
||||
}
|
||||
break;
|
||||
case RADEON_SE_VF_CNTL:
|
||||
track->vap_vf_cntl = ib_chunk->kdata[idx];
|
||||
track->vap_vf_cntl = idx_value;
|
||||
break;
|
||||
case 0x210c:
|
||||
/* VAP_VF_MAX_VTX_INDX */
|
||||
track->max_indx = ib_chunk->kdata[idx] & 0x00FFFFFFUL;
|
||||
track->max_indx = idx_value & 0x00FFFFFFUL;
|
||||
break;
|
||||
case R200_SE_VTX_FMT_0:
|
||||
track->vtx_size = r200_get_vtx_size_0(ib_chunk->kdata[idx]);
|
||||
track->vtx_size = r200_get_vtx_size_0(idx_value);
|
||||
break;
|
||||
case R200_SE_VTX_FMT_1:
|
||||
track->vtx_size += r200_get_vtx_size_1(ib_chunk->kdata[idx]);
|
||||
track->vtx_size += r200_get_vtx_size_1(idx_value);
|
||||
break;
|
||||
case R200_PP_TXSIZE_0:
|
||||
case R200_PP_TXSIZE_1:
|
||||
|
@ -321,8 +320,8 @@ int r200_packet0_check(struct radeon_cs_parser *p,
|
|||
case R200_PP_TXSIZE_4:
|
||||
case R200_PP_TXSIZE_5:
|
||||
i = (reg - R200_PP_TXSIZE_0) / 32;
|
||||
track->textures[i].width = (ib_chunk->kdata[idx] & RADEON_TEX_USIZE_MASK) + 1;
|
||||
track->textures[i].height = ((ib_chunk->kdata[idx] & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
|
||||
track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1;
|
||||
track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1;
|
||||
break;
|
||||
case R200_PP_TXPITCH_0:
|
||||
case R200_PP_TXPITCH_1:
|
||||
|
@ -331,7 +330,7 @@ int r200_packet0_check(struct radeon_cs_parser *p,
|
|||
case R200_PP_TXPITCH_4:
|
||||
case R200_PP_TXPITCH_5:
|
||||
i = (reg - R200_PP_TXPITCH_0) / 32;
|
||||
track->textures[i].pitch = ib_chunk->kdata[idx] + 32;
|
||||
track->textures[i].pitch = idx_value + 32;
|
||||
break;
|
||||
case R200_PP_TXFILTER_0:
|
||||
case R200_PP_TXFILTER_1:
|
||||
|
@ -340,12 +339,12 @@ int r200_packet0_check(struct radeon_cs_parser *p,
|
|||
case R200_PP_TXFILTER_4:
|
||||
case R200_PP_TXFILTER_5:
|
||||
i = (reg - R200_PP_TXFILTER_0) / 32;
|
||||
track->textures[i].num_levels = ((ib_chunk->kdata[idx] & R200_MAX_MIP_LEVEL_MASK)
|
||||
track->textures[i].num_levels = ((idx_value & R200_MAX_MIP_LEVEL_MASK)
|
||||
>> R200_MAX_MIP_LEVEL_SHIFT);
|
||||
tmp = (ib_chunk->kdata[idx] >> 23) & 0x7;
|
||||
tmp = (idx_value >> 23) & 0x7;
|
||||
if (tmp == 2 || tmp == 6)
|
||||
track->textures[i].roundup_w = false;
|
||||
tmp = (ib_chunk->kdata[idx] >> 27) & 0x7;
|
||||
tmp = (idx_value >> 27) & 0x7;
|
||||
if (tmp == 2 || tmp == 6)
|
||||
track->textures[i].roundup_h = false;
|
||||
break;
|
||||
|
@ -364,8 +363,8 @@ int r200_packet0_check(struct radeon_cs_parser *p,
|
|||
case R200_PP_TXFORMAT_X_4:
|
||||
case R200_PP_TXFORMAT_X_5:
|
||||
i = (reg - R200_PP_TXFORMAT_X_0) / 32;
|
||||
track->textures[i].txdepth = ib_chunk->kdata[idx] & 0x7;
|
||||
tmp = (ib_chunk->kdata[idx] >> 16) & 0x3;
|
||||
track->textures[i].txdepth = idx_value & 0x7;
|
||||
tmp = (idx_value >> 16) & 0x3;
|
||||
/* 2D, 3D, CUBE */
|
||||
switch (tmp) {
|
||||
case 0:
|
||||
|
@ -389,14 +388,14 @@ int r200_packet0_check(struct radeon_cs_parser *p,
|
|||
case R200_PP_TXFORMAT_4:
|
||||
case R200_PP_TXFORMAT_5:
|
||||
i = (reg - R200_PP_TXFORMAT_0) / 32;
|
||||
if (ib_chunk->kdata[idx] & R200_TXFORMAT_NON_POWER2) {
|
||||
if (idx_value & R200_TXFORMAT_NON_POWER2) {
|
||||
track->textures[i].use_pitch = 1;
|
||||
} else {
|
||||
track->textures[i].use_pitch = 0;
|
||||
track->textures[i].width = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
|
||||
track->textures[i].height = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
|
||||
track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK);
|
||||
track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK);
|
||||
}
|
||||
switch ((ib_chunk->kdata[idx] & RADEON_TXFORMAT_FORMAT_MASK)) {
|
||||
switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) {
|
||||
case R200_TXFORMAT_I8:
|
||||
case R200_TXFORMAT_RGB332:
|
||||
case R200_TXFORMAT_Y8:
|
||||
|
@ -424,8 +423,8 @@ int r200_packet0_check(struct radeon_cs_parser *p,
|
|||
track->textures[i].cpp = 4;
|
||||
break;
|
||||
}
|
||||
track->textures[i].cube_info[4].width = 1 << ((ib_chunk->kdata[idx] >> 16) & 0xf);
|
||||
track->textures[i].cube_info[4].height = 1 << ((ib_chunk->kdata[idx] >> 20) & 0xf);
|
||||
track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf);
|
||||
track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf);
|
||||
break;
|
||||
case R200_PP_CUBIC_FACES_0:
|
||||
case R200_PP_CUBIC_FACES_1:
|
||||
|
@ -433,7 +432,7 @@ int r200_packet0_check(struct radeon_cs_parser *p,
|
|||
case R200_PP_CUBIC_FACES_3:
|
||||
case R200_PP_CUBIC_FACES_4:
|
||||
case R200_PP_CUBIC_FACES_5:
|
||||
tmp = ib_chunk->kdata[idx];
|
||||
tmp = idx_value;
|
||||
i = (reg - R200_PP_CUBIC_FACES_0) / 32;
|
||||
for (face = 0; face < 4; face++) {
|
||||
track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf);
|
||||
|
|
|
@ -697,17 +697,18 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
struct radeon_cs_packet *pkt,
|
||||
unsigned idx, unsigned reg)
|
||||
{
|
||||
struct radeon_cs_chunk *ib_chunk;
|
||||
struct radeon_cs_reloc *reloc;
|
||||
struct r100_cs_track *track;
|
||||
volatile uint32_t *ib;
|
||||
uint32_t tmp, tile_flags = 0;
|
||||
unsigned i;
|
||||
int r;
|
||||
u32 idx_value;
|
||||
|
||||
ib = p->ib->ptr;
|
||||
ib_chunk = &p->chunks[p->chunk_ib_idx];
|
||||
track = (struct r100_cs_track *)p->track;
|
||||
idx_value = radeon_get_ib_value(p, idx);
|
||||
|
||||
switch(reg) {
|
||||
case AVIVO_D1MODE_VLINE_START_END:
|
||||
case RADEON_CRTC_GUI_TRIG_VLINE:
|
||||
|
@ -738,8 +739,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
return r;
|
||||
}
|
||||
track->cb[i].robj = reloc->robj;
|
||||
track->cb[i].offset = ib_chunk->kdata[idx];
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
track->cb[i].offset = idx_value;
|
||||
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
|
||||
break;
|
||||
case R300_ZB_DEPTHOFFSET:
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
|
@ -750,8 +751,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
return r;
|
||||
}
|
||||
track->zb.robj = reloc->robj;
|
||||
track->zb.offset = ib_chunk->kdata[idx];
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
track->zb.offset = idx_value;
|
||||
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
|
||||
break;
|
||||
case R300_TX_OFFSET_0:
|
||||
case R300_TX_OFFSET_0+4:
|
||||
|
@ -777,32 +778,32 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
|
||||
track->textures[i].robj = reloc->robj;
|
||||
break;
|
||||
/* Tracked registers */
|
||||
case 0x2084:
|
||||
/* VAP_VF_CNTL */
|
||||
track->vap_vf_cntl = ib_chunk->kdata[idx];
|
||||
track->vap_vf_cntl = idx_value;
|
||||
break;
|
||||
case 0x20B4:
|
||||
/* VAP_VTX_SIZE */
|
||||
track->vtx_size = ib_chunk->kdata[idx] & 0x7F;
|
||||
track->vtx_size = idx_value & 0x7F;
|
||||
break;
|
||||
case 0x2134:
|
||||
/* VAP_VF_MAX_VTX_INDX */
|
||||
track->max_indx = ib_chunk->kdata[idx] & 0x00FFFFFFUL;
|
||||
track->max_indx = idx_value & 0x00FFFFFFUL;
|
||||
break;
|
||||
case 0x43E4:
|
||||
/* SC_SCISSOR1 */
|
||||
track->maxy = ((ib_chunk->kdata[idx] >> 13) & 0x1FFF) + 1;
|
||||
track->maxy = ((idx_value >> 13) & 0x1FFF) + 1;
|
||||
if (p->rdev->family < CHIP_RV515) {
|
||||
track->maxy -= 1440;
|
||||
}
|
||||
break;
|
||||
case 0x4E00:
|
||||
/* RB3D_CCTL */
|
||||
track->num_cb = ((ib_chunk->kdata[idx] >> 5) & 0x3) + 1;
|
||||
track->num_cb = ((idx_value >> 5) & 0x3) + 1;
|
||||
break;
|
||||
case 0x4E38:
|
||||
case 0x4E3C:
|
||||
|
@ -825,13 +826,13 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
|
||||
tile_flags |= R300_COLOR_MICROTILE_ENABLE;
|
||||
|
||||
tmp = ib_chunk->kdata[idx] & ~(0x7 << 16);
|
||||
tmp = idx_value & ~(0x7 << 16);
|
||||
tmp |= tile_flags;
|
||||
ib[idx] = tmp;
|
||||
|
||||
i = (reg - 0x4E38) >> 2;
|
||||
track->cb[i].pitch = ib_chunk->kdata[idx] & 0x3FFE;
|
||||
switch (((ib_chunk->kdata[idx] >> 21) & 0xF)) {
|
||||
track->cb[i].pitch = idx_value & 0x3FFE;
|
||||
switch (((idx_value >> 21) & 0xF)) {
|
||||
case 9:
|
||||
case 11:
|
||||
case 12:
|
||||
|
@ -854,13 +855,13 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
break;
|
||||
default:
|
||||
DRM_ERROR("Invalid color buffer format (%d) !\n",
|
||||
((ib_chunk->kdata[idx] >> 21) & 0xF));
|
||||
((idx_value >> 21) & 0xF));
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case 0x4F00:
|
||||
/* ZB_CNTL */
|
||||
if (ib_chunk->kdata[idx] & 2) {
|
||||
if (idx_value & 2) {
|
||||
track->z_enabled = true;
|
||||
} else {
|
||||
track->z_enabled = false;
|
||||
|
@ -868,7 +869,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
break;
|
||||
case 0x4F10:
|
||||
/* ZB_FORMAT */
|
||||
switch ((ib_chunk->kdata[idx] & 0xF)) {
|
||||
switch ((idx_value & 0xF)) {
|
||||
case 0:
|
||||
case 1:
|
||||
track->zb.cpp = 2;
|
||||
|
@ -878,7 +879,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
break;
|
||||
default:
|
||||
DRM_ERROR("Invalid z buffer format (%d) !\n",
|
||||
(ib_chunk->kdata[idx] & 0xF));
|
||||
(idx_value & 0xF));
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
@ -897,17 +898,17 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO)
|
||||
tile_flags |= R300_DEPTHMICROTILE_TILED;;
|
||||
|
||||
tmp = ib_chunk->kdata[idx] & ~(0x7 << 16);
|
||||
tmp = idx_value & ~(0x7 << 16);
|
||||
tmp |= tile_flags;
|
||||
ib[idx] = tmp;
|
||||
|
||||
track->zb.pitch = ib_chunk->kdata[idx] & 0x3FFC;
|
||||
track->zb.pitch = idx_value & 0x3FFC;
|
||||
break;
|
||||
case 0x4104:
|
||||
for (i = 0; i < 16; i++) {
|
||||
bool enabled;
|
||||
|
||||
enabled = !!(ib_chunk->kdata[idx] & (1 << i));
|
||||
enabled = !!(idx_value & (1 << i));
|
||||
track->textures[i].enabled = enabled;
|
||||
}
|
||||
break;
|
||||
|
@ -929,9 +930,9 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
case 0x44FC:
|
||||
/* TX_FORMAT1_[0-15] */
|
||||
i = (reg - 0x44C0) >> 2;
|
||||
tmp = (ib_chunk->kdata[idx] >> 25) & 0x3;
|
||||
tmp = (idx_value >> 25) & 0x3;
|
||||
track->textures[i].tex_coord_type = tmp;
|
||||
switch ((ib_chunk->kdata[idx] & 0x1F)) {
|
||||
switch ((idx_value & 0x1F)) {
|
||||
case R300_TX_FORMAT_X8:
|
||||
case R300_TX_FORMAT_Y4X4:
|
||||
case R300_TX_FORMAT_Z3Y3X2:
|
||||
|
@ -971,7 +972,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
break;
|
||||
default:
|
||||
DRM_ERROR("Invalid texture format %u\n",
|
||||
(ib_chunk->kdata[idx] & 0x1F));
|
||||
(idx_value & 0x1F));
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
@ -994,11 +995,11 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
case 0x443C:
|
||||
/* TX_FILTER0_[0-15] */
|
||||
i = (reg - 0x4400) >> 2;
|
||||
tmp = ib_chunk->kdata[idx] & 0x7;
|
||||
tmp = idx_value & 0x7;
|
||||
if (tmp == 2 || tmp == 4 || tmp == 6) {
|
||||
track->textures[i].roundup_w = false;
|
||||
}
|
||||
tmp = (ib_chunk->kdata[idx] >> 3) & 0x7;
|
||||
tmp = (idx_value >> 3) & 0x7;
|
||||
if (tmp == 2 || tmp == 4 || tmp == 6) {
|
||||
track->textures[i].roundup_h = false;
|
||||
}
|
||||
|
@ -1021,12 +1022,12 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
case 0x453C:
|
||||
/* TX_FORMAT2_[0-15] */
|
||||
i = (reg - 0x4500) >> 2;
|
||||
tmp = ib_chunk->kdata[idx] & 0x3FFF;
|
||||
tmp = idx_value & 0x3FFF;
|
||||
track->textures[i].pitch = tmp + 1;
|
||||
if (p->rdev->family >= CHIP_RV515) {
|
||||
tmp = ((ib_chunk->kdata[idx] >> 15) & 1) << 11;
|
||||
tmp = ((idx_value >> 15) & 1) << 11;
|
||||
track->textures[i].width_11 = tmp;
|
||||
tmp = ((ib_chunk->kdata[idx] >> 16) & 1) << 11;
|
||||
tmp = ((idx_value >> 16) & 1) << 11;
|
||||
track->textures[i].height_11 = tmp;
|
||||
}
|
||||
break;
|
||||
|
@ -1048,15 +1049,15 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
case 0x44BC:
|
||||
/* TX_FORMAT0_[0-15] */
|
||||
i = (reg - 0x4480) >> 2;
|
||||
tmp = ib_chunk->kdata[idx] & 0x7FF;
|
||||
tmp = idx_value & 0x7FF;
|
||||
track->textures[i].width = tmp + 1;
|
||||
tmp = (ib_chunk->kdata[idx] >> 11) & 0x7FF;
|
||||
tmp = (idx_value >> 11) & 0x7FF;
|
||||
track->textures[i].height = tmp + 1;
|
||||
tmp = (ib_chunk->kdata[idx] >> 26) & 0xF;
|
||||
tmp = (idx_value >> 26) & 0xF;
|
||||
track->textures[i].num_levels = tmp;
|
||||
tmp = ib_chunk->kdata[idx] & (1 << 31);
|
||||
tmp = idx_value & (1 << 31);
|
||||
track->textures[i].use_pitch = !!tmp;
|
||||
tmp = (ib_chunk->kdata[idx] >> 22) & 0xF;
|
||||
tmp = (idx_value >> 22) & 0xF;
|
||||
track->textures[i].txdepth = tmp;
|
||||
break;
|
||||
case R300_ZB_ZPASS_ADDR:
|
||||
|
@ -1067,7 +1068,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset);
|
||||
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
|
||||
break;
|
||||
case 0x4be8:
|
||||
/* valid register only on RV530 */
|
||||
|
@ -1085,60 +1086,20 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
|
|||
static int r300_packet3_check(struct radeon_cs_parser *p,
|
||||
struct radeon_cs_packet *pkt)
|
||||
{
|
||||
struct radeon_cs_chunk *ib_chunk;
|
||||
|
||||
struct radeon_cs_reloc *reloc;
|
||||
struct r100_cs_track *track;
|
||||
volatile uint32_t *ib;
|
||||
unsigned idx;
|
||||
unsigned i, c;
|
||||
int r;
|
||||
|
||||
ib = p->ib->ptr;
|
||||
ib_chunk = &p->chunks[p->chunk_ib_idx];
|
||||
idx = pkt->idx + 1;
|
||||
track = (struct r100_cs_track *)p->track;
|
||||
switch(pkt->opcode) {
|
||||
case PACKET3_3D_LOAD_VBPNTR:
|
||||
c = ib_chunk->kdata[idx++] & 0x1F;
|
||||
track->num_arrays = c;
|
||||
for (i = 0; i < (c - 1); i+=2, idx+=3) {
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
DRM_ERROR("No reloc for packet3 %d\n",
|
||||
pkt->opcode);
|
||||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset);
|
||||
track->arrays[i + 0].robj = reloc->robj;
|
||||
track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8;
|
||||
track->arrays[i + 0].esize &= 0x7F;
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
DRM_ERROR("No reloc for packet3 %d\n",
|
||||
pkt->opcode);
|
||||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
ib[idx+2] = ib_chunk->kdata[idx+2] + ((u32)reloc->lobj.gpu_offset);
|
||||
track->arrays[i + 1].robj = reloc->robj;
|
||||
track->arrays[i + 1].esize = ib_chunk->kdata[idx] >> 24;
|
||||
track->arrays[i + 1].esize &= 0x7F;
|
||||
}
|
||||
if (c & 1) {
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
DRM_ERROR("No reloc for packet3 %d\n",
|
||||
pkt->opcode);
|
||||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset);
|
||||
track->arrays[i + 0].robj = reloc->robj;
|
||||
track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8;
|
||||
track->arrays[i + 0].esize &= 0x7F;
|
||||
}
|
||||
r = r100_packet3_load_vbpntr(p, pkt, idx);
|
||||
if (r)
|
||||
return r;
|
||||
break;
|
||||
case PACKET3_INDX_BUFFER:
|
||||
r = r100_cs_packet_next_reloc(p, &reloc);
|
||||
|
@ -1147,7 +1108,7 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
|
|||
r100_cs_dump_packet(p, pkt);
|
||||
return r;
|
||||
}
|
||||
ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset);
|
||||
ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset);
|
||||
r = r100_cs_track_check_pkt3_indx_buffer(p, pkt, reloc->robj);
|
||||
if (r) {
|
||||
return r;
|
||||
|
@ -1158,11 +1119,11 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
|
|||
/* Number of dwords is vtx_size * (num_vertices - 1)
|
||||
* PRIM_WALK must be equal to 3 vertex data in embedded
|
||||
* in cmd stream */
|
||||
if (((ib_chunk->kdata[idx+1] >> 4) & 0x3) != 3) {
|
||||
if (((radeon_get_ib_value(p, idx + 1) >> 4) & 0x3) != 3) {
|
||||
DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
track->vap_vf_cntl = ib_chunk->kdata[idx+1];
|
||||
track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1);
|
||||
track->immd_dwords = pkt->count - 1;
|
||||
r = r100_cs_track_check(p->rdev, track);
|
||||
if (r) {
|
||||
|
@ -1173,11 +1134,11 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
|
|||
/* Number of dwords is vtx_size * (num_vertices - 1)
|
||||
* PRIM_WALK must be equal to 3 vertex data in embedded
|
||||
* in cmd stream */
|
||||
if (((ib_chunk->kdata[idx] >> 4) & 0x3) != 3) {
|
||||
if (((radeon_get_ib_value(p, idx) >> 4) & 0x3) != 3) {
|
||||
DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
track->vap_vf_cntl = ib_chunk->kdata[idx];
|
||||
track->vap_vf_cntl = radeon_get_ib_value(p, idx);
|
||||
track->immd_dwords = pkt->count;
|
||||
r = r100_cs_track_check(p->rdev, track);
|
||||
if (r) {
|
||||
|
@ -1185,28 +1146,28 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
|
|||
}
|
||||
break;
|
||||
case PACKET3_3D_DRAW_VBUF:
|
||||
track->vap_vf_cntl = ib_chunk->kdata[idx + 1];
|
||||
track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1);
|
||||
r = r100_cs_track_check(p->rdev, track);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
break;
|
||||
case PACKET3_3D_DRAW_VBUF_2:
|
||||
track->vap_vf_cntl = ib_chunk->kdata[idx];
|
||||
track->vap_vf_cntl = radeon_get_ib_value(p, idx);
|
||||
r = r100_cs_track_check(p->rdev, track);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
break;
|
||||
case PACKET3_3D_DRAW_INDX:
|
||||
track->vap_vf_cntl = ib_chunk->kdata[idx + 1];
|
||||
track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1);
|
||||
r = r100_cs_track_check(p->rdev, track);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
break;
|
||||
case PACKET3_3D_DRAW_INDX_2:
|
||||
track->vap_vf_cntl = ib_chunk->kdata[idx];
|
||||
track->vap_vf_cntl = radeon_get_ib_value(p, idx);
|
||||
r = r100_cs_track_check(p->rdev, track);
|
||||
if (r) {
|
||||
return r;
|
||||
|
|
|
@ -445,6 +445,8 @@
|
|||
#define AVIVO_D1MODE_VBLANK_STATUS 0x6534
|
||||
# define AVIVO_VBLANK_ACK (1 << 4)
|
||||
#define AVIVO_D1MODE_VLINE_START_END 0x6538
|
||||
#define AVIVO_D1MODE_VLINE_STATUS 0x653c
|
||||
# define AVIVO_D1MODE_VLINE_STAT (1 << 12)
|
||||
#define AVIVO_DxMODE_INT_MASK 0x6540
|
||||
# define AVIVO_D1MODE_INT_MASK (1 << 0)
|
||||
# define AVIVO_D2MODE_INT_MASK (1 << 8)
|
||||
|
@ -502,6 +504,7 @@
|
|||
|
||||
#define AVIVO_D2MODE_VBLANK_STATUS 0x6d34
|
||||
#define AVIVO_D2MODE_VLINE_START_END 0x6d38
|
||||
#define AVIVO_D2MODE_VLINE_STATUS 0x6d3c
|
||||
#define AVIVO_D2MODE_VIEWPORT_START 0x6d80
|
||||
#define AVIVO_D2MODE_VIEWPORT_SIZE 0x6d84
|
||||
#define AVIVO_D2MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6d88
|
||||
|
|
|
@ -26,108 +26,13 @@
|
|||
* Jerome Glisse
|
||||
*/
|
||||
#include "drmP.h"
|
||||
#include "radeon_reg.h"
|
||||
#include "radeon.h"
|
||||
#include "atom.h"
|
||||
#include "r520d.h"
|
||||
|
||||
/* r520,rv530,rv560,rv570,r580 depends on : */
|
||||
void r100_hdp_reset(struct radeon_device *rdev);
|
||||
void r420_pipes_init(struct radeon_device *rdev);
|
||||
void rs600_mc_disable_clients(struct radeon_device *rdev);
|
||||
void rs600_disable_vga(struct radeon_device *rdev);
|
||||
int rv515_debugfs_pipes_info_init(struct radeon_device *rdev);
|
||||
int rv515_debugfs_ga_info_init(struct radeon_device *rdev);
|
||||
/* This files gather functions specifics to: r520,rv530,rv560,rv570,r580 */
|
||||
|
||||
/* This files gather functions specifics to:
|
||||
* r520,rv530,rv560,rv570,r580
|
||||
*
|
||||
* Some of these functions might be used by newer ASICs.
|
||||
*/
|
||||
void r520_gpu_init(struct radeon_device *rdev);
|
||||
int r520_mc_wait_for_idle(struct radeon_device *rdev);
|
||||
|
||||
|
||||
/*
|
||||
* MC
|
||||
*/
|
||||
int r520_mc_init(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
int r;
|
||||
|
||||
if (r100_debugfs_rbbm_init(rdev)) {
|
||||
DRM_ERROR("Failed to register debugfs file for RBBM !\n");
|
||||
}
|
||||
if (rv515_debugfs_pipes_info_init(rdev)) {
|
||||
DRM_ERROR("Failed to register debugfs file for pipes !\n");
|
||||
}
|
||||
if (rv515_debugfs_ga_info_init(rdev)) {
|
||||
DRM_ERROR("Failed to register debugfs file for pipes !\n");
|
||||
}
|
||||
|
||||
r520_gpu_init(rdev);
|
||||
rv370_pcie_gart_disable(rdev);
|
||||
|
||||
/* Setup GPU memory space */
|
||||
rdev->mc.vram_location = 0xFFFFFFFFUL;
|
||||
rdev->mc.gtt_location = 0xFFFFFFFFUL;
|
||||
if (rdev->flags & RADEON_IS_AGP) {
|
||||
r = radeon_agp_init(rdev);
|
||||
if (r) {
|
||||
printk(KERN_WARNING "[drm] Disabling AGP\n");
|
||||
rdev->flags &= ~RADEON_IS_AGP;
|
||||
rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
|
||||
} else {
|
||||
rdev->mc.gtt_location = rdev->mc.agp_base;
|
||||
}
|
||||
}
|
||||
r = radeon_mc_setup(rdev);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Program GPU memory space */
|
||||
rs600_mc_disable_clients(rdev);
|
||||
if (r520_mc_wait_for_idle(rdev)) {
|
||||
printk(KERN_WARNING "Failed to wait MC idle while "
|
||||
"programming pipes. Bad things might happen.\n");
|
||||
}
|
||||
/* Write VRAM size in case we are limiting it */
|
||||
WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
|
||||
tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
|
||||
tmp = REG_SET(R520_MC_FB_TOP, tmp >> 16);
|
||||
tmp |= REG_SET(R520_MC_FB_START, rdev->mc.vram_location >> 16);
|
||||
WREG32_MC(R520_MC_FB_LOCATION, tmp);
|
||||
WREG32(RS690_HDP_FB_LOCATION, rdev->mc.vram_location >> 16);
|
||||
WREG32(0x310, rdev->mc.vram_location);
|
||||
if (rdev->flags & RADEON_IS_AGP) {
|
||||
tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
|
||||
tmp = REG_SET(R520_MC_AGP_TOP, tmp >> 16);
|
||||
tmp |= REG_SET(R520_MC_AGP_START, rdev->mc.gtt_location >> 16);
|
||||
WREG32_MC(R520_MC_AGP_LOCATION, tmp);
|
||||
WREG32_MC(R520_MC_AGP_BASE, rdev->mc.agp_base);
|
||||
WREG32_MC(R520_MC_AGP_BASE_2, 0);
|
||||
} else {
|
||||
WREG32_MC(R520_MC_AGP_LOCATION, 0x0FFFFFFF);
|
||||
WREG32_MC(R520_MC_AGP_BASE, 0);
|
||||
WREG32_MC(R520_MC_AGP_BASE_2, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void r520_mc_fini(struct radeon_device *rdev)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Global GPU functions
|
||||
*/
|
||||
void r520_errata(struct radeon_device *rdev)
|
||||
{
|
||||
rdev->pll_errata = 0;
|
||||
}
|
||||
|
||||
int r520_mc_wait_for_idle(struct radeon_device *rdev)
|
||||
static int r520_mc_wait_for_idle(struct radeon_device *rdev)
|
||||
{
|
||||
unsigned i;
|
||||
uint32_t tmp;
|
||||
|
@ -143,12 +48,12 @@ int r520_mc_wait_for_idle(struct radeon_device *rdev)
|
|||
return -1;
|
||||
}
|
||||
|
||||
void r520_gpu_init(struct radeon_device *rdev)
|
||||
static void r520_gpu_init(struct radeon_device *rdev)
|
||||
{
|
||||
unsigned pipe_select_current, gb_pipe_select, tmp;
|
||||
|
||||
r100_hdp_reset(rdev);
|
||||
rs600_disable_vga(rdev);
|
||||
rv515_vga_render_disable(rdev);
|
||||
/*
|
||||
* DST_PIPE_CONFIG 0x170C
|
||||
* GB_TILE_CONFIG 0x4018
|
||||
|
@ -186,10 +91,6 @@ void r520_gpu_init(struct radeon_device *rdev)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* VRAM info
|
||||
*/
|
||||
static void r520_vram_get_type(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
@ -233,7 +134,168 @@ void r520_vram_info(struct radeon_device *rdev)
|
|||
rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
|
||||
}
|
||||
|
||||
void r520_bandwidth_update(struct radeon_device *rdev)
|
||||
void r520_mc_program(struct radeon_device *rdev)
|
||||
{
|
||||
rv515_bandwidth_avivo_update(rdev);
|
||||
struct rv515_mc_save save;
|
||||
|
||||
/* Stops all mc clients */
|
||||
rv515_mc_stop(rdev, &save);
|
||||
|
||||
/* Wait for mc idle */
|
||||
if (r520_mc_wait_for_idle(rdev))
|
||||
dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
|
||||
/* Write VRAM size in case we are limiting it */
|
||||
WREG32(R_0000F8_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
|
||||
/* Program MC, should be a 32bits limited address space */
|
||||
WREG32_MC(R_000004_MC_FB_LOCATION,
|
||||
S_000004_MC_FB_START(rdev->mc.vram_start >> 16) |
|
||||
S_000004_MC_FB_TOP(rdev->mc.vram_end >> 16));
|
||||
WREG32(R_000134_HDP_FB_LOCATION,
|
||||
S_000134_HDP_FB_START(rdev->mc.vram_start >> 16));
|
||||
if (rdev->flags & RADEON_IS_AGP) {
|
||||
WREG32_MC(R_000005_MC_AGP_LOCATION,
|
||||
S_000005_MC_AGP_START(rdev->mc.gtt_start >> 16) |
|
||||
S_000005_MC_AGP_TOP(rdev->mc.gtt_end >> 16));
|
||||
WREG32_MC(R_000006_AGP_BASE, lower_32_bits(rdev->mc.agp_base));
|
||||
WREG32_MC(R_000007_AGP_BASE_2,
|
||||
S_000007_AGP_BASE_ADDR_2(upper_32_bits(rdev->mc.agp_base)));
|
||||
} else {
|
||||
WREG32_MC(R_000005_MC_AGP_LOCATION, 0xFFFFFFFF);
|
||||
WREG32_MC(R_000006_AGP_BASE, 0);
|
||||
WREG32_MC(R_000007_AGP_BASE_2, 0);
|
||||
}
|
||||
|
||||
rv515_mc_resume(rdev, &save);
|
||||
}
|
||||
|
||||
static int r520_startup(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
r520_mc_program(rdev);
|
||||
/* Resume clock */
|
||||
rv515_clock_startup(rdev);
|
||||
/* Initialize GPU configuration (# pipes, ...) */
|
||||
r520_gpu_init(rdev);
|
||||
/* Initialize GART (initialize after TTM so we can allocate
|
||||
* memory through TTM but finalize after TTM) */
|
||||
if (rdev->flags & RADEON_IS_PCIE) {
|
||||
r = rv370_pcie_gart_enable(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
r100_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
if (r) {
|
||||
dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
r = r100_wb_init(rdev);
|
||||
if (r)
|
||||
dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
|
||||
r = r100_ib_init(rdev);
|
||||
if (r) {
|
||||
dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int r520_resume(struct radeon_device *rdev)
|
||||
{
|
||||
/* Make sur GART are not working */
|
||||
if (rdev->flags & RADEON_IS_PCIE)
|
||||
rv370_pcie_gart_disable(rdev);
|
||||
/* Resume clock before doing reset */
|
||||
rv515_clock_startup(rdev);
|
||||
/* Reset gpu before posting otherwise ATOM will enter infinite loop */
|
||||
if (radeon_gpu_reset(rdev)) {
|
||||
dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
|
||||
RREG32(R_000E40_RBBM_STATUS),
|
||||
RREG32(R_0007C0_CP_STAT));
|
||||
}
|
||||
/* post */
|
||||
atom_asic_init(rdev->mode_info.atom_context);
|
||||
/* Resume clock after posting */
|
||||
rv515_clock_startup(rdev);
|
||||
return r520_startup(rdev);
|
||||
}
|
||||
|
||||
int r520_init(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
rdev->new_init_path = true;
|
||||
/* Initialize scratch registers */
|
||||
radeon_scratch_init(rdev);
|
||||
/* Initialize surface registers */
|
||||
radeon_surface_init(rdev);
|
||||
/* TODO: disable VGA need to use VGA request */
|
||||
/* BIOS*/
|
||||
if (!radeon_get_bios(rdev)) {
|
||||
if (ASIC_IS_AVIVO(rdev))
|
||||
return -EINVAL;
|
||||
}
|
||||
if (rdev->is_atom_bios) {
|
||||
r = radeon_atombios_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
} else {
|
||||
dev_err(rdev->dev, "Expecting atombios for RV515 GPU\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Reset gpu before posting otherwise ATOM will enter infinite loop */
|
||||
if (radeon_gpu_reset(rdev)) {
|
||||
dev_warn(rdev->dev,
|
||||
"GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
|
||||
RREG32(R_000E40_RBBM_STATUS),
|
||||
RREG32(R_0007C0_CP_STAT));
|
||||
}
|
||||
/* check if cards are posted or not */
|
||||
if (!radeon_card_posted(rdev) && rdev->bios) {
|
||||
DRM_INFO("GPU not posted. posting now...\n");
|
||||
atom_asic_init(rdev->mode_info.atom_context);
|
||||
}
|
||||
/* Initialize clocks */
|
||||
radeon_get_clock_info(rdev->ddev);
|
||||
/* Get vram informations */
|
||||
r520_vram_info(rdev);
|
||||
/* Initialize memory controller (also test AGP) */
|
||||
r = r420_mc_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
rv515_debugfs(rdev);
|
||||
/* Fence driver */
|
||||
r = radeon_fence_driver_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
r = radeon_irq_kms_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
/* Memory manager */
|
||||
r = radeon_object_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
r = rv370_pcie_gart_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
rv515_set_safe_registers(rdev);
|
||||
rdev->accel_working = true;
|
||||
r = r520_startup(rdev);
|
||||
if (r) {
|
||||
/* Somethings want wront with the accel init stop accel */
|
||||
dev_err(rdev->dev, "Disabling GPU acceleration\n");
|
||||
rv515_suspend(rdev);
|
||||
r100_cp_fini(rdev);
|
||||
r100_wb_fini(rdev);
|
||||
r100_ib_fini(rdev);
|
||||
rv370_pcie_gart_fini(rdev);
|
||||
radeon_agp_fini(rdev);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
rdev->accel_working = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
* Copyright 2008 Advanced Micro Devices, Inc.
|
||||
* Copyright 2008 Red Hat Inc.
|
||||
* Copyright 2009 Jerome Glisse.
|
||||
*
|
||||
* 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: Dave Airlie
|
||||
* Alex Deucher
|
||||
* Jerome Glisse
|
||||
*/
|
||||
#ifndef __R520D_H__
|
||||
#define __R520D_H__
|
||||
|
||||
/* Registers */
|
||||
#define R_0000F8_CONFIG_MEMSIZE 0x0000F8
|
||||
#define S_0000F8_CONFIG_MEMSIZE(x) (((x) & 0xFFFFFFFF) << 0)
|
||||
#define G_0000F8_CONFIG_MEMSIZE(x) (((x) >> 0) & 0xFFFFFFFF)
|
||||
#define C_0000F8_CONFIG_MEMSIZE 0x00000000
|
||||
#define R_000134_HDP_FB_LOCATION 0x000134
|
||||
#define S_000134_HDP_FB_START(x) (((x) & 0xFFFF) << 0)
|
||||
#define G_000134_HDP_FB_START(x) (((x) >> 0) & 0xFFFF)
|
||||
#define C_000134_HDP_FB_START 0xFFFF0000
|
||||
#define R_0007C0_CP_STAT 0x0007C0
|
||||
#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0)
|
||||
#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1)
|
||||
#define C_0007C0_MRU_BUSY 0xFFFFFFFE
|
||||
#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1)
|
||||
#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1)
|
||||
#define C_0007C0_MWU_BUSY 0xFFFFFFFD
|
||||
#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2)
|
||||
#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1)
|
||||
#define C_0007C0_RSIU_BUSY 0xFFFFFFFB
|
||||
#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3)
|
||||
#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1)
|
||||
#define C_0007C0_RCIU_BUSY 0xFFFFFFF7
|
||||
#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9)
|
||||
#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1)
|
||||
#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF
|
||||
#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10)
|
||||
#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1)
|
||||
#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF
|
||||
#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11)
|
||||
#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1)
|
||||
#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF
|
||||
#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12)
|
||||
#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1)
|
||||
#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF
|
||||
#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13)
|
||||
#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1)
|
||||
#define C_0007C0_CSI_BUSY 0xFFFFDFFF
|
||||
#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14)
|
||||
#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1)
|
||||
#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF
|
||||
#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15)
|
||||
#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1)
|
||||
#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF
|
||||
#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28)
|
||||
#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1)
|
||||
#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF
|
||||
#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29)
|
||||
#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1)
|
||||
#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF
|
||||
#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30)
|
||||
#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1)
|
||||
#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF
|
||||
#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31)
|
||||
#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1)
|
||||
#define C_0007C0_CP_BUSY 0x7FFFFFFF
|
||||
#define R_000E40_RBBM_STATUS 0x000E40
|
||||
#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0)
|
||||
#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F)
|
||||
#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80
|
||||
#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8)
|
||||
#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1)
|
||||
#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF
|
||||
#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9)
|
||||
#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1)
|
||||
#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF
|
||||
#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10)
|
||||
#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1)
|
||||
#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF
|
||||
#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11)
|
||||
#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1)
|
||||
#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF
|
||||
#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12)
|
||||
#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1)
|
||||
#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF
|
||||
#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13)
|
||||
#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1)
|
||||
#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF
|
||||
#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14)
|
||||
#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1)
|
||||
#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF
|
||||
#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15)
|
||||
#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1)
|
||||
#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF
|
||||
#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16)
|
||||
#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1)
|
||||
#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF
|
||||
#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17)
|
||||
#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1)
|
||||
#define C_000E40_E2_BUSY 0xFFFDFFFF
|
||||
#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18)
|
||||
#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1)
|
||||
#define C_000E40_RB2D_BUSY 0xFFFBFFFF
|
||||
#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19)
|
||||
#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1)
|
||||
#define C_000E40_RB3D_BUSY 0xFFF7FFFF
|
||||
#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20)
|
||||
#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1)
|
||||
#define C_000E40_VAP_BUSY 0xFFEFFFFF
|
||||
#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21)
|
||||
#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1)
|
||||
#define C_000E40_RE_BUSY 0xFFDFFFFF
|
||||
#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22)
|
||||
#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1)
|
||||
#define C_000E40_TAM_BUSY 0xFFBFFFFF
|
||||
#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23)
|
||||
#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1)
|
||||
#define C_000E40_TDM_BUSY 0xFF7FFFFF
|
||||
#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24)
|
||||
#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1)
|
||||
#define C_000E40_PB_BUSY 0xFEFFFFFF
|
||||
#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25)
|
||||
#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1)
|
||||
#define C_000E40_TIM_BUSY 0xFDFFFFFF
|
||||
#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26)
|
||||
#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1)
|
||||
#define C_000E40_GA_BUSY 0xFBFFFFFF
|
||||
#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27)
|
||||
#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1)
|
||||
#define C_000E40_CBA2D_BUSY 0xF7FFFFFF
|
||||
#define S_000E40_RBBM_HIBUSY(x) (((x) & 0x1) << 28)
|
||||
#define G_000E40_RBBM_HIBUSY(x) (((x) >> 28) & 0x1)
|
||||
#define C_000E40_RBBM_HIBUSY 0xEFFFFFFF
|
||||
#define S_000E40_SKID_CFBUSY(x) (((x) & 0x1) << 29)
|
||||
#define G_000E40_SKID_CFBUSY(x) (((x) >> 29) & 0x1)
|
||||
#define C_000E40_SKID_CFBUSY 0xDFFFFFFF
|
||||
#define S_000E40_VAP_VF_BUSY(x) (((x) & 0x1) << 30)
|
||||
#define G_000E40_VAP_VF_BUSY(x) (((x) >> 30) & 0x1)
|
||||
#define C_000E40_VAP_VF_BUSY 0xBFFFFFFF
|
||||
#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31)
|
||||
#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1)
|
||||
#define C_000E40_GUI_ACTIVE 0x7FFFFFFF
|
||||
|
||||
|
||||
#define R_000004_MC_FB_LOCATION 0x000004
|
||||
#define S_000004_MC_FB_START(x) (((x) & 0xFFFF) << 0)
|
||||
#define G_000004_MC_FB_START(x) (((x) >> 0) & 0xFFFF)
|
||||
#define C_000004_MC_FB_START 0xFFFF0000
|
||||
#define S_000004_MC_FB_TOP(x) (((x) & 0xFFFF) << 16)
|
||||
#define G_000004_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF)
|
||||
#define C_000004_MC_FB_TOP 0x0000FFFF
|
||||
#define R_000005_MC_AGP_LOCATION 0x000005
|
||||
#define S_000005_MC_AGP_START(x) (((x) & 0xFFFF) << 0)
|
||||
#define G_000005_MC_AGP_START(x) (((x) >> 0) & 0xFFFF)
|
||||
#define C_000005_MC_AGP_START 0xFFFF0000
|
||||
#define S_000005_MC_AGP_TOP(x) (((x) & 0xFFFF) << 16)
|
||||
#define G_000005_MC_AGP_TOP(x) (((x) >> 16) & 0xFFFF)
|
||||
#define C_000005_MC_AGP_TOP 0x0000FFFF
|
||||
#define R_000006_AGP_BASE 0x000006
|
||||
#define S_000006_AGP_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
|
||||
#define G_000006_AGP_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
|
||||
#define C_000006_AGP_BASE_ADDR 0x00000000
|
||||
#define R_000007_AGP_BASE_2 0x000007
|
||||
#define S_000007_AGP_BASE_ADDR_2(x) (((x) & 0xF) << 0)
|
||||
#define G_000007_AGP_BASE_ADDR_2(x) (((x) >> 0) & 0xF)
|
||||
#define C_000007_AGP_BASE_ADDR_2 0xFFFFFFF0
|
||||
|
||||
#endif
|
|
@ -33,8 +33,8 @@
|
|||
#include "radeon.h"
|
||||
#include "radeon_mode.h"
|
||||
#include "r600d.h"
|
||||
#include "avivod.h"
|
||||
#include "atom.h"
|
||||
#include "avivod.h"
|
||||
|
||||
#define PFP_UCODE_SIZE 576
|
||||
#define PM4_UCODE_SIZE 1792
|
||||
|
@ -342,7 +342,7 @@ static void r600_mc_resume(struct radeon_device *rdev)
|
|||
|
||||
/* we need to own VRAM, so turn off the VGA renderer here
|
||||
* to stop it overwriting our objects */
|
||||
radeon_avivo_vga_render_disable(rdev);
|
||||
rv515_vga_render_disable(rdev);
|
||||
}
|
||||
|
||||
int r600_mc_init(struct radeon_device *rdev)
|
||||
|
@ -380,6 +380,13 @@ int r600_mc_init(struct radeon_device *rdev)
|
|||
/* Setup GPU memory space */
|
||||
rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
|
||||
rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
|
||||
|
||||
if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
|
||||
rdev->mc.mc_vram_size = rdev->mc.aper_size;
|
||||
|
||||
if (rdev->mc.real_vram_size > rdev->mc.aper_size)
|
||||
rdev->mc.real_vram_size = rdev->mc.aper_size;
|
||||
|
||||
if (rdev->flags & RADEON_IS_AGP) {
|
||||
r = radeon_agp_init(rdev);
|
||||
if (r)
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "drmP.h"
|
||||
#include "radeon.h"
|
||||
#include "r600d.h"
|
||||
#include "avivod.h"
|
||||
|
||||
static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p,
|
||||
struct radeon_cs_reloc **cs_reloc);
|
||||
|
@ -57,7 +56,7 @@ int r600_cs_packet_parse(struct radeon_cs_parser *p,
|
|||
idx, ib_chunk->length_dw);
|
||||
return -EINVAL;
|
||||
}
|
||||
header = ib_chunk->kdata[idx];
|
||||
header = radeon_get_ib_value(p, idx);
|
||||
pkt->idx = idx;
|
||||
pkt->type = CP_PACKET_GET_TYPE(header);
|
||||
pkt->count = CP_PACKET_GET_COUNT(header);
|
||||
|
@ -98,7 +97,6 @@ int r600_cs_packet_parse(struct radeon_cs_parser *p,
|
|||
static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p,
|
||||
struct radeon_cs_reloc **cs_reloc)
|
||||
{
|
||||
struct radeon_cs_chunk *ib_chunk;
|
||||
struct radeon_cs_chunk *relocs_chunk;
|
||||
struct radeon_cs_packet p3reloc;
|
||||
unsigned idx;
|
||||
|
@ -109,7 +107,6 @@ static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p,
|
|||
return -EINVAL;
|
||||
}
|
||||
*cs_reloc = NULL;
|
||||
ib_chunk = &p->chunks[p->chunk_ib_idx];
|
||||
relocs_chunk = &p->chunks[p->chunk_relocs_idx];
|
||||
r = r600_cs_packet_parse(p, &p3reloc, p->idx);
|
||||
if (r) {
|
||||
|
@ -121,7 +118,7 @@ static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p,
|
|||
p3reloc.idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
idx = ib_chunk->kdata[p3reloc.idx + 1];
|
||||
idx = radeon_get_ib_value(p, p3reloc.idx + 1);
|
||||
if (idx >= relocs_chunk->length_dw) {
|
||||
DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
|
||||
idx, relocs_chunk->length_dw);
|
||||
|
@ -146,7 +143,6 @@ static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p,
|
|||
static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p,
|
||||
struct radeon_cs_reloc **cs_reloc)
|
||||
{
|
||||
struct radeon_cs_chunk *ib_chunk;
|
||||
struct radeon_cs_chunk *relocs_chunk;
|
||||
struct radeon_cs_packet p3reloc;
|
||||
unsigned idx;
|
||||
|
@ -157,7 +153,6 @@ static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p,
|
|||
return -EINVAL;
|
||||
}
|
||||
*cs_reloc = NULL;
|
||||
ib_chunk = &p->chunks[p->chunk_ib_idx];
|
||||
relocs_chunk = &p->chunks[p->chunk_relocs_idx];
|
||||
r = r600_cs_packet_parse(p, &p3reloc, p->idx);
|
||||
if (r) {
|
||||
|
@ -169,7 +164,7 @@ static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p,
|
|||
p3reloc.idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
idx = ib_chunk->kdata[p3reloc.idx + 1];
|
||||
idx = radeon_get_ib_value(p, p3reloc.idx + 1);
|
||||
if (idx >= relocs_chunk->length_dw) {
|
||||
DRM_ERROR("Relocs at %d after relocations chunk end %d !\n",
|
||||
idx, relocs_chunk->length_dw);
|
||||
|
@ -181,13 +176,136 @@ static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* r600_cs_packet_next_vline() - parse userspace VLINE packet
|
||||
* @parser: parser structure holding parsing context.
|
||||
*
|
||||
* Userspace sends a special sequence for VLINE waits.
|
||||
* PACKET0 - VLINE_START_END + value
|
||||
* PACKET3 - WAIT_REG_MEM poll vline status reg
|
||||
* RELOC (P3) - crtc_id in reloc.
|
||||
*
|
||||
* This function parses this and relocates the VLINE START END
|
||||
* and WAIT_REG_MEM packets to the correct crtc.
|
||||
* It also detects a switched off crtc and nulls out the
|
||||
* wait in that case.
|
||||
*/
|
||||
static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p)
|
||||
{
|
||||
struct drm_mode_object *obj;
|
||||
struct drm_crtc *crtc;
|
||||
struct radeon_crtc *radeon_crtc;
|
||||
struct radeon_cs_packet p3reloc, wait_reg_mem;
|
||||
int crtc_id;
|
||||
int r;
|
||||
uint32_t header, h_idx, reg, wait_reg_mem_info;
|
||||
volatile uint32_t *ib;
|
||||
|
||||
ib = p->ib->ptr;
|
||||
|
||||
/* parse the WAIT_REG_MEM */
|
||||
r = r600_cs_packet_parse(p, &wait_reg_mem, p->idx);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* check its a WAIT_REG_MEM */
|
||||
if (wait_reg_mem.type != PACKET_TYPE3 ||
|
||||
wait_reg_mem.opcode != PACKET3_WAIT_REG_MEM) {
|
||||
DRM_ERROR("vline wait missing WAIT_REG_MEM segment\n");
|
||||
r = -EINVAL;
|
||||
return r;
|
||||
}
|
||||
|
||||
wait_reg_mem_info = radeon_get_ib_value(p, wait_reg_mem.idx + 1);
|
||||
/* bit 4 is reg (0) or mem (1) */
|
||||
if (wait_reg_mem_info & 0x10) {
|
||||
DRM_ERROR("vline WAIT_REG_MEM waiting on MEM rather than REG\n");
|
||||
r = -EINVAL;
|
||||
return r;
|
||||
}
|
||||
/* waiting for value to be equal */
|
||||
if ((wait_reg_mem_info & 0x7) != 0x3) {
|
||||
DRM_ERROR("vline WAIT_REG_MEM function not equal\n");
|
||||
r = -EINVAL;
|
||||
return r;
|
||||
}
|
||||
if ((radeon_get_ib_value(p, wait_reg_mem.idx + 2) << 2) != AVIVO_D1MODE_VLINE_STATUS) {
|
||||
DRM_ERROR("vline WAIT_REG_MEM bad reg\n");
|
||||
r = -EINVAL;
|
||||
return r;
|
||||
}
|
||||
|
||||
if (radeon_get_ib_value(p, wait_reg_mem.idx + 5) != AVIVO_D1MODE_VLINE_STAT) {
|
||||
DRM_ERROR("vline WAIT_REG_MEM bad bit mask\n");
|
||||
r = -EINVAL;
|
||||
return r;
|
||||
}
|
||||
|
||||
/* jump over the NOP */
|
||||
r = r600_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
h_idx = p->idx - 2;
|
||||
p->idx += wait_reg_mem.count + 2;
|
||||
p->idx += p3reloc.count + 2;
|
||||
|
||||
header = radeon_get_ib_value(p, h_idx);
|
||||
crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1);
|
||||
reg = header >> 2;
|
||||
mutex_lock(&p->rdev->ddev->mode_config.mutex);
|
||||
obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC);
|
||||
if (!obj) {
|
||||
DRM_ERROR("cannot find crtc %d\n", crtc_id);
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
crtc = obj_to_crtc(obj);
|
||||
radeon_crtc = to_radeon_crtc(crtc);
|
||||
crtc_id = radeon_crtc->crtc_id;
|
||||
|
||||
if (!crtc->enabled) {
|
||||
/* if the CRTC isn't enabled - we need to nop out the WAIT_REG_MEM */
|
||||
ib[h_idx + 2] = PACKET2(0);
|
||||
ib[h_idx + 3] = PACKET2(0);
|
||||
ib[h_idx + 4] = PACKET2(0);
|
||||
ib[h_idx + 5] = PACKET2(0);
|
||||
ib[h_idx + 6] = PACKET2(0);
|
||||
ib[h_idx + 7] = PACKET2(0);
|
||||
ib[h_idx + 8] = PACKET2(0);
|
||||
} else if (crtc_id == 1) {
|
||||
switch (reg) {
|
||||
case AVIVO_D1MODE_VLINE_START_END:
|
||||
header &= ~R600_CP_PACKET0_REG_MASK;
|
||||
header |= AVIVO_D2MODE_VLINE_START_END >> 2;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("unknown crtc reloc\n");
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
ib[h_idx] = header;
|
||||
ib[h_idx + 4] = AVIVO_D2MODE_VLINE_STATUS >> 2;
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&p->rdev->ddev->mode_config.mutex);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int r600_packet0_check(struct radeon_cs_parser *p,
|
||||
struct radeon_cs_packet *pkt,
|
||||
unsigned idx, unsigned reg)
|
||||
{
|
||||
int r;
|
||||
|
||||
switch (reg) {
|
||||
case AVIVO_D1MODE_VLINE_START_END:
|
||||
case AVIVO_D2MODE_VLINE_START_END:
|
||||
r = r600_cs_packet_parse_vline(p);
|
||||
if (r) {
|
||||
DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
|
||||
idx, reg);
|
||||
return r;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n",
|
||||
|
@ -218,17 +336,18 @@ static int r600_cs_parse_packet0(struct radeon_cs_parser *p,
|
|||
static int r600_packet3_check(struct radeon_cs_parser *p,
|
||||
struct radeon_cs_packet *pkt)
|
||||
{
|
||||
struct radeon_cs_chunk *ib_chunk;
|
||||
struct radeon_cs_reloc *reloc;
|
||||
volatile u32 *ib;
|
||||
unsigned idx;
|
||||
unsigned i;
|
||||
unsigned start_reg, end_reg, reg;
|
||||
int r;
|
||||
u32 idx_value;
|
||||
|
||||
ib = p->ib->ptr;
|
||||
ib_chunk = &p->chunks[p->chunk_ib_idx];
|
||||
idx = pkt->idx + 1;
|
||||
idx_value = radeon_get_ib_value(p, idx);
|
||||
|
||||
switch (pkt->opcode) {
|
||||
case PACKET3_START_3D_CMDBUF:
|
||||
if (p->family >= CHIP_RV770 || pkt->count) {
|
||||
|
@ -259,8 +378,8 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
|||
DRM_ERROR("bad DRAW_INDEX\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
ib[idx+0] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
|
||||
ib[idx+1] = upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
|
||||
ib[idx+0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff);
|
||||
ib[idx+1] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
|
||||
break;
|
||||
case PACKET3_DRAW_INDEX_AUTO:
|
||||
if (pkt->count != 1) {
|
||||
|
@ -281,14 +400,14 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
|||
return -EINVAL;
|
||||
}
|
||||
/* bit 4 is reg (0) or mem (1) */
|
||||
if (ib_chunk->kdata[idx+0] & 0x10) {
|
||||
if (idx_value & 0x10) {
|
||||
r = r600_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
DRM_ERROR("bad WAIT_REG_MEM\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
|
||||
ib[idx+2] = upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
|
||||
ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
|
||||
}
|
||||
break;
|
||||
case PACKET3_SURFACE_SYNC:
|
||||
|
@ -297,8 +416,8 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
|||
return -EINVAL;
|
||||
}
|
||||
/* 0xffffffff/0x0 is flush all cache flag */
|
||||
if (ib_chunk->kdata[idx+1] != 0xffffffff ||
|
||||
ib_chunk->kdata[idx+2] != 0) {
|
||||
if (radeon_get_ib_value(p, idx + 1) != 0xffffffff ||
|
||||
radeon_get_ib_value(p, idx + 2) != 0) {
|
||||
r = r600_cs_packet_next_reloc(p, &reloc);
|
||||
if (r) {
|
||||
DRM_ERROR("bad SURFACE_SYNC\n");
|
||||
|
@ -319,7 +438,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
|||
return -EINVAL;
|
||||
}
|
||||
ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
|
||||
ib[idx+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
|
||||
ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
|
||||
}
|
||||
break;
|
||||
case PACKET3_EVENT_WRITE_EOP:
|
||||
|
@ -333,10 +452,10 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
|||
return -EINVAL;
|
||||
}
|
||||
ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff);
|
||||
ib[idx+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
|
||||
ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
|
||||
break;
|
||||
case PACKET3_SET_CONFIG_REG:
|
||||
start_reg = (ib[idx+0] << 2) + PACKET3_SET_CONFIG_REG_OFFSET;
|
||||
start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_OFFSET;
|
||||
end_reg = 4 * pkt->count + start_reg - 4;
|
||||
if ((start_reg < PACKET3_SET_CONFIG_REG_OFFSET) ||
|
||||
(start_reg >= PACKET3_SET_CONFIG_REG_END) ||
|
||||
|
@ -356,7 +475,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
|||
}
|
||||
break;
|
||||
case PACKET3_SET_CONTEXT_REG:
|
||||
start_reg = (ib[idx+0] << 2) + PACKET3_SET_CONTEXT_REG_OFFSET;
|
||||
start_reg = (idx_value << 2) + PACKET3_SET_CONTEXT_REG_OFFSET;
|
||||
end_reg = 4 * pkt->count + start_reg - 4;
|
||||
if ((start_reg < PACKET3_SET_CONTEXT_REG_OFFSET) ||
|
||||
(start_reg >= PACKET3_SET_CONTEXT_REG_END) ||
|
||||
|
@ -421,7 +540,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
|||
DRM_ERROR("bad SET_RESOURCE\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
start_reg = (ib[idx+0] << 2) + PACKET3_SET_RESOURCE_OFFSET;
|
||||
start_reg = (idx_value << 2) + PACKET3_SET_RESOURCE_OFFSET;
|
||||
end_reg = 4 * pkt->count + start_reg - 4;
|
||||
if ((start_reg < PACKET3_SET_RESOURCE_OFFSET) ||
|
||||
(start_reg >= PACKET3_SET_RESOURCE_END) ||
|
||||
|
@ -430,7 +549,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
|||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < (pkt->count / 7); i++) {
|
||||
switch (G__SQ_VTX_CONSTANT_TYPE(ib[idx+(i*7)+6+1])) {
|
||||
switch (G__SQ_VTX_CONSTANT_TYPE(radeon_get_ib_value(p, idx+(i*7)+6+1))) {
|
||||
case SQ_TEX_VTX_VALID_TEXTURE:
|
||||
/* tex base */
|
||||
r = r600_cs_packet_next_reloc(p, &reloc);
|
||||
|
@ -455,7 +574,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
|||
return -EINVAL;
|
||||
}
|
||||
ib[idx+1+(i*7)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff);
|
||||
ib[idx+1+(i*7)+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
|
||||
ib[idx+1+(i*7)+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff;
|
||||
break;
|
||||
case SQ_TEX_VTX_INVALID_TEXTURE:
|
||||
case SQ_TEX_VTX_INVALID_BUFFER:
|
||||
|
@ -466,7 +585,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
|||
}
|
||||
break;
|
||||
case PACKET3_SET_ALU_CONST:
|
||||
start_reg = (ib[idx+0] << 2) + PACKET3_SET_ALU_CONST_OFFSET;
|
||||
start_reg = (idx_value << 2) + PACKET3_SET_ALU_CONST_OFFSET;
|
||||
end_reg = 4 * pkt->count + start_reg - 4;
|
||||
if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) ||
|
||||
(start_reg >= PACKET3_SET_ALU_CONST_END) ||
|
||||
|
@ -476,7 +595,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
|||
}
|
||||
break;
|
||||
case PACKET3_SET_BOOL_CONST:
|
||||
start_reg = (ib[idx+0] << 2) + PACKET3_SET_BOOL_CONST_OFFSET;
|
||||
start_reg = (idx_value << 2) + PACKET3_SET_BOOL_CONST_OFFSET;
|
||||
end_reg = 4 * pkt->count + start_reg - 4;
|
||||
if ((start_reg < PACKET3_SET_BOOL_CONST_OFFSET) ||
|
||||
(start_reg >= PACKET3_SET_BOOL_CONST_END) ||
|
||||
|
@ -486,7 +605,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
|||
}
|
||||
break;
|
||||
case PACKET3_SET_LOOP_CONST:
|
||||
start_reg = (ib[idx+0] << 2) + PACKET3_SET_LOOP_CONST_OFFSET;
|
||||
start_reg = (idx_value << 2) + PACKET3_SET_LOOP_CONST_OFFSET;
|
||||
end_reg = 4 * pkt->count + start_reg - 4;
|
||||
if ((start_reg < PACKET3_SET_LOOP_CONST_OFFSET) ||
|
||||
(start_reg >= PACKET3_SET_LOOP_CONST_END) ||
|
||||
|
@ -496,7 +615,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
|||
}
|
||||
break;
|
||||
case PACKET3_SET_CTL_CONST:
|
||||
start_reg = (ib[idx+0] << 2) + PACKET3_SET_CTL_CONST_OFFSET;
|
||||
start_reg = (idx_value << 2) + PACKET3_SET_CTL_CONST_OFFSET;
|
||||
end_reg = 4 * pkt->count + start_reg - 4;
|
||||
if ((start_reg < PACKET3_SET_CTL_CONST_OFFSET) ||
|
||||
(start_reg >= PACKET3_SET_CTL_CONST_END) ||
|
||||
|
@ -510,7 +629,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
|
|||
DRM_ERROR("bad SET_SAMPLER\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
start_reg = (ib[idx+0] << 2) + PACKET3_SET_SAMPLER_OFFSET;
|
||||
start_reg = (idx_value << 2) + PACKET3_SET_SAMPLER_OFFSET;
|
||||
end_reg = 4 * pkt->count + start_reg - 4;
|
||||
if ((start_reg < PACKET3_SET_SAMPLER_OFFSET) ||
|
||||
(start_reg >= PACKET3_SET_SAMPLER_END) ||
|
||||
|
@ -602,6 +721,8 @@ static void r600_cs_parser_fini(struct radeon_cs_parser *parser, int error)
|
|||
kfree(parser->relocs);
|
||||
for (i = 0; i < parser->nchunks; i++) {
|
||||
kfree(parser->chunks[i].kdata);
|
||||
kfree(parser->chunks[i].kpage[0]);
|
||||
kfree(parser->chunks[i].kpage[1]);
|
||||
}
|
||||
kfree(parser->chunks);
|
||||
kfree(parser->chunks_array);
|
||||
|
@ -639,7 +760,6 @@ int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp,
|
|||
* uncached). */
|
||||
ib_chunk = &parser.chunks[parser.chunk_ib_idx];
|
||||
parser.ib->length_dw = ib_chunk->length_dw;
|
||||
memcpy((void *)parser.ib->ptr, ib_chunk->kdata, ib_chunk->length_dw*4);
|
||||
*l = parser.ib->length_dw;
|
||||
r = r600_cs_parse(&parser);
|
||||
if (r) {
|
||||
|
@ -647,6 +767,12 @@ int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp,
|
|||
r600_cs_parser_fini(&parser, r);
|
||||
return r;
|
||||
}
|
||||
r = radeon_cs_finish_pages(&parser);
|
||||
if (r) {
|
||||
DRM_ERROR("Invalid command stream !\n");
|
||||
r600_cs_parser_fini(&parser, r);
|
||||
return r;
|
||||
}
|
||||
r600_cs_parser_fini(&parser, r);
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,24 @@
|
|||
* - TESTING, TESTING, TESTING
|
||||
*/
|
||||
|
||||
/* Initialization path:
|
||||
* We expect that acceleration initialization might fail for various
|
||||
* reasons even thought we work hard to make it works on most
|
||||
* configurations. In order to still have a working userspace in such
|
||||
* situation the init path must succeed up to the memory controller
|
||||
* initialization point. Failure before this point are considered as
|
||||
* fatal error. Here is the init callchain :
|
||||
* radeon_device_init perform common structure, mutex initialization
|
||||
* asic_init setup the GPU memory layout and perform all
|
||||
* one time initialization (failure in this
|
||||
* function are considered fatal)
|
||||
* asic_startup setup the GPU acceleration, in order to
|
||||
* follow guideline the first thing this
|
||||
* function should do is setting the GPU
|
||||
* memory controller (only MC setup failure
|
||||
* are considered as fatal)
|
||||
*/
|
||||
|
||||
#include <asm/atomic.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/list.h>
|
||||
|
@ -342,7 +360,7 @@ struct radeon_ib {
|
|||
unsigned long idx;
|
||||
uint64_t gpu_addr;
|
||||
struct radeon_fence *fence;
|
||||
volatile uint32_t *ptr;
|
||||
uint32_t *ptr;
|
||||
uint32_t length_dw;
|
||||
};
|
||||
|
||||
|
@ -415,7 +433,12 @@ struct radeon_cs_reloc {
|
|||
struct radeon_cs_chunk {
|
||||
uint32_t chunk_id;
|
||||
uint32_t length_dw;
|
||||
int kpage_idx[2];
|
||||
uint32_t *kpage[2];
|
||||
uint32_t *kdata;
|
||||
void __user *user_ptr;
|
||||
int last_copied_page;
|
||||
int last_page_index;
|
||||
};
|
||||
|
||||
struct radeon_cs_parser {
|
||||
|
@ -438,8 +461,38 @@ struct radeon_cs_parser {
|
|||
struct radeon_ib *ib;
|
||||
void *track;
|
||||
unsigned family;
|
||||
int parser_error;
|
||||
};
|
||||
|
||||
extern int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx);
|
||||
extern int radeon_cs_finish_pages(struct radeon_cs_parser *p);
|
||||
|
||||
|
||||
static inline u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx)
|
||||
{
|
||||
struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx];
|
||||
u32 pg_idx, pg_offset;
|
||||
u32 idx_value = 0;
|
||||
int new_page;
|
||||
|
||||
pg_idx = (idx * 4) / PAGE_SIZE;
|
||||
pg_offset = (idx * 4) % PAGE_SIZE;
|
||||
|
||||
if (ibc->kpage_idx[0] == pg_idx)
|
||||
return ibc->kpage[0][pg_offset/4];
|
||||
if (ibc->kpage_idx[1] == pg_idx)
|
||||
return ibc->kpage[1][pg_offset/4];
|
||||
|
||||
new_page = radeon_cs_update_pages(p, pg_idx);
|
||||
if (new_page < 0) {
|
||||
p->parser_error = new_page;
|
||||
return 0;
|
||||
}
|
||||
|
||||
idx_value = ibc->kpage[new_page][pg_offset/4];
|
||||
return idx_value;
|
||||
}
|
||||
|
||||
struct radeon_cs_packet {
|
||||
unsigned idx;
|
||||
unsigned type;
|
||||
|
@ -943,6 +996,7 @@ extern void radeon_clocks_fini(struct radeon_device *rdev);
|
|||
extern void radeon_scratch_init(struct radeon_device *rdev);
|
||||
extern void radeon_surface_init(struct radeon_device *rdev);
|
||||
extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data);
|
||||
extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable);
|
||||
|
||||
/* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */
|
||||
struct r100_mc_save {
|
||||
|
@ -974,6 +1028,9 @@ extern void r100_vram_init_sizes(struct radeon_device *rdev);
|
|||
extern void r100_wb_disable(struct radeon_device *rdev);
|
||||
extern void r100_wb_fini(struct radeon_device *rdev);
|
||||
extern int r100_wb_init(struct radeon_device *rdev);
|
||||
extern void r100_hdp_reset(struct radeon_device *rdev);
|
||||
extern int r100_rb2d_reset(struct radeon_device *rdev);
|
||||
extern int r100_cp_reset(struct radeon_device *rdev);
|
||||
|
||||
/* r300,r350,rv350,rv370,rv380 */
|
||||
extern void r300_set_reg_safe(struct radeon_device *rdev);
|
||||
|
@ -985,12 +1042,29 @@ extern int rv370_pcie_gart_enable(struct radeon_device *rdev);
|
|||
extern void rv370_pcie_gart_disable(struct radeon_device *rdev);
|
||||
|
||||
/* r420,r423,rv410 */
|
||||
extern int r420_mc_init(struct radeon_device *rdev);
|
||||
extern u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg);
|
||||
extern void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v);
|
||||
extern int r420_debugfs_pipes_info_init(struct radeon_device *rdev);
|
||||
extern void r420_pipes_init(struct radeon_device *rdev);
|
||||
|
||||
/* rv515 */
|
||||
struct rv515_mc_save {
|
||||
u32 d1vga_control;
|
||||
u32 d2vga_control;
|
||||
u32 vga_render_control;
|
||||
u32 vga_hdp_control;
|
||||
u32 d1crtc_control;
|
||||
u32 d2crtc_control;
|
||||
};
|
||||
extern void rv515_bandwidth_avivo_update(struct radeon_device *rdev);
|
||||
extern void rv515_vga_render_disable(struct radeon_device *rdev);
|
||||
extern void rv515_set_safe_registers(struct radeon_device *rdev);
|
||||
extern void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save);
|
||||
extern void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save);
|
||||
extern void rv515_clock_startup(struct radeon_device *rdev);
|
||||
extern void rv515_debugfs(struct radeon_device *rdev);
|
||||
extern int rv515_suspend(struct radeon_device *rdev);
|
||||
|
||||
/* rs690, rs740 */
|
||||
extern void rs690_line_buffer_adjust(struct radeon_device *rdev,
|
||||
|
|
|
@ -420,41 +420,43 @@ static struct radeon_asic rs690_asic = {
|
|||
* rv515
|
||||
*/
|
||||
int rv515_init(struct radeon_device *rdev);
|
||||
void rv515_errata(struct radeon_device *rdev);
|
||||
void rv515_vram_info(struct radeon_device *rdev);
|
||||
void rv515_fini(struct radeon_device *rdev);
|
||||
int rv515_gpu_reset(struct radeon_device *rdev);
|
||||
int rv515_mc_init(struct radeon_device *rdev);
|
||||
void rv515_mc_fini(struct radeon_device *rdev);
|
||||
uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg);
|
||||
void rv515_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
|
||||
void rv515_ring_start(struct radeon_device *rdev);
|
||||
uint32_t rv515_pcie_rreg(struct radeon_device *rdev, uint32_t reg);
|
||||
void rv515_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
|
||||
void rv515_bandwidth_update(struct radeon_device *rdev);
|
||||
int rv515_resume(struct radeon_device *rdev);
|
||||
int rv515_suspend(struct radeon_device *rdev);
|
||||
static struct radeon_asic rv515_asic = {
|
||||
.init = &rv515_init,
|
||||
.errata = &rv515_errata,
|
||||
.vram_info = &rv515_vram_info,
|
||||
.fini = &rv515_fini,
|
||||
.suspend = &rv515_suspend,
|
||||
.resume = &rv515_resume,
|
||||
.errata = NULL,
|
||||
.vram_info = NULL,
|
||||
.vga_set_state = &r100_vga_set_state,
|
||||
.gpu_reset = &rv515_gpu_reset,
|
||||
.mc_init = &rv515_mc_init,
|
||||
.mc_fini = &rv515_mc_fini,
|
||||
.wb_init = &r100_wb_init,
|
||||
.wb_fini = &r100_wb_fini,
|
||||
.mc_init = NULL,
|
||||
.mc_fini = NULL,
|
||||
.wb_init = NULL,
|
||||
.wb_fini = NULL,
|
||||
.gart_init = &rv370_pcie_gart_init,
|
||||
.gart_fini = &rv370_pcie_gart_fini,
|
||||
.gart_enable = &rv370_pcie_gart_enable,
|
||||
.gart_disable = &rv370_pcie_gart_disable,
|
||||
.gart_enable = NULL,
|
||||
.gart_disable = NULL,
|
||||
.gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
|
||||
.gart_set_page = &rv370_pcie_gart_set_page,
|
||||
.cp_init = &r100_cp_init,
|
||||
.cp_fini = &r100_cp_fini,
|
||||
.cp_disable = &r100_cp_disable,
|
||||
.cp_init = NULL,
|
||||
.cp_fini = NULL,
|
||||
.cp_disable = NULL,
|
||||
.cp_commit = &r100_cp_commit,
|
||||
.ring_start = &rv515_ring_start,
|
||||
.ring_test = &r100_ring_test,
|
||||
.ring_ib_execute = &r100_ring_ib_execute,
|
||||
.ib_test = &r100_ib_test,
|
||||
.ib_test = NULL,
|
||||
.irq_set = &rs600_irq_set,
|
||||
.irq_process = &rs600_irq_process,
|
||||
.get_vblank_counter = &rs600_get_vblank_counter,
|
||||
|
@ -476,35 +478,35 @@ static struct radeon_asic rv515_asic = {
|
|||
/*
|
||||
* r520,rv530,rv560,rv570,r580
|
||||
*/
|
||||
void r520_errata(struct radeon_device *rdev);
|
||||
void r520_vram_info(struct radeon_device *rdev);
|
||||
int r520_mc_init(struct radeon_device *rdev);
|
||||
void r520_mc_fini(struct radeon_device *rdev);
|
||||
void r520_bandwidth_update(struct radeon_device *rdev);
|
||||
int r520_init(struct radeon_device *rdev);
|
||||
int r520_resume(struct radeon_device *rdev);
|
||||
static struct radeon_asic r520_asic = {
|
||||
.init = &rv515_init,
|
||||
.errata = &r520_errata,
|
||||
.vram_info = &r520_vram_info,
|
||||
.init = &r520_init,
|
||||
.fini = &rv515_fini,
|
||||
.suspend = &rv515_suspend,
|
||||
.resume = &r520_resume,
|
||||
.errata = NULL,
|
||||
.vram_info = NULL,
|
||||
.vga_set_state = &r100_vga_set_state,
|
||||
.gpu_reset = &rv515_gpu_reset,
|
||||
.mc_init = &r520_mc_init,
|
||||
.mc_fini = &r520_mc_fini,
|
||||
.wb_init = &r100_wb_init,
|
||||
.wb_fini = &r100_wb_fini,
|
||||
.gart_init = &rv370_pcie_gart_init,
|
||||
.gart_fini = &rv370_pcie_gart_fini,
|
||||
.gart_enable = &rv370_pcie_gart_enable,
|
||||
.gart_disable = &rv370_pcie_gart_disable,
|
||||
.mc_init = NULL,
|
||||
.mc_fini = NULL,
|
||||
.wb_init = NULL,
|
||||
.wb_fini = NULL,
|
||||
.gart_init = NULL,
|
||||
.gart_fini = NULL,
|
||||
.gart_enable = NULL,
|
||||
.gart_disable = NULL,
|
||||
.gart_tlb_flush = &rv370_pcie_gart_tlb_flush,
|
||||
.gart_set_page = &rv370_pcie_gart_set_page,
|
||||
.cp_init = &r100_cp_init,
|
||||
.cp_fini = &r100_cp_fini,
|
||||
.cp_disable = &r100_cp_disable,
|
||||
.cp_init = NULL,
|
||||
.cp_fini = NULL,
|
||||
.cp_disable = NULL,
|
||||
.cp_commit = &r100_cp_commit,
|
||||
.ring_start = &rv515_ring_start,
|
||||
.ring_test = &r100_ring_test,
|
||||
.ring_ib_execute = &r100_ring_ib_execute,
|
||||
.ib_test = &r100_ib_test,
|
||||
.ib_test = NULL,
|
||||
.irq_set = &rs600_irq_set,
|
||||
.irq_process = &rs600_irq_process,
|
||||
.get_vblank_counter = &rs600_get_vblank_counter,
|
||||
|
@ -519,7 +521,7 @@ static struct radeon_asic r520_asic = {
|
|||
.set_clock_gating = &radeon_atom_set_clock_gating,
|
||||
.set_surface_reg = r100_set_surface_reg,
|
||||
.clear_surface_reg = r100_clear_surface_reg,
|
||||
.bandwidth_update = &r520_bandwidth_update,
|
||||
.bandwidth_update = &rv515_bandwidth_update,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -596,7 +598,7 @@ static struct radeon_asic r600_asic = {
|
|||
.set_clock_gating = &radeon_atom_set_clock_gating,
|
||||
.set_surface_reg = r600_set_surface_reg,
|
||||
.clear_surface_reg = r600_clear_surface_reg,
|
||||
.bandwidth_update = &r520_bandwidth_update,
|
||||
.bandwidth_update = &rv515_bandwidth_update,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -646,7 +648,7 @@ static struct radeon_asic rv770_asic = {
|
|||
.set_clock_gating = &radeon_atom_set_clock_gating,
|
||||
.set_surface_reg = r600_set_surface_reg,
|
||||
.clear_surface_reg = r600_clear_surface_reg,
|
||||
.bandwidth_update = &r520_bandwidth_update,
|
||||
.bandwidth_update = &rv515_bandwidth_update,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -272,12 +272,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev)
|
|||
(le16_to_cpu(path->usConnObjectId) &
|
||||
OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT;
|
||||
|
||||
if ((le16_to_cpu(path->usDeviceTag) ==
|
||||
ATOM_DEVICE_TV1_SUPPORT)
|
||||
|| (le16_to_cpu(path->usDeviceTag) ==
|
||||
ATOM_DEVICE_TV2_SUPPORT)
|
||||
|| (le16_to_cpu(path->usDeviceTag) ==
|
||||
ATOM_DEVICE_CV_SUPPORT))
|
||||
/* TODO CV support */
|
||||
if (le16_to_cpu(path->usDeviceTag) ==
|
||||
ATOM_DEVICE_CV_SUPPORT)
|
||||
continue;
|
||||
|
||||
if ((rdev->family == CHIP_RS780) &&
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "drmP.h"
|
||||
#include "drm_edid.h"
|
||||
#include "drm_crtc_helper.h"
|
||||
#include "drm_fb_helper.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "radeon.h"
|
||||
#include "atom.h"
|
||||
|
@ -245,7 +246,7 @@ static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_conn
|
|||
if (common_modes[i].w < 320 || common_modes[i].h < 200)
|
||||
continue;
|
||||
|
||||
mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false);
|
||||
mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false);
|
||||
drm_mode_probed_add(connector, mode);
|
||||
}
|
||||
}
|
||||
|
@ -559,7 +560,7 @@ static int radeon_tv_get_modes(struct drm_connector *connector)
|
|||
radeon_add_common_modes(encoder, connector);
|
||||
else {
|
||||
/* only 800x600 is supported right now on pre-avivo chips */
|
||||
tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false);
|
||||
tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false, false);
|
||||
tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
|
||||
drm_mode_probed_add(connector, tv_mode);
|
||||
}
|
||||
|
@ -743,6 +744,15 @@ struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void radeon_dvi_force(struct drm_connector *connector)
|
||||
{
|
||||
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
|
||||
if (connector->force == DRM_FORCE_ON)
|
||||
radeon_connector->use_digital = false;
|
||||
if (connector->force == DRM_FORCE_ON_DIGITAL)
|
||||
radeon_connector->use_digital = true;
|
||||
}
|
||||
|
||||
struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = {
|
||||
.get_modes = radeon_dvi_get_modes,
|
||||
.mode_valid = radeon_vga_mode_valid,
|
||||
|
@ -755,6 +765,7 @@ struct drm_connector_funcs radeon_dvi_connector_funcs = {
|
|||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.set_property = radeon_connector_set_property,
|
||||
.destroy = radeon_connector_destroy,
|
||||
.force = radeon_dvi_force,
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -771,6 +782,7 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
struct radeon_connector *radeon_connector;
|
||||
struct radeon_connector_atom_dig *radeon_dig_connector;
|
||||
uint32_t subpixel_order = SubPixelNone;
|
||||
int ret;
|
||||
|
||||
/* fixme - tv/cv/din */
|
||||
if (connector_type == DRM_MODE_CONNECTOR_Unknown)
|
||||
|
@ -796,24 +808,30 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
switch (connector_type) {
|
||||
case DRM_MODE_CONNECTOR_VGA:
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
|
||||
ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
|
||||
if (ret)
|
||||
goto failed;
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA");
|
||||
if (!radeon_connector->ddc_bus)
|
||||
goto failed;
|
||||
}
|
||||
radeon_connector->dac_load_detect = true;
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_DVIA:
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
|
||||
ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
|
||||
if (ret)
|
||||
goto failed;
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
|
||||
if (!radeon_connector->ddc_bus)
|
||||
goto failed;
|
||||
}
|
||||
radeon_connector->dac_load_detect = true;
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
|
@ -827,7 +845,9 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
radeon_dig_connector->igp_lane_info = igp_lane_info;
|
||||
radeon_connector->con_priv = radeon_dig_connector;
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
|
||||
ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
|
||||
if (ret)
|
||||
goto failed;
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
|
||||
if (!radeon_connector->ddc_bus)
|
||||
|
@ -837,6 +857,7 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.coherent_mode_property,
|
||||
1);
|
||||
radeon_connector->dac_load_detect = true;
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
|
@ -850,7 +871,9 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
radeon_dig_connector->igp_lane_info = igp_lane_info;
|
||||
radeon_connector->con_priv = radeon_dig_connector;
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
|
||||
ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
|
||||
if (ret)
|
||||
goto failed;
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "HDMI");
|
||||
if (!radeon_connector->ddc_bus)
|
||||
|
@ -869,7 +892,9 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
radeon_dig_connector->igp_lane_info = igp_lane_info;
|
||||
radeon_connector->con_priv = radeon_dig_connector;
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
|
||||
ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
|
||||
if (ret)
|
||||
goto failed;
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP");
|
||||
if (!radeon_connector->ddc_bus)
|
||||
|
@ -882,11 +907,14 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
case DRM_MODE_CONNECTOR_9PinDIN:
|
||||
if (radeon_tv == 1) {
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
|
||||
ret = drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
|
||||
if (ret)
|
||||
goto failed;
|
||||
radeon_connector->dac_load_detect = true;
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
}
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_LVDS:
|
||||
radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
|
||||
|
@ -896,7 +924,9 @@ radeon_add_atom_connector(struct drm_device *dev,
|
|||
radeon_dig_connector->igp_lane_info = igp_lane_info;
|
||||
radeon_connector->con_priv = radeon_dig_connector;
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
|
||||
ret = drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
|
||||
if (ret)
|
||||
goto failed;
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS");
|
||||
if (!radeon_connector->ddc_bus)
|
||||
|
@ -932,6 +962,7 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
|||
struct drm_connector *connector;
|
||||
struct radeon_connector *radeon_connector;
|
||||
uint32_t subpixel_order = SubPixelNone;
|
||||
int ret;
|
||||
|
||||
/* fixme - tv/cv/din */
|
||||
if (connector_type == DRM_MODE_CONNECTOR_Unknown)
|
||||
|
@ -957,24 +988,30 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
|||
switch (connector_type) {
|
||||
case DRM_MODE_CONNECTOR_VGA:
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
|
||||
ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
|
||||
if (ret)
|
||||
goto failed;
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA");
|
||||
if (!radeon_connector->ddc_bus)
|
||||
goto failed;
|
||||
}
|
||||
radeon_connector->dac_load_detect = true;
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_DVIA:
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
|
||||
ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
|
||||
if (ret)
|
||||
goto failed;
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
|
||||
if (!radeon_connector->ddc_bus)
|
||||
goto failed;
|
||||
}
|
||||
radeon_connector->dac_load_detect = true;
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
|
@ -982,11 +1019,14 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
|||
case DRM_MODE_CONNECTOR_DVII:
|
||||
case DRM_MODE_CONNECTOR_DVID:
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
|
||||
ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
|
||||
if (ret)
|
||||
goto failed;
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI");
|
||||
if (!radeon_connector->ddc_bus)
|
||||
goto failed;
|
||||
radeon_connector->dac_load_detect = true;
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
|
@ -998,7 +1038,10 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
|||
case DRM_MODE_CONNECTOR_9PinDIN:
|
||||
if (radeon_tv == 1) {
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
|
||||
ret = drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
|
||||
if (ret)
|
||||
goto failed;
|
||||
radeon_connector->dac_load_detect = true;
|
||||
drm_connector_attach_property(&radeon_connector->base,
|
||||
rdev->mode_info.load_detect_property,
|
||||
1);
|
||||
|
@ -1006,7 +1049,9 @@ radeon_add_legacy_connector(struct drm_device *dev,
|
|||
break;
|
||||
case DRM_MODE_CONNECTOR_LVDS:
|
||||
drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
|
||||
drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
|
||||
ret = drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
|
||||
if (ret)
|
||||
goto failed;
|
||||
if (i2c_bus->valid) {
|
||||
radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS");
|
||||
if (!radeon_connector->ddc_bus)
|
||||
|
|
|
@ -142,15 +142,31 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
|
|||
}
|
||||
|
||||
p->chunks[i].length_dw = user_chunk.length_dw;
|
||||
cdata = (uint32_t *)(unsigned long)user_chunk.chunk_data;
|
||||
p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data;
|
||||
|
||||
size = p->chunks[i].length_dw * sizeof(uint32_t);
|
||||
p->chunks[i].kdata = kmalloc(size, GFP_KERNEL);
|
||||
if (p->chunks[i].kdata == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (DRM_COPY_FROM_USER(p->chunks[i].kdata, cdata, size)) {
|
||||
return -EFAULT;
|
||||
cdata = (uint32_t *)(unsigned long)user_chunk.chunk_data;
|
||||
if (p->chunks[i].chunk_id != RADEON_CHUNK_ID_IB) {
|
||||
size = p->chunks[i].length_dw * sizeof(uint32_t);
|
||||
p->chunks[i].kdata = kmalloc(size, GFP_KERNEL);
|
||||
if (p->chunks[i].kdata == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (DRM_COPY_FROM_USER(p->chunks[i].kdata,
|
||||
p->chunks[i].user_ptr, size)) {
|
||||
return -EFAULT;
|
||||
}
|
||||
} else {
|
||||
p->chunks[i].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
p->chunks[i].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
if (p->chunks[i].kpage[0] == NULL || p->chunks[i].kpage[1] == NULL) {
|
||||
kfree(p->chunks[i].kpage[0]);
|
||||
kfree(p->chunks[i].kpage[1]);
|
||||
return -ENOMEM;
|
||||
}
|
||||
p->chunks[i].kpage_idx[0] = -1;
|
||||
p->chunks[i].kpage_idx[1] = -1;
|
||||
p->chunks[i].last_copied_page = -1;
|
||||
p->chunks[i].last_page_index = ((p->chunks[i].length_dw * 4) - 1) / PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
if (p->chunks[p->chunk_ib_idx].length_dw > (16 * 1024)) {
|
||||
|
@ -190,6 +206,8 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)
|
|||
kfree(parser->relocs_ptr);
|
||||
for (i = 0; i < parser->nchunks; i++) {
|
||||
kfree(parser->chunks[i].kdata);
|
||||
kfree(parser->chunks[i].kpage[0]);
|
||||
kfree(parser->chunks[i].kpage[1]);
|
||||
}
|
||||
kfree(parser->chunks);
|
||||
kfree(parser->chunks_array);
|
||||
|
@ -238,8 +256,14 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
|||
* uncached). */
|
||||
ib_chunk = &parser.chunks[parser.chunk_ib_idx];
|
||||
parser.ib->length_dw = ib_chunk->length_dw;
|
||||
memcpy((void *)parser.ib->ptr, ib_chunk->kdata, ib_chunk->length_dw*4);
|
||||
r = radeon_cs_parse(&parser);
|
||||
if (r || parser.parser_error) {
|
||||
DRM_ERROR("Invalid command stream !\n");
|
||||
radeon_cs_parser_fini(&parser, r);
|
||||
mutex_unlock(&rdev->cs_mutex);
|
||||
return r;
|
||||
}
|
||||
r = radeon_cs_finish_pages(&parser);
|
||||
if (r) {
|
||||
DRM_ERROR("Invalid command stream !\n");
|
||||
radeon_cs_parser_fini(&parser, r);
|
||||
|
@ -254,3 +278,64 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
|
|||
mutex_unlock(&rdev->cs_mutex);
|
||||
return r;
|
||||
}
|
||||
|
||||
int radeon_cs_finish_pages(struct radeon_cs_parser *p)
|
||||
{
|
||||
struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx];
|
||||
int i;
|
||||
int size = PAGE_SIZE;
|
||||
|
||||
for (i = ibc->last_copied_page + 1; i <= ibc->last_page_index; i++) {
|
||||
if (i == ibc->last_page_index) {
|
||||
size = (ibc->length_dw * 4) % PAGE_SIZE;
|
||||
if (size == 0)
|
||||
size = PAGE_SIZE;
|
||||
}
|
||||
|
||||
if (DRM_COPY_FROM_USER(p->ib->ptr + (i * (PAGE_SIZE/4)),
|
||||
ibc->user_ptr + (i * PAGE_SIZE),
|
||||
size))
|
||||
return -EFAULT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx)
|
||||
{
|
||||
int new_page;
|
||||
struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx];
|
||||
int i;
|
||||
int size = PAGE_SIZE;
|
||||
|
||||
for (i = ibc->last_copied_page + 1; i < pg_idx; i++) {
|
||||
if (DRM_COPY_FROM_USER(p->ib->ptr + (i * (PAGE_SIZE/4)),
|
||||
ibc->user_ptr + (i * PAGE_SIZE),
|
||||
PAGE_SIZE)) {
|
||||
p->parser_error = -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
new_page = ibc->kpage_idx[0] < ibc->kpage_idx[1] ? 0 : 1;
|
||||
|
||||
if (pg_idx == ibc->last_page_index) {
|
||||
size = (ibc->length_dw * 4) % PAGE_SIZE;
|
||||
if (size == 0)
|
||||
size = PAGE_SIZE;
|
||||
}
|
||||
|
||||
if (DRM_COPY_FROM_USER(ibc->kpage[new_page],
|
||||
ibc->user_ptr + (pg_idx * PAGE_SIZE),
|
||||
size)) {
|
||||
p->parser_error = -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* copy to IB here */
|
||||
memcpy((void *)(p->ib->ptr+(pg_idx*(PAGE_SIZE/4))), ibc->kpage[new_page], size);
|
||||
|
||||
ibc->last_copied_page = pg_idx;
|
||||
ibc->kpage_idx[new_page] = pg_idx;
|
||||
|
||||
return new_page;
|
||||
}
|
||||
|
|
|
@ -532,10 +532,13 @@ int radeon_device_init(struct radeon_device *rdev,
|
|||
|
||||
if (radeon_agpmode == -1) {
|
||||
rdev->flags &= ~RADEON_IS_AGP;
|
||||
if (rdev->family >= CHIP_RV515 ||
|
||||
rdev->family == CHIP_RV380 ||
|
||||
rdev->family == CHIP_RV410 ||
|
||||
rdev->family == CHIP_R423) {
|
||||
if (rdev->family >= CHIP_R600) {
|
||||
DRM_INFO("Forcing AGP to PCIE mode\n");
|
||||
rdev->flags |= RADEON_IS_PCIE;
|
||||
} else if (rdev->family >= CHIP_RV515 ||
|
||||
rdev->family == CHIP_RV380 ||
|
||||
rdev->family == CHIP_RV410 ||
|
||||
rdev->family == CHIP_R423) {
|
||||
DRM_INFO("Forcing AGP to PCIE mode\n");
|
||||
rdev->flags |= RADEON_IS_PCIE;
|
||||
rdev->asic->gart_init = &rv370_pcie_gart_init;
|
||||
|
|
|
@ -62,9 +62,6 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev);
|
|||
int radeon_driver_irq_postinstall_kms(struct drm_device *dev);
|
||||
void radeon_driver_irq_uninstall_kms(struct drm_device *dev);
|
||||
irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS);
|
||||
int radeon_master_create_kms(struct drm_device *dev, struct drm_master *master);
|
||||
void radeon_master_destroy_kms(struct drm_device *dev,
|
||||
struct drm_master *master);
|
||||
int radeon_dma_ioctl_kms(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
int radeon_gem_object_init(struct drm_gem_object *obj);
|
||||
|
@ -260,8 +257,6 @@ static struct drm_driver kms_driver = {
|
|||
.get_vblank_counter = radeon_get_vblank_counter_kms,
|
||||
.enable_vblank = radeon_enable_vblank_kms,
|
||||
.disable_vblank = radeon_disable_vblank_kms,
|
||||
.master_create = radeon_master_create_kms,
|
||||
.master_destroy = radeon_master_destroy_kms,
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
.debugfs_init = radeon_debugfs_init,
|
||||
.debugfs_cleanup = radeon_debugfs_cleanup,
|
||||
|
|
|
@ -128,6 +128,7 @@ static struct drm_fb_helper_funcs radeon_fb_helper_funcs = {
|
|||
int radeonfb_create(struct drm_device *dev,
|
||||
uint32_t fb_width, uint32_t fb_height,
|
||||
uint32_t surface_width, uint32_t surface_height,
|
||||
uint32_t surface_depth, uint32_t surface_bpp,
|
||||
struct drm_framebuffer **fb_p)
|
||||
{
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
|
@ -148,10 +149,10 @@ int radeonfb_create(struct drm_device *dev,
|
|||
|
||||
mode_cmd.width = surface_width;
|
||||
mode_cmd.height = surface_height;
|
||||
mode_cmd.bpp = 32;
|
||||
mode_cmd.bpp = surface_bpp;
|
||||
/* need to align pitch with crtc limits */
|
||||
mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp, fb_tiled) * ((mode_cmd.bpp + 1) / 8);
|
||||
mode_cmd.depth = 24;
|
||||
mode_cmd.depth = surface_depth;
|
||||
|
||||
size = mode_cmd.pitch * mode_cmd.height;
|
||||
aligned_size = ALIGN(size, PAGE_SIZE);
|
||||
|
@ -290,13 +291,26 @@ int radeonfb_create(struct drm_device *dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static char *mode_option;
|
||||
int radeon_parse_options(char *options)
|
||||
{
|
||||
char *this_opt;
|
||||
|
||||
if (!options || !*options)
|
||||
return 0;
|
||||
|
||||
while ((this_opt = strsep(&options, ",")) != NULL) {
|
||||
if (!*this_opt)
|
||||
continue;
|
||||
mode_option = this_opt;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radeonfb_probe(struct drm_device *dev)
|
||||
{
|
||||
int ret;
|
||||
ret = drm_fb_helper_single_fb_probe(dev, &radeonfb_create);
|
||||
return ret;
|
||||
return drm_fb_helper_single_fb_probe(dev, &radeonfb_create);
|
||||
}
|
||||
EXPORT_SYMBOL(radeonfb_probe);
|
||||
|
||||
int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
|
||||
{
|
||||
|
|
|
@ -200,55 +200,6 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* For multiple master (like multiple X).
|
||||
*/
|
||||
struct drm_radeon_master_private {
|
||||
drm_local_map_t *sarea;
|
||||
drm_radeon_sarea_t *sarea_priv;
|
||||
};
|
||||
|
||||
int radeon_master_create_kms(struct drm_device *dev, struct drm_master *master)
|
||||
{
|
||||
struct drm_radeon_master_private *master_priv;
|
||||
unsigned long sareapage;
|
||||
int ret;
|
||||
|
||||
master_priv = kzalloc(sizeof(*master_priv), GFP_KERNEL);
|
||||
if (master_priv == NULL) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
/* prebuild the SAREA */
|
||||
sareapage = max_t(unsigned long, SAREA_MAX, PAGE_SIZE);
|
||||
ret = drm_addmap(dev, 0, sareapage, _DRM_SHM,
|
||||
_DRM_CONTAINS_LOCK,
|
||||
&master_priv->sarea);
|
||||
if (ret) {
|
||||
DRM_ERROR("SAREA setup failed\n");
|
||||
return ret;
|
||||
}
|
||||
master_priv->sarea_priv = master_priv->sarea->handle + sizeof(struct drm_sarea);
|
||||
master_priv->sarea_priv->pfCurrentPage = 0;
|
||||
master->driver_priv = master_priv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void radeon_master_destroy_kms(struct drm_device *dev,
|
||||
struct drm_master *master)
|
||||
{
|
||||
struct drm_radeon_master_private *master_priv = master->driver_priv;
|
||||
|
||||
if (master_priv == NULL) {
|
||||
return;
|
||||
}
|
||||
if (master_priv->sarea) {
|
||||
drm_rmmap_locked(dev, master_priv->sarea);
|
||||
}
|
||||
kfree(master_priv);
|
||||
master->driver_priv = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* IOCTL.
|
||||
*/
|
||||
|
|
|
@ -3333,6 +3333,7 @@
|
|||
# define RADEON_CP_PACKET_MAX_DWORDS (1 << 12)
|
||||
# define RADEON_CP_PACKET0_REG_MASK 0x000007ff
|
||||
# define R300_CP_PACKET0_REG_MASK 0x00001fff
|
||||
# define R600_CP_PACKET0_REG_MASK 0x0000ffff
|
||||
# define RADEON_CP_PACKET1_REG0_MASK 0x000007ff
|
||||
# define RADEON_CP_PACKET1_REG1_MASK 0x003ff800
|
||||
|
||||
|
|
|
@ -689,9 +689,6 @@ struct ttm_backend *radeon_ttm_backend_create(struct radeon_device *rdev)
|
|||
|
||||
#define RADEON_DEBUGFS_MEM_TYPES 2
|
||||
|
||||
static struct drm_info_list radeon_mem_types_list[RADEON_DEBUGFS_MEM_TYPES];
|
||||
static char radeon_mem_types_names[RADEON_DEBUGFS_MEM_TYPES][32];
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
static int radeon_mm_dump_table(struct seq_file *m, void *data)
|
||||
{
|
||||
|
@ -711,9 +708,11 @@ static int radeon_mm_dump_table(struct seq_file *m, void *data)
|
|||
|
||||
static int radeon_ttm_debugfs_init(struct radeon_device *rdev)
|
||||
{
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
static struct drm_info_list radeon_mem_types_list[RADEON_DEBUGFS_MEM_TYPES];
|
||||
static char radeon_mem_types_names[RADEON_DEBUGFS_MEM_TYPES][32];
|
||||
unsigned i;
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
for (i = 0; i < RADEON_DEBUGFS_MEM_TYPES; i++) {
|
||||
if (i == 0)
|
||||
sprintf(radeon_mem_types_names[i], "radeon_vram_mm");
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "drmP.h"
|
||||
#include "radeon_reg.h"
|
||||
#include "radeon.h"
|
||||
#include "avivod.h"
|
||||
|
||||
#include "rs600_reg_safe.h"
|
||||
|
||||
|
@ -45,7 +44,6 @@ void r420_pipes_init(struct radeon_device *rdev);
|
|||
*/
|
||||
void rs600_gpu_init(struct radeon_device *rdev);
|
||||
int rs600_mc_wait_for_idle(struct radeon_device *rdev);
|
||||
void rs600_disable_vga(struct radeon_device *rdev);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -198,7 +196,7 @@ void rs600_mc_disable_clients(struct radeon_device *rdev)
|
|||
"programming pipes. Bad things might happen.\n");
|
||||
}
|
||||
|
||||
radeon_avivo_vga_render_disable(rdev);
|
||||
rv515_vga_render_disable(rdev);
|
||||
|
||||
tmp = RREG32(AVIVO_D1VGA_CONTROL);
|
||||
WREG32(AVIVO_D1VGA_CONTROL, tmp & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
|
||||
|
@ -346,20 +344,6 @@ u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc)
|
|||
/*
|
||||
* Global GPU functions
|
||||
*/
|
||||
void rs600_disable_vga(struct radeon_device *rdev)
|
||||
{
|
||||
unsigned tmp;
|
||||
|
||||
WREG32(0x330, 0);
|
||||
WREG32(0x338, 0);
|
||||
tmp = RREG32(0x300);
|
||||
tmp &= ~(3 << 16);
|
||||
WREG32(0x300, tmp);
|
||||
WREG32(0x308, (1 << 8));
|
||||
WREG32(0x310, rdev->mc.vram_location);
|
||||
WREG32(0x594, 0);
|
||||
}
|
||||
|
||||
int rs600_mc_wait_for_idle(struct radeon_device *rdev)
|
||||
{
|
||||
unsigned i;
|
||||
|
@ -385,7 +369,7 @@ void rs600_gpu_init(struct radeon_device *rdev)
|
|||
{
|
||||
/* FIXME: HDP same place on rs600 ? */
|
||||
r100_hdp_reset(rdev);
|
||||
rs600_disable_vga(rdev);
|
||||
rv515_vga_render_disable(rdev);
|
||||
/* FIXME: is this correct ? */
|
||||
r420_pipes_init(rdev);
|
||||
if (rs600_mc_wait_for_idle(rdev)) {
|
||||
|
|
|
@ -40,7 +40,6 @@ void rs400_gart_disable(struct radeon_device *rdev);
|
|||
int rs400_gart_enable(struct radeon_device *rdev);
|
||||
void rs400_gart_adjust_size(struct radeon_device *rdev);
|
||||
void rs600_mc_disable_clients(struct radeon_device *rdev);
|
||||
void rs600_disable_vga(struct radeon_device *rdev);
|
||||
|
||||
/* This files gather functions specifics to :
|
||||
* rs690,rs740
|
||||
|
@ -125,7 +124,7 @@ void rs690_gpu_init(struct radeon_device *rdev)
|
|||
{
|
||||
/* FIXME: HDP same place on rs690 ? */
|
||||
r100_hdp_reset(rdev);
|
||||
rs600_disable_vga(rdev);
|
||||
rv515_vga_render_disable(rdev);
|
||||
/* FIXME: is this correct ? */
|
||||
r420_pipes_init(rdev);
|
||||
if (rs690_mc_wait_for_idle(rdev)) {
|
||||
|
|
|
@ -29,37 +29,17 @@
|
|||
#include "drmP.h"
|
||||
#include "rv515d.h"
|
||||
#include "radeon.h"
|
||||
|
||||
#include "atom.h"
|
||||
#include "rv515_reg_safe.h"
|
||||
/* rv515 depends on : */
|
||||
void r100_hdp_reset(struct radeon_device *rdev);
|
||||
int r100_cp_reset(struct radeon_device *rdev);
|
||||
int r100_rb2d_reset(struct radeon_device *rdev);
|
||||
int r100_gui_wait_for_idle(struct radeon_device *rdev);
|
||||
int r100_cp_init(struct radeon_device *rdev, unsigned ring_size);
|
||||
void r420_pipes_init(struct radeon_device *rdev);
|
||||
void rs600_mc_disable_clients(struct radeon_device *rdev);
|
||||
void rs600_disable_vga(struct radeon_device *rdev);
|
||||
|
||||
/* This files gather functions specifics to:
|
||||
* rv515
|
||||
*
|
||||
* Some of these functions might be used by newer ASICs.
|
||||
*/
|
||||
/* This files gather functions specifics to: rv515 */
|
||||
int rv515_debugfs_pipes_info_init(struct radeon_device *rdev);
|
||||
int rv515_debugfs_ga_info_init(struct radeon_device *rdev);
|
||||
void rv515_gpu_init(struct radeon_device *rdev);
|
||||
int rv515_mc_wait_for_idle(struct radeon_device *rdev);
|
||||
|
||||
|
||||
/*
|
||||
* MC
|
||||
*/
|
||||
int rv515_mc_init(struct radeon_device *rdev)
|
||||
void rv515_debugfs(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
int r;
|
||||
|
||||
if (r100_debugfs_rbbm_init(rdev)) {
|
||||
DRM_ERROR("Failed to register debugfs file for RBBM !\n");
|
||||
}
|
||||
|
@ -69,67 +49,8 @@ int rv515_mc_init(struct radeon_device *rdev)
|
|||
if (rv515_debugfs_ga_info_init(rdev)) {
|
||||
DRM_ERROR("Failed to register debugfs file for pipes !\n");
|
||||
}
|
||||
|
||||
rv515_gpu_init(rdev);
|
||||
rv370_pcie_gart_disable(rdev);
|
||||
|
||||
/* Setup GPU memory space */
|
||||
rdev->mc.vram_location = 0xFFFFFFFFUL;
|
||||
rdev->mc.gtt_location = 0xFFFFFFFFUL;
|
||||
if (rdev->flags & RADEON_IS_AGP) {
|
||||
r = radeon_agp_init(rdev);
|
||||
if (r) {
|
||||
printk(KERN_WARNING "[drm] Disabling AGP\n");
|
||||
rdev->flags &= ~RADEON_IS_AGP;
|
||||
rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024;
|
||||
} else {
|
||||
rdev->mc.gtt_location = rdev->mc.agp_base;
|
||||
}
|
||||
}
|
||||
r = radeon_mc_setup(rdev);
|
||||
if (r) {
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Program GPU memory space */
|
||||
rs600_mc_disable_clients(rdev);
|
||||
if (rv515_mc_wait_for_idle(rdev)) {
|
||||
printk(KERN_WARNING "Failed to wait MC idle while "
|
||||
"programming pipes. Bad things might happen.\n");
|
||||
}
|
||||
/* Write VRAM size in case we are limiting it */
|
||||
WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
|
||||
tmp = REG_SET(MC_FB_START, rdev->mc.vram_location >> 16);
|
||||
WREG32(0x134, tmp);
|
||||
tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
|
||||
tmp = REG_SET(MC_FB_TOP, tmp >> 16);
|
||||
tmp |= REG_SET(MC_FB_START, rdev->mc.vram_location >> 16);
|
||||
WREG32_MC(MC_FB_LOCATION, tmp);
|
||||
WREG32(HDP_FB_LOCATION, rdev->mc.vram_location >> 16);
|
||||
WREG32(0x310, rdev->mc.vram_location);
|
||||
if (rdev->flags & RADEON_IS_AGP) {
|
||||
tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
|
||||
tmp = REG_SET(MC_AGP_TOP, tmp >> 16);
|
||||
tmp |= REG_SET(MC_AGP_START, rdev->mc.gtt_location >> 16);
|
||||
WREG32_MC(MC_AGP_LOCATION, tmp);
|
||||
WREG32_MC(MC_AGP_BASE, rdev->mc.agp_base);
|
||||
WREG32_MC(MC_AGP_BASE_2, 0);
|
||||
} else {
|
||||
WREG32_MC(MC_AGP_LOCATION, 0x0FFFFFFF);
|
||||
WREG32_MC(MC_AGP_BASE, 0);
|
||||
WREG32_MC(MC_AGP_BASE_2, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rv515_mc_fini(struct radeon_device *rdev)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Global GPU functions
|
||||
*/
|
||||
void rv515_ring_start(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
@ -198,11 +119,6 @@ void rv515_ring_start(struct radeon_device *rdev)
|
|||
radeon_ring_unlock_commit(rdev);
|
||||
}
|
||||
|
||||
void rv515_errata(struct radeon_device *rdev)
|
||||
{
|
||||
rdev->pll_errata = 0;
|
||||
}
|
||||
|
||||
int rv515_mc_wait_for_idle(struct radeon_device *rdev)
|
||||
{
|
||||
unsigned i;
|
||||
|
@ -219,6 +135,12 @@ int rv515_mc_wait_for_idle(struct radeon_device *rdev)
|
|||
return -1;
|
||||
}
|
||||
|
||||
void rv515_vga_render_disable(struct radeon_device *rdev)
|
||||
{
|
||||
WREG32(R_000300_VGA_RENDER_CONTROL,
|
||||
RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL);
|
||||
}
|
||||
|
||||
void rv515_gpu_init(struct radeon_device *rdev)
|
||||
{
|
||||
unsigned pipe_select_current, gb_pipe_select, tmp;
|
||||
|
@ -231,7 +153,7 @@ void rv515_gpu_init(struct radeon_device *rdev)
|
|||
"reseting GPU. Bad things might happen.\n");
|
||||
}
|
||||
|
||||
rs600_disable_vga(rdev);
|
||||
rv515_vga_render_disable(rdev);
|
||||
|
||||
r420_pipes_init(rdev);
|
||||
gb_pipe_select = RREG32(0x402C);
|
||||
|
@ -335,10 +257,6 @@ int rv515_gpu_reset(struct radeon_device *rdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* VRAM info
|
||||
*/
|
||||
static void rv515_vram_get_type(struct radeon_device *rdev)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
@ -374,10 +292,6 @@ void rv515_vram_info(struct radeon_device *rdev)
|
|||
rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Indirect registers accessor
|
||||
*/
|
||||
uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg)
|
||||
{
|
||||
uint32_t r;
|
||||
|
@ -395,9 +309,6 @@ void rv515_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
|
|||
WREG32(MC_IND_INDEX, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Debugfs info
|
||||
*/
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
static int rv515_debugfs_pipes_info(struct seq_file *m, void *data)
|
||||
{
|
||||
|
@ -459,13 +370,258 @@ int rv515_debugfs_ga_info_init(struct radeon_device *rdev)
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Asic initialization
|
||||
*/
|
||||
int rv515_init(struct radeon_device *rdev)
|
||||
void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save)
|
||||
{
|
||||
save->d1vga_control = RREG32(R_000330_D1VGA_CONTROL);
|
||||
save->d2vga_control = RREG32(R_000338_D2VGA_CONTROL);
|
||||
save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL);
|
||||
save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL);
|
||||
save->d1crtc_control = RREG32(R_006080_D1CRTC_CONTROL);
|
||||
save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL);
|
||||
|
||||
/* Stop all video */
|
||||
WREG32(R_000330_D1VGA_CONTROL, 0);
|
||||
WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
|
||||
WREG32(R_000300_VGA_RENDER_CONTROL, 0);
|
||||
WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1);
|
||||
WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1);
|
||||
WREG32(R_006080_D1CRTC_CONTROL, 0);
|
||||
WREG32(R_006880_D2CRTC_CONTROL, 0);
|
||||
WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0);
|
||||
WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
|
||||
}
|
||||
|
||||
void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save)
|
||||
{
|
||||
WREG32(R_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS, rdev->mc.vram_start);
|
||||
WREG32(R_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS, rdev->mc.vram_start);
|
||||
WREG32(R_006910_D2GRPH_PRIMARY_SURFACE_ADDRESS, rdev->mc.vram_start);
|
||||
WREG32(R_006918_D2GRPH_SECONDARY_SURFACE_ADDRESS, rdev->mc.vram_start);
|
||||
WREG32(R_000310_VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start);
|
||||
/* Unlock host access */
|
||||
WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control);
|
||||
mdelay(1);
|
||||
/* Restore video state */
|
||||
WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1);
|
||||
WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1);
|
||||
WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control);
|
||||
WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control);
|
||||
WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0);
|
||||
WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0);
|
||||
WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control);
|
||||
WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control);
|
||||
WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control);
|
||||
}
|
||||
|
||||
void rv515_mc_program(struct radeon_device *rdev)
|
||||
{
|
||||
struct rv515_mc_save save;
|
||||
|
||||
/* Stops all mc clients */
|
||||
rv515_mc_stop(rdev, &save);
|
||||
|
||||
/* Wait for mc idle */
|
||||
if (rv515_mc_wait_for_idle(rdev))
|
||||
dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n");
|
||||
/* Write VRAM size in case we are limiting it */
|
||||
WREG32(R_0000F8_CONFIG_MEMSIZE, rdev->mc.real_vram_size);
|
||||
/* Program MC, should be a 32bits limited address space */
|
||||
WREG32_MC(R_000001_MC_FB_LOCATION,
|
||||
S_000001_MC_FB_START(rdev->mc.vram_start >> 16) |
|
||||
S_000001_MC_FB_TOP(rdev->mc.vram_end >> 16));
|
||||
WREG32(R_000134_HDP_FB_LOCATION,
|
||||
S_000134_HDP_FB_START(rdev->mc.vram_start >> 16));
|
||||
if (rdev->flags & RADEON_IS_AGP) {
|
||||
WREG32_MC(R_000002_MC_AGP_LOCATION,
|
||||
S_000002_MC_AGP_START(rdev->mc.gtt_start >> 16) |
|
||||
S_000002_MC_AGP_TOP(rdev->mc.gtt_end >> 16));
|
||||
WREG32_MC(R_000003_MC_AGP_BASE, lower_32_bits(rdev->mc.agp_base));
|
||||
WREG32_MC(R_000004_MC_AGP_BASE_2,
|
||||
S_000004_AGP_BASE_ADDR_2(upper_32_bits(rdev->mc.agp_base)));
|
||||
} else {
|
||||
WREG32_MC(R_000002_MC_AGP_LOCATION, 0xFFFFFFFF);
|
||||
WREG32_MC(R_000003_MC_AGP_BASE, 0);
|
||||
WREG32_MC(R_000004_MC_AGP_BASE_2, 0);
|
||||
}
|
||||
|
||||
rv515_mc_resume(rdev, &save);
|
||||
}
|
||||
|
||||
void rv515_clock_startup(struct radeon_device *rdev)
|
||||
{
|
||||
if (radeon_dynclks != -1 && radeon_dynclks)
|
||||
radeon_atom_set_clock_gating(rdev, 1);
|
||||
/* We need to force on some of the block */
|
||||
WREG32_PLL(R_00000F_CP_DYN_CNTL,
|
||||
RREG32_PLL(R_00000F_CP_DYN_CNTL) | S_00000F_CP_FORCEON(1));
|
||||
WREG32_PLL(R_000011_E2_DYN_CNTL,
|
||||
RREG32_PLL(R_000011_E2_DYN_CNTL) | S_000011_E2_FORCEON(1));
|
||||
WREG32_PLL(R_000013_IDCT_DYN_CNTL,
|
||||
RREG32_PLL(R_000013_IDCT_DYN_CNTL) | S_000013_IDCT_FORCEON(1));
|
||||
}
|
||||
|
||||
static int rv515_startup(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
rv515_mc_program(rdev);
|
||||
/* Resume clock */
|
||||
rv515_clock_startup(rdev);
|
||||
/* Initialize GPU configuration (# pipes, ...) */
|
||||
rv515_gpu_init(rdev);
|
||||
/* Initialize GART (initialize after TTM so we can allocate
|
||||
* memory through TTM but finalize after TTM) */
|
||||
if (rdev->flags & RADEON_IS_PCIE) {
|
||||
r = rv370_pcie_gart_enable(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
/* Enable IRQ */
|
||||
rdev->irq.sw_int = true;
|
||||
r100_irq_set(rdev);
|
||||
/* 1M ring buffer */
|
||||
r = r100_cp_init(rdev, 1024 * 1024);
|
||||
if (r) {
|
||||
dev_err(rdev->dev, "failled initializing CP (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
r = r100_wb_init(rdev);
|
||||
if (r)
|
||||
dev_err(rdev->dev, "failled initializing WB (%d).\n", r);
|
||||
r = r100_ib_init(rdev);
|
||||
if (r) {
|
||||
dev_err(rdev->dev, "failled initializing IB (%d).\n", r);
|
||||
return r;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rv515_resume(struct radeon_device *rdev)
|
||||
{
|
||||
/* Make sur GART are not working */
|
||||
if (rdev->flags & RADEON_IS_PCIE)
|
||||
rv370_pcie_gart_disable(rdev);
|
||||
/* Resume clock before doing reset */
|
||||
rv515_clock_startup(rdev);
|
||||
/* Reset gpu before posting otherwise ATOM will enter infinite loop */
|
||||
if (radeon_gpu_reset(rdev)) {
|
||||
dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
|
||||
RREG32(R_000E40_RBBM_STATUS),
|
||||
RREG32(R_0007C0_CP_STAT));
|
||||
}
|
||||
/* post */
|
||||
atom_asic_init(rdev->mode_info.atom_context);
|
||||
/* Resume clock after posting */
|
||||
rv515_clock_startup(rdev);
|
||||
return rv515_startup(rdev);
|
||||
}
|
||||
|
||||
int rv515_suspend(struct radeon_device *rdev)
|
||||
{
|
||||
r100_cp_disable(rdev);
|
||||
r100_wb_disable(rdev);
|
||||
r100_irq_disable(rdev);
|
||||
if (rdev->flags & RADEON_IS_PCIE)
|
||||
rv370_pcie_gart_disable(rdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void rv515_set_safe_registers(struct radeon_device *rdev)
|
||||
{
|
||||
rdev->config.r300.reg_safe_bm = rv515_reg_safe_bm;
|
||||
rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rv515_reg_safe_bm);
|
||||
}
|
||||
|
||||
void rv515_fini(struct radeon_device *rdev)
|
||||
{
|
||||
rv515_suspend(rdev);
|
||||
r100_cp_fini(rdev);
|
||||
r100_wb_fini(rdev);
|
||||
r100_ib_fini(rdev);
|
||||
radeon_gem_fini(rdev);
|
||||
rv370_pcie_gart_fini(rdev);
|
||||
radeon_agp_fini(rdev);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
radeon_fence_driver_fini(rdev);
|
||||
radeon_object_fini(rdev);
|
||||
radeon_atombios_fini(rdev);
|
||||
kfree(rdev->bios);
|
||||
rdev->bios = NULL;
|
||||
}
|
||||
|
||||
int rv515_init(struct radeon_device *rdev)
|
||||
{
|
||||
int r;
|
||||
|
||||
rdev->new_init_path = true;
|
||||
/* Initialize scratch registers */
|
||||
radeon_scratch_init(rdev);
|
||||
/* Initialize surface registers */
|
||||
radeon_surface_init(rdev);
|
||||
/* TODO: disable VGA need to use VGA request */
|
||||
/* BIOS*/
|
||||
if (!radeon_get_bios(rdev)) {
|
||||
if (ASIC_IS_AVIVO(rdev))
|
||||
return -EINVAL;
|
||||
}
|
||||
if (rdev->is_atom_bios) {
|
||||
r = radeon_atombios_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
} else {
|
||||
dev_err(rdev->dev, "Expecting atombios for RV515 GPU\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
/* Reset gpu before posting otherwise ATOM will enter infinite loop */
|
||||
if (radeon_gpu_reset(rdev)) {
|
||||
dev_warn(rdev->dev,
|
||||
"GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n",
|
||||
RREG32(R_000E40_RBBM_STATUS),
|
||||
RREG32(R_0007C0_CP_STAT));
|
||||
}
|
||||
/* check if cards are posted or not */
|
||||
if (!radeon_card_posted(rdev) && rdev->bios) {
|
||||
DRM_INFO("GPU not posted. posting now...\n");
|
||||
atom_asic_init(rdev->mode_info.atom_context);
|
||||
}
|
||||
/* Initialize clocks */
|
||||
radeon_get_clock_info(rdev->ddev);
|
||||
/* Get vram informations */
|
||||
rv515_vram_info(rdev);
|
||||
/* Initialize memory controller (also test AGP) */
|
||||
r = r420_mc_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
rv515_debugfs(rdev);
|
||||
/* Fence driver */
|
||||
r = radeon_fence_driver_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
r = radeon_irq_kms_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
/* Memory manager */
|
||||
r = radeon_object_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
r = rv370_pcie_gart_init(rdev);
|
||||
if (r)
|
||||
return r;
|
||||
rv515_set_safe_registers(rdev);
|
||||
rdev->accel_working = true;
|
||||
r = rv515_startup(rdev);
|
||||
if (r) {
|
||||
/* Somethings want wront with the accel init stop accel */
|
||||
dev_err(rdev->dev, "Disabling GPU acceleration\n");
|
||||
rv515_suspend(rdev);
|
||||
r100_cp_fini(rdev);
|
||||
r100_wb_fini(rdev);
|
||||
r100_ib_fini(rdev);
|
||||
rv370_pcie_gart_fini(rdev);
|
||||
radeon_agp_fini(rdev);
|
||||
radeon_irq_kms_fini(rdev);
|
||||
rdev->accel_working = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -216,5 +216,388 @@
|
|||
#define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1)
|
||||
#define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF)
|
||||
|
||||
#endif
|
||||
/* Registers */
|
||||
#define R_0000F8_CONFIG_MEMSIZE 0x0000F8
|
||||
#define S_0000F8_CONFIG_MEMSIZE(x) (((x) & 0xFFFFFFFF) << 0)
|
||||
#define G_0000F8_CONFIG_MEMSIZE(x) (((x) >> 0) & 0xFFFFFFFF)
|
||||
#define C_0000F8_CONFIG_MEMSIZE 0x00000000
|
||||
#define R_000134_HDP_FB_LOCATION 0x000134
|
||||
#define S_000134_HDP_FB_START(x) (((x) & 0xFFFF) << 0)
|
||||
#define G_000134_HDP_FB_START(x) (((x) >> 0) & 0xFFFF)
|
||||
#define C_000134_HDP_FB_START 0xFFFF0000
|
||||
#define R_000300_VGA_RENDER_CONTROL 0x000300
|
||||
#define S_000300_VGA_BLINK_RATE(x) (((x) & 0x1F) << 0)
|
||||
#define G_000300_VGA_BLINK_RATE(x) (((x) >> 0) & 0x1F)
|
||||
#define C_000300_VGA_BLINK_RATE 0xFFFFFFE0
|
||||
#define S_000300_VGA_BLINK_MODE(x) (((x) & 0x3) << 5)
|
||||
#define G_000300_VGA_BLINK_MODE(x) (((x) >> 5) & 0x3)
|
||||
#define C_000300_VGA_BLINK_MODE 0xFFFFFF9F
|
||||
#define S_000300_VGA_CURSOR_BLINK_INVERT(x) (((x) & 0x1) << 7)
|
||||
#define G_000300_VGA_CURSOR_BLINK_INVERT(x) (((x) >> 7) & 0x1)
|
||||
#define C_000300_VGA_CURSOR_BLINK_INVERT 0xFFFFFF7F
|
||||
#define S_000300_VGA_EXTD_ADDR_COUNT_ENABLE(x) (((x) & 0x1) << 8)
|
||||
#define G_000300_VGA_EXTD_ADDR_COUNT_ENABLE(x) (((x) >> 8) & 0x1)
|
||||
#define C_000300_VGA_EXTD_ADDR_COUNT_ENABLE 0xFFFFFEFF
|
||||
#define S_000300_VGA_VSTATUS_CNTL(x) (((x) & 0x3) << 16)
|
||||
#define G_000300_VGA_VSTATUS_CNTL(x) (((x) >> 16) & 0x3)
|
||||
#define C_000300_VGA_VSTATUS_CNTL 0xFFFCFFFF
|
||||
#define S_000300_VGA_LOCK_8DOT(x) (((x) & 0x1) << 24)
|
||||
#define G_000300_VGA_LOCK_8DOT(x) (((x) >> 24) & 0x1)
|
||||
#define C_000300_VGA_LOCK_8DOT 0xFEFFFFFF
|
||||
#define S_000300_VGAREG_LINECMP_COMPATIBILITY_SEL(x) (((x) & 0x1) << 25)
|
||||
#define G_000300_VGAREG_LINECMP_COMPATIBILITY_SEL(x) (((x) >> 25) & 0x1)
|
||||
#define C_000300_VGAREG_LINECMP_COMPATIBILITY_SEL 0xFDFFFFFF
|
||||
#define R_000310_VGA_MEMORY_BASE_ADDRESS 0x000310
|
||||
#define S_000310_VGA_MEMORY_BASE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0)
|
||||
#define G_000310_VGA_MEMORY_BASE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF)
|
||||
#define C_000310_VGA_MEMORY_BASE_ADDRESS 0x00000000
|
||||
#define R_000328_VGA_HDP_CONTROL 0x000328
|
||||
#define S_000328_VGA_MEM_PAGE_SELECT_EN(x) (((x) & 0x1) << 0)
|
||||
#define G_000328_VGA_MEM_PAGE_SELECT_EN(x) (((x) >> 0) & 0x1)
|
||||
#define C_000328_VGA_MEM_PAGE_SELECT_EN 0xFFFFFFFE
|
||||
#define S_000328_VGA_RBBM_LOCK_DISABLE(x) (((x) & 0x1) << 8)
|
||||
#define G_000328_VGA_RBBM_LOCK_DISABLE(x) (((x) >> 8) & 0x1)
|
||||
#define C_000328_VGA_RBBM_LOCK_DISABLE 0xFFFFFEFF
|
||||
#define S_000328_VGA_SOFT_RESET(x) (((x) & 0x1) << 16)
|
||||
#define G_000328_VGA_SOFT_RESET(x) (((x) >> 16) & 0x1)
|
||||
#define C_000328_VGA_SOFT_RESET 0xFFFEFFFF
|
||||
#define S_000328_VGA_TEST_RESET_CONTROL(x) (((x) & 0x1) << 24)
|
||||
#define G_000328_VGA_TEST_RESET_CONTROL(x) (((x) >> 24) & 0x1)
|
||||
#define C_000328_VGA_TEST_RESET_CONTROL 0xFEFFFFFF
|
||||
#define R_000330_D1VGA_CONTROL 0x000330
|
||||
#define S_000330_D1VGA_MODE_ENABLE(x) (((x) & 0x1) << 0)
|
||||
#define G_000330_D1VGA_MODE_ENABLE(x) (((x) >> 0) & 0x1)
|
||||
#define C_000330_D1VGA_MODE_ENABLE 0xFFFFFFFE
|
||||
#define S_000330_D1VGA_TIMING_SELECT(x) (((x) & 0x1) << 8)
|
||||
#define G_000330_D1VGA_TIMING_SELECT(x) (((x) >> 8) & 0x1)
|
||||
#define C_000330_D1VGA_TIMING_SELECT 0xFFFFFEFF
|
||||
#define S_000330_D1VGA_SYNC_POLARITY_SELECT(x) (((x) & 0x1) << 9)
|
||||
#define G_000330_D1VGA_SYNC_POLARITY_SELECT(x) (((x) >> 9) & 0x1)
|
||||
#define C_000330_D1VGA_SYNC_POLARITY_SELECT 0xFFFFFDFF
|
||||
#define S_000330_D1VGA_OVERSCAN_TIMING_SELECT(x) (((x) & 0x1) << 10)
|
||||
#define G_000330_D1VGA_OVERSCAN_TIMING_SELECT(x) (((x) >> 10) & 0x1)
|
||||
#define C_000330_D1VGA_OVERSCAN_TIMING_SELECT 0xFFFFFBFF
|
||||
#define S_000330_D1VGA_OVERSCAN_COLOR_EN(x) (((x) & 0x1) << 16)
|
||||
#define G_000330_D1VGA_OVERSCAN_COLOR_EN(x) (((x) >> 16) & 0x1)
|
||||
#define C_000330_D1VGA_OVERSCAN_COLOR_EN 0xFFFEFFFF
|
||||
#define S_000330_D1VGA_ROTATE(x) (((x) & 0x3) << 24)
|
||||
#define G_000330_D1VGA_ROTATE(x) (((x) >> 24) & 0x3)
|
||||
#define C_000330_D1VGA_ROTATE 0xFCFFFFFF
|
||||
#define R_000338_D2VGA_CONTROL 0x000338
|
||||
#define S_000338_D2VGA_MODE_ENABLE(x) (((x) & 0x1) << 0)
|
||||
#define G_000338_D2VGA_MODE_ENABLE(x) (((x) >> 0) & 0x1)
|
||||
#define C_000338_D2VGA_MODE_ENABLE 0xFFFFFFFE
|
||||
#define S_000338_D2VGA_TIMING_SELECT(x) (((x) & 0x1) << 8)
|
||||
#define G_000338_D2VGA_TIMING_SELECT(x) (((x) >> 8) & 0x1)
|
||||
#define C_000338_D2VGA_TIMING_SELECT 0xFFFFFEFF
|
||||
#define S_000338_D2VGA_SYNC_POLARITY_SELECT(x) (((x) & 0x1) << 9)
|
||||
#define G_000338_D2VGA_SYNC_POLARITY_SELECT(x) (((x) >> 9) & 0x1)
|
||||
#define C_000338_D2VGA_SYNC_POLARITY_SELECT 0xFFFFFDFF
|
||||
#define S_000338_D2VGA_OVERSCAN_TIMING_SELECT(x) (((x) & 0x1) << 10)
|
||||
#define G_000338_D2VGA_OVERSCAN_TIMING_SELECT(x) (((x) >> 10) & 0x1)
|
||||
#define C_000338_D2VGA_OVERSCAN_TIMING_SELECT 0xFFFFFBFF
|
||||
#define S_000338_D2VGA_OVERSCAN_COLOR_EN(x) (((x) & 0x1) << 16)
|
||||
#define G_000338_D2VGA_OVERSCAN_COLOR_EN(x) (((x) >> 16) & 0x1)
|
||||
#define C_000338_D2VGA_OVERSCAN_COLOR_EN 0xFFFEFFFF
|
||||
#define S_000338_D2VGA_ROTATE(x) (((x) & 0x3) << 24)
|
||||
#define G_000338_D2VGA_ROTATE(x) (((x) >> 24) & 0x3)
|
||||
#define C_000338_D2VGA_ROTATE 0xFCFFFFFF
|
||||
#define R_0007C0_CP_STAT 0x0007C0
|
||||
#define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0)
|
||||
#define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1)
|
||||
#define C_0007C0_MRU_BUSY 0xFFFFFFFE
|
||||
#define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1)
|
||||
#define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1)
|
||||
#define C_0007C0_MWU_BUSY 0xFFFFFFFD
|
||||
#define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2)
|
||||
#define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1)
|
||||
#define C_0007C0_RSIU_BUSY 0xFFFFFFFB
|
||||
#define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3)
|
||||
#define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1)
|
||||
#define C_0007C0_RCIU_BUSY 0xFFFFFFF7
|
||||
#define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9)
|
||||
#define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1)
|
||||
#define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF
|
||||
#define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10)
|
||||
#define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1)
|
||||
#define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF
|
||||
#define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11)
|
||||
#define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1)
|
||||
#define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF
|
||||
#define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12)
|
||||
#define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1)
|
||||
#define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF
|
||||
#define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13)
|
||||
#define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1)
|
||||
#define C_0007C0_CSI_BUSY 0xFFFFDFFF
|
||||
#define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14)
|
||||
#define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1)
|
||||
#define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF
|
||||
#define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15)
|
||||
#define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1)
|
||||
#define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF
|
||||
#define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28)
|
||||
#define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1)
|
||||
#define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF
|
||||
#define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29)
|
||||
#define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1)
|
||||
#define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF
|
||||
#define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30)
|
||||
#define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1)
|
||||
#define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF
|
||||
#define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31)
|
||||
#define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1)
|
||||
#define C_0007C0_CP_BUSY 0x7FFFFFFF
|
||||
#define R_000E40_RBBM_STATUS 0x000E40
|
||||
#define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0)
|
||||
#define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F)
|
||||
#define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80
|
||||
#define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8)
|
||||
#define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1)
|
||||
#define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF
|
||||
#define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9)
|
||||
#define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1)
|
||||
#define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF
|
||||
#define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10)
|
||||
#define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1)
|
||||
#define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF
|
||||
#define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11)
|
||||
#define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1)
|
||||
#define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF
|
||||
#define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12)
|
||||
#define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1)
|
||||
#define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF
|
||||
#define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13)
|
||||
#define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1)
|
||||
#define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF
|
||||
#define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14)
|
||||
#define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1)
|
||||
#define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF
|
||||
#define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15)
|
||||
#define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1)
|
||||
#define C_000E40_ENG_EV_BUSY 0xFFFF7FFF
|
||||
#define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16)
|
||||
#define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1)
|
||||
#define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF
|
||||
#define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17)
|
||||
#define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1)
|
||||
#define C_000E40_E2_BUSY 0xFFFDFFFF
|
||||
#define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18)
|
||||
#define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1)
|
||||
#define C_000E40_RB2D_BUSY 0xFFFBFFFF
|
||||
#define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19)
|
||||
#define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1)
|
||||
#define C_000E40_RB3D_BUSY 0xFFF7FFFF
|
||||
#define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20)
|
||||
#define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1)
|
||||
#define C_000E40_VAP_BUSY 0xFFEFFFFF
|
||||
#define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21)
|
||||
#define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1)
|
||||
#define C_000E40_RE_BUSY 0xFFDFFFFF
|
||||
#define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22)
|
||||
#define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1)
|
||||
#define C_000E40_TAM_BUSY 0xFFBFFFFF
|
||||
#define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23)
|
||||
#define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1)
|
||||
#define C_000E40_TDM_BUSY 0xFF7FFFFF
|
||||
#define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24)
|
||||
#define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1)
|
||||
#define C_000E40_PB_BUSY 0xFEFFFFFF
|
||||
#define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25)
|
||||
#define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1)
|
||||
#define C_000E40_TIM_BUSY 0xFDFFFFFF
|
||||
#define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26)
|
||||
#define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1)
|
||||
#define C_000E40_GA_BUSY 0xFBFFFFFF
|
||||
#define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27)
|
||||
#define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1)
|
||||
#define C_000E40_CBA2D_BUSY 0xF7FFFFFF
|
||||
#define S_000E40_RBBM_HIBUSY(x) (((x) & 0x1) << 28)
|
||||
#define G_000E40_RBBM_HIBUSY(x) (((x) >> 28) & 0x1)
|
||||
#define C_000E40_RBBM_HIBUSY 0xEFFFFFFF
|
||||
#define S_000E40_SKID_CFBUSY(x) (((x) & 0x1) << 29)
|
||||
#define G_000E40_SKID_CFBUSY(x) (((x) >> 29) & 0x1)
|
||||
#define C_000E40_SKID_CFBUSY 0xDFFFFFFF
|
||||
#define S_000E40_VAP_VF_BUSY(x) (((x) & 0x1) << 30)
|
||||
#define G_000E40_VAP_VF_BUSY(x) (((x) >> 30) & 0x1)
|
||||
#define C_000E40_VAP_VF_BUSY 0xBFFFFFFF
|
||||
#define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31)
|
||||
#define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1)
|
||||
#define C_000E40_GUI_ACTIVE 0x7FFFFFFF
|
||||
#define R_006080_D1CRTC_CONTROL 0x006080
|
||||
#define S_006080_D1CRTC_MASTER_EN(x) (((x) & 0x1) << 0)
|
||||
#define G_006080_D1CRTC_MASTER_EN(x) (((x) >> 0) & 0x1)
|
||||
#define C_006080_D1CRTC_MASTER_EN 0xFFFFFFFE
|
||||
#define S_006080_D1CRTC_SYNC_RESET_SEL(x) (((x) & 0x1) << 4)
|
||||
#define G_006080_D1CRTC_SYNC_RESET_SEL(x) (((x) >> 4) & 0x1)
|
||||
#define C_006080_D1CRTC_SYNC_RESET_SEL 0xFFFFFFEF
|
||||
#define S_006080_D1CRTC_DISABLE_POINT_CNTL(x) (((x) & 0x3) << 8)
|
||||
#define G_006080_D1CRTC_DISABLE_POINT_CNTL(x) (((x) >> 8) & 0x3)
|
||||
#define C_006080_D1CRTC_DISABLE_POINT_CNTL 0xFFFFFCFF
|
||||
#define S_006080_D1CRTC_CURRENT_MASTER_EN_STATE(x) (((x) & 0x1) << 16)
|
||||
#define G_006080_D1CRTC_CURRENT_MASTER_EN_STATE(x) (((x) >> 16) & 0x1)
|
||||
#define C_006080_D1CRTC_CURRENT_MASTER_EN_STATE 0xFFFEFFFF
|
||||
#define S_006080_D1CRTC_DISP_READ_REQUEST_DISABLE(x) (((x) & 0x1) << 24)
|
||||
#define G_006080_D1CRTC_DISP_READ_REQUEST_DISABLE(x) (((x) >> 24) & 0x1)
|
||||
#define C_006080_D1CRTC_DISP_READ_REQUEST_DISABLE 0xFEFFFFFF
|
||||
#define R_0060E8_D1CRTC_UPDATE_LOCK 0x0060E8
|
||||
#define S_0060E8_D1CRTC_UPDATE_LOCK(x) (((x) & 0x1) << 0)
|
||||
#define G_0060E8_D1CRTC_UPDATE_LOCK(x) (((x) >> 0) & 0x1)
|
||||
#define C_0060E8_D1CRTC_UPDATE_LOCK 0xFFFFFFFE
|
||||
#define R_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x006110
|
||||
#define S_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0)
|
||||
#define G_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF)
|
||||
#define C_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x00000000
|
||||
#define R_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS 0x006118
|
||||
#define S_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0)
|
||||
#define G_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF)
|
||||
#define C_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS 0x00000000
|
||||
#define R_006880_D2CRTC_CONTROL 0x006880
|
||||
#define S_006880_D2CRTC_MASTER_EN(x) (((x) & 0x1) << 0)
|
||||
#define G_006880_D2CRTC_MASTER_EN(x) (((x) >> 0) & 0x1)
|
||||
#define C_006880_D2CRTC_MASTER_EN 0xFFFFFFFE
|
||||
#define S_006880_D2CRTC_SYNC_RESET_SEL(x) (((x) & 0x1) << 4)
|
||||
#define G_006880_D2CRTC_SYNC_RESET_SEL(x) (((x) >> 4) & 0x1)
|
||||
#define C_006880_D2CRTC_SYNC_RESET_SEL 0xFFFFFFEF
|
||||
#define S_006880_D2CRTC_DISABLE_POINT_CNTL(x) (((x) & 0x3) << 8)
|
||||
#define G_006880_D2CRTC_DISABLE_POINT_CNTL(x) (((x) >> 8) & 0x3)
|
||||
#define C_006880_D2CRTC_DISABLE_POINT_CNTL 0xFFFFFCFF
|
||||
#define S_006880_D2CRTC_CURRENT_MASTER_EN_STATE(x) (((x) & 0x1) << 16)
|
||||
#define G_006880_D2CRTC_CURRENT_MASTER_EN_STATE(x) (((x) >> 16) & 0x1)
|
||||
#define C_006880_D2CRTC_CURRENT_MASTER_EN_STATE 0xFFFEFFFF
|
||||
#define S_006880_D2CRTC_DISP_READ_REQUEST_DISABLE(x) (((x) & 0x1) << 24)
|
||||
#define G_006880_D2CRTC_DISP_READ_REQUEST_DISABLE(x) (((x) >> 24) & 0x1)
|
||||
#define C_006880_D2CRTC_DISP_READ_REQUEST_DISABLE 0xFEFFFFFF
|
||||
#define R_0068E8_D2CRTC_UPDATE_LOCK 0x0068E8
|
||||
#define S_0068E8_D2CRTC_UPDATE_LOCK(x) (((x) & 0x1) << 0)
|
||||
#define G_0068E8_D2CRTC_UPDATE_LOCK(x) (((x) >> 0) & 0x1)
|
||||
#define C_0068E8_D2CRTC_UPDATE_LOCK 0xFFFFFFFE
|
||||
#define R_006910_D2GRPH_PRIMARY_SURFACE_ADDRESS 0x006910
|
||||
#define S_006910_D2GRPH_PRIMARY_SURFACE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0)
|
||||
#define G_006910_D2GRPH_PRIMARY_SURFACE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF)
|
||||
#define C_006910_D2GRPH_PRIMARY_SURFACE_ADDRESS 0x00000000
|
||||
#define R_006918_D2GRPH_SECONDARY_SURFACE_ADDRESS 0x006918
|
||||
#define S_006918_D2GRPH_SECONDARY_SURFACE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0)
|
||||
#define G_006918_D2GRPH_SECONDARY_SURFACE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF)
|
||||
#define C_006918_D2GRPH_SECONDARY_SURFACE_ADDRESS 0x00000000
|
||||
|
||||
|
||||
#define R_000001_MC_FB_LOCATION 0x000001
|
||||
#define S_000001_MC_FB_START(x) (((x) & 0xFFFF) << 0)
|
||||
#define G_000001_MC_FB_START(x) (((x) >> 0) & 0xFFFF)
|
||||
#define C_000001_MC_FB_START 0xFFFF0000
|
||||
#define S_000001_MC_FB_TOP(x) (((x) & 0xFFFF) << 16)
|
||||
#define G_000001_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF)
|
||||
#define C_000001_MC_FB_TOP 0x0000FFFF
|
||||
#define R_000002_MC_AGP_LOCATION 0x000002
|
||||
#define S_000002_MC_AGP_START(x) (((x) & 0xFFFF) << 0)
|
||||
#define G_000002_MC_AGP_START(x) (((x) >> 0) & 0xFFFF)
|
||||
#define C_000002_MC_AGP_START 0xFFFF0000
|
||||
#define S_000002_MC_AGP_TOP(x) (((x) & 0xFFFF) << 16)
|
||||
#define G_000002_MC_AGP_TOP(x) (((x) >> 16) & 0xFFFF)
|
||||
#define C_000002_MC_AGP_TOP 0x0000FFFF
|
||||
#define R_000003_MC_AGP_BASE 0x000003
|
||||
#define S_000003_AGP_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0)
|
||||
#define G_000003_AGP_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF)
|
||||
#define C_000003_AGP_BASE_ADDR 0x00000000
|
||||
#define R_000004_MC_AGP_BASE_2 0x000004
|
||||
#define S_000004_AGP_BASE_ADDR_2(x) (((x) & 0xF) << 0)
|
||||
#define G_000004_AGP_BASE_ADDR_2(x) (((x) >> 0) & 0xF)
|
||||
#define C_000004_AGP_BASE_ADDR_2 0xFFFFFFF0
|
||||
|
||||
|
||||
#define R_00000F_CP_DYN_CNTL 0x00000F
|
||||
#define S_00000F_CP_FORCEON(x) (((x) & 0x1) << 0)
|
||||
#define G_00000F_CP_FORCEON(x) (((x) >> 0) & 0x1)
|
||||
#define C_00000F_CP_FORCEON 0xFFFFFFFE
|
||||
#define S_00000F_CP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 1)
|
||||
#define G_00000F_CP_MAX_DYN_STOP_LAT(x) (((x) >> 1) & 0x1)
|
||||
#define C_00000F_CP_MAX_DYN_STOP_LAT 0xFFFFFFFD
|
||||
#define S_00000F_CP_CLOCK_STATUS(x) (((x) & 0x1) << 2)
|
||||
#define G_00000F_CP_CLOCK_STATUS(x) (((x) >> 2) & 0x1)
|
||||
#define C_00000F_CP_CLOCK_STATUS 0xFFFFFFFB
|
||||
#define S_00000F_CP_PROG_SHUTOFF(x) (((x) & 0x1) << 3)
|
||||
#define G_00000F_CP_PROG_SHUTOFF(x) (((x) >> 3) & 0x1)
|
||||
#define C_00000F_CP_PROG_SHUTOFF 0xFFFFFFF7
|
||||
#define S_00000F_CP_PROG_DELAY_VALUE(x) (((x) & 0xFF) << 4)
|
||||
#define G_00000F_CP_PROG_DELAY_VALUE(x) (((x) >> 4) & 0xFF)
|
||||
#define C_00000F_CP_PROG_DELAY_VALUE 0xFFFFF00F
|
||||
#define S_00000F_CP_LOWER_POWER_IDLE(x) (((x) & 0xFF) << 12)
|
||||
#define G_00000F_CP_LOWER_POWER_IDLE(x) (((x) >> 12) & 0xFF)
|
||||
#define C_00000F_CP_LOWER_POWER_IDLE 0xFFF00FFF
|
||||
#define S_00000F_CP_LOWER_POWER_IGNORE(x) (((x) & 0x1) << 20)
|
||||
#define G_00000F_CP_LOWER_POWER_IGNORE(x) (((x) >> 20) & 0x1)
|
||||
#define C_00000F_CP_LOWER_POWER_IGNORE 0xFFEFFFFF
|
||||
#define S_00000F_CP_NORMAL_POWER_IGNORE(x) (((x) & 0x1) << 21)
|
||||
#define G_00000F_CP_NORMAL_POWER_IGNORE(x) (((x) >> 21) & 0x1)
|
||||
#define C_00000F_CP_NORMAL_POWER_IGNORE 0xFFDFFFFF
|
||||
#define S_00000F_SPARE(x) (((x) & 0x3) << 22)
|
||||
#define G_00000F_SPARE(x) (((x) >> 22) & 0x3)
|
||||
#define C_00000F_SPARE 0xFF3FFFFF
|
||||
#define S_00000F_CP_NORMAL_POWER_BUSY(x) (((x) & 0xFF) << 24)
|
||||
#define G_00000F_CP_NORMAL_POWER_BUSY(x) (((x) >> 24) & 0xFF)
|
||||
#define C_00000F_CP_NORMAL_POWER_BUSY 0x00FFFFFF
|
||||
#define R_000011_E2_DYN_CNTL 0x000011
|
||||
#define S_000011_E2_FORCEON(x) (((x) & 0x1) << 0)
|
||||
#define G_000011_E2_FORCEON(x) (((x) >> 0) & 0x1)
|
||||
#define C_000011_E2_FORCEON 0xFFFFFFFE
|
||||
#define S_000011_E2_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 1)
|
||||
#define G_000011_E2_MAX_DYN_STOP_LAT(x) (((x) >> 1) & 0x1)
|
||||
#define C_000011_E2_MAX_DYN_STOP_LAT 0xFFFFFFFD
|
||||
#define S_000011_E2_CLOCK_STATUS(x) (((x) & 0x1) << 2)
|
||||
#define G_000011_E2_CLOCK_STATUS(x) (((x) >> 2) & 0x1)
|
||||
#define C_000011_E2_CLOCK_STATUS 0xFFFFFFFB
|
||||
#define S_000011_E2_PROG_SHUTOFF(x) (((x) & 0x1) << 3)
|
||||
#define G_000011_E2_PROG_SHUTOFF(x) (((x) >> 3) & 0x1)
|
||||
#define C_000011_E2_PROG_SHUTOFF 0xFFFFFFF7
|
||||
#define S_000011_E2_PROG_DELAY_VALUE(x) (((x) & 0xFF) << 4)
|
||||
#define G_000011_E2_PROG_DELAY_VALUE(x) (((x) >> 4) & 0xFF)
|
||||
#define C_000011_E2_PROG_DELAY_VALUE 0xFFFFF00F
|
||||
#define S_000011_E2_LOWER_POWER_IDLE(x) (((x) & 0xFF) << 12)
|
||||
#define G_000011_E2_LOWER_POWER_IDLE(x) (((x) >> 12) & 0xFF)
|
||||
#define C_000011_E2_LOWER_POWER_IDLE 0xFFF00FFF
|
||||
#define S_000011_E2_LOWER_POWER_IGNORE(x) (((x) & 0x1) << 20)
|
||||
#define G_000011_E2_LOWER_POWER_IGNORE(x) (((x) >> 20) & 0x1)
|
||||
#define C_000011_E2_LOWER_POWER_IGNORE 0xFFEFFFFF
|
||||
#define S_000011_E2_NORMAL_POWER_IGNORE(x) (((x) & 0x1) << 21)
|
||||
#define G_000011_E2_NORMAL_POWER_IGNORE(x) (((x) >> 21) & 0x1)
|
||||
#define C_000011_E2_NORMAL_POWER_IGNORE 0xFFDFFFFF
|
||||
#define S_000011_SPARE(x) (((x) & 0x3) << 22)
|
||||
#define G_000011_SPARE(x) (((x) >> 22) & 0x3)
|
||||
#define C_000011_SPARE 0xFF3FFFFF
|
||||
#define S_000011_E2_NORMAL_POWER_BUSY(x) (((x) & 0xFF) << 24)
|
||||
#define G_000011_E2_NORMAL_POWER_BUSY(x) (((x) >> 24) & 0xFF)
|
||||
#define C_000011_E2_NORMAL_POWER_BUSY 0x00FFFFFF
|
||||
#define R_000013_IDCT_DYN_CNTL 0x000013
|
||||
#define S_000013_IDCT_FORCEON(x) (((x) & 0x1) << 0)
|
||||
#define G_000013_IDCT_FORCEON(x) (((x) >> 0) & 0x1)
|
||||
#define C_000013_IDCT_FORCEON 0xFFFFFFFE
|
||||
#define S_000013_IDCT_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 1)
|
||||
#define G_000013_IDCT_MAX_DYN_STOP_LAT(x) (((x) >> 1) & 0x1)
|
||||
#define C_000013_IDCT_MAX_DYN_STOP_LAT 0xFFFFFFFD
|
||||
#define S_000013_IDCT_CLOCK_STATUS(x) (((x) & 0x1) << 2)
|
||||
#define G_000013_IDCT_CLOCK_STATUS(x) (((x) >> 2) & 0x1)
|
||||
#define C_000013_IDCT_CLOCK_STATUS 0xFFFFFFFB
|
||||
#define S_000013_IDCT_PROG_SHUTOFF(x) (((x) & 0x1) << 3)
|
||||
#define G_000013_IDCT_PROG_SHUTOFF(x) (((x) >> 3) & 0x1)
|
||||
#define C_000013_IDCT_PROG_SHUTOFF 0xFFFFFFF7
|
||||
#define S_000013_IDCT_PROG_DELAY_VALUE(x) (((x) & 0xFF) << 4)
|
||||
#define G_000013_IDCT_PROG_DELAY_VALUE(x) (((x) >> 4) & 0xFF)
|
||||
#define C_000013_IDCT_PROG_DELAY_VALUE 0xFFFFF00F
|
||||
#define S_000013_IDCT_LOWER_POWER_IDLE(x) (((x) & 0xFF) << 12)
|
||||
#define G_000013_IDCT_LOWER_POWER_IDLE(x) (((x) >> 12) & 0xFF)
|
||||
#define C_000013_IDCT_LOWER_POWER_IDLE 0xFFF00FFF
|
||||
#define S_000013_IDCT_LOWER_POWER_IGNORE(x) (((x) & 0x1) << 20)
|
||||
#define G_000013_IDCT_LOWER_POWER_IGNORE(x) (((x) >> 20) & 0x1)
|
||||
#define C_000013_IDCT_LOWER_POWER_IGNORE 0xFFEFFFFF
|
||||
#define S_000013_IDCT_NORMAL_POWER_IGNORE(x) (((x) & 0x1) << 21)
|
||||
#define G_000013_IDCT_NORMAL_POWER_IGNORE(x) (((x) >> 21) & 0x1)
|
||||
#define C_000013_IDCT_NORMAL_POWER_IGNORE 0xFFDFFFFF
|
||||
#define S_000013_SPARE(x) (((x) & 0x3) << 22)
|
||||
#define G_000013_SPARE(x) (((x) >> 22) & 0x3)
|
||||
#define C_000013_SPARE 0xFF3FFFFF
|
||||
#define S_000013_IDCT_NORMAL_POWER_BUSY(x) (((x) & 0xFF) << 24)
|
||||
#define G_000013_IDCT_NORMAL_POWER_BUSY(x) (((x) >> 24) & 0xFF)
|
||||
#define C_000013_IDCT_NORMAL_POWER_BUSY 0x00FFFFFF
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
#include "radeon.h"
|
||||
#include "radeon_drm.h"
|
||||
#include "rv770d.h"
|
||||
#include "avivod.h"
|
||||
#include "atom.h"
|
||||
#include "avivod.h"
|
||||
|
||||
#define R700_PFP_UCODE_SIZE 848
|
||||
#define R700_PM4_UCODE_SIZE 1360
|
||||
|
@ -231,7 +231,7 @@ static void rv770_mc_resume(struct radeon_device *rdev)
|
|||
|
||||
/* we need to own VRAM, so turn off the VGA renderer here
|
||||
* to stop it overwriting our objects */
|
||||
radeon_avivo_vga_render_disable(rdev);
|
||||
rv515_vga_render_disable(rdev);
|
||||
}
|
||||
|
||||
|
||||
|
@ -801,6 +801,13 @@ int rv770_mc_init(struct radeon_device *rdev)
|
|||
/* Setup GPU memory space */
|
||||
rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
|
||||
rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
|
||||
|
||||
if (rdev->mc.mc_vram_size > rdev->mc.aper_size)
|
||||
rdev->mc.mc_vram_size = rdev->mc.aper_size;
|
||||
|
||||
if (rdev->mc.real_vram_size > rdev->mc.aper_size)
|
||||
rdev->mc.real_vram_size = rdev->mc.aper_size;
|
||||
|
||||
if (rdev->flags & RADEON_IS_AGP) {
|
||||
r = radeon_agp_init(rdev);
|
||||
if (r)
|
||||
|
|
|
@ -1800,7 +1800,7 @@ static int __init video_setup(char *options)
|
|||
global = 1;
|
||||
}
|
||||
|
||||
if (!global && !strstr(options, "fb:")) {
|
||||
if (!global && !strchr(options, ':')) {
|
||||
fb_mode_option = options;
|
||||
global = 1;
|
||||
}
|
||||
|
|
|
@ -387,6 +387,7 @@ struct drm_crtc {
|
|||
* @get_modes: get mode list for this connector
|
||||
* @set_property: property for this connector may need update
|
||||
* @destroy: make object go away
|
||||
* @force: notify the driver the connector is forced on
|
||||
*
|
||||
* Each CRTC may have one or more connectors attached to it. The functions
|
||||
* below allow the core DRM code to control connectors, enumerate available modes,
|
||||
|
@ -401,6 +402,7 @@ struct drm_connector_funcs {
|
|||
int (*set_property)(struct drm_connector *connector, struct drm_property *property,
|
||||
uint64_t val);
|
||||
void (*destroy)(struct drm_connector *connector);
|
||||
void (*force)(struct drm_connector *connector);
|
||||
};
|
||||
|
||||
struct drm_encoder_funcs {
|
||||
|
@ -429,6 +431,13 @@ struct drm_encoder {
|
|||
void *helper_private;
|
||||
};
|
||||
|
||||
enum drm_connector_force {
|
||||
DRM_FORCE_UNSPECIFIED,
|
||||
DRM_FORCE_OFF,
|
||||
DRM_FORCE_ON, /* force on analog part normally */
|
||||
DRM_FORCE_ON_DIGITAL, /* for DVI-I use digital connector */
|
||||
};
|
||||
|
||||
/**
|
||||
* drm_connector - central DRM connector control structure
|
||||
* @crtc: CRTC this connector is currently connected to, NULL if none
|
||||
|
@ -478,9 +487,12 @@ struct drm_connector {
|
|||
|
||||
void *helper_private;
|
||||
|
||||
/* forced on connector */
|
||||
enum drm_connector_force force;
|
||||
uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
|
||||
uint32_t force_encoder_id;
|
||||
struct drm_encoder *encoder; /* currently active encoder */
|
||||
void *fb_helper_private;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -746,7 +758,7 @@ extern int drm_mode_gamma_set_ioctl(struct drm_device *dev,
|
|||
extern bool drm_detect_hdmi_monitor(struct edid *edid);
|
||||
extern struct drm_display_mode *drm_cvt_mode(struct drm_device *dev,
|
||||
int hdisplay, int vdisplay, int vrefresh,
|
||||
bool reduced, bool interlaced);
|
||||
bool reduced, bool interlaced, bool margins);
|
||||
extern struct drm_display_mode *drm_gtf_mode(struct drm_device *dev,
|
||||
int hdisplay, int vdisplay, int vrefresh,
|
||||
bool interlaced, int margins);
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
|
||||
#include <linux/fb.h>
|
||||
|
||||
#include "drm_fb_helper.h"
|
||||
struct drm_crtc_helper_funcs {
|
||||
/*
|
||||
* Control power levels on the CRTC. If the mode passed in is
|
||||
|
@ -119,10 +120,11 @@ static inline void drm_encoder_helper_add(struct drm_encoder *encoder,
|
|||
encoder->helper_private = (void *)funcs;
|
||||
}
|
||||
|
||||
static inline void drm_connector_helper_add(struct drm_connector *connector,
|
||||
static inline int drm_connector_helper_add(struct drm_connector *connector,
|
||||
const struct drm_connector_helper_funcs *funcs)
|
||||
{
|
||||
connector->helper_private = (void *)funcs;
|
||||
return drm_fb_helper_add_connector(connector);
|
||||
}
|
||||
|
||||
extern int drm_helper_resume_force_mode(struct drm_device *dev);
|
||||
|
|
|
@ -35,11 +35,30 @@ struct drm_fb_helper_crtc {
|
|||
struct drm_mode_set mode_set;
|
||||
};
|
||||
|
||||
|
||||
struct drm_fb_helper_funcs {
|
||||
void (*gamma_set)(struct drm_crtc *crtc, u16 red, u16 green,
|
||||
u16 blue, int regno);
|
||||
};
|
||||
|
||||
/* mode specified on the command line */
|
||||
struct drm_fb_helper_cmdline_mode {
|
||||
bool specified;
|
||||
bool refresh_specified;
|
||||
bool bpp_specified;
|
||||
int xres, yres;
|
||||
int bpp;
|
||||
int refresh;
|
||||
bool rb;
|
||||
bool interlace;
|
||||
bool cvt;
|
||||
bool margins;
|
||||
};
|
||||
|
||||
struct drm_fb_helper_connector {
|
||||
struct drm_fb_helper_cmdline_mode cmdline_mode;
|
||||
};
|
||||
|
||||
struct drm_fb_helper {
|
||||
struct drm_framebuffer *fb;
|
||||
struct drm_device *dev;
|
||||
|
@ -57,6 +76,8 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev,
|
|||
uint32_t fb_height,
|
||||
uint32_t surface_width,
|
||||
uint32_t surface_height,
|
||||
uint32_t surface_depth,
|
||||
uint32_t surface_bpp,
|
||||
struct drm_framebuffer **fb_ptr));
|
||||
int drm_fb_helper_init_crtc_count(struct drm_fb_helper *helper, int crtc_count,
|
||||
int max_conn);
|
||||
|
@ -79,4 +100,7 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb,
|
|||
uint32_t fb_width, uint32_t fb_height);
|
||||
void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch);
|
||||
|
||||
int drm_fb_helper_add_connector(struct drm_connector *connector);
|
||||
int drm_fb_helper_parse_command_line(struct drm_device *dev);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue