diff options
37 files changed, 2117 insertions, 691 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index ba728ad77f2a..8e7b0ebece0c 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
| @@ -482,6 +482,7 @@ void drm_connector_cleanup(struct drm_connector *connector) | |||
| 482 | list_for_each_entry_safe(mode, t, &connector->user_modes, head) | 482 | list_for_each_entry_safe(mode, t, &connector->user_modes, head) |
| 483 | drm_mode_remove(connector, mode); | 483 | drm_mode_remove(connector, mode); |
| 484 | 484 | ||
| 485 | kfree(connector->fb_helper_private); | ||
| 485 | mutex_lock(&dev->mode_config.mutex); | 486 | mutex_lock(&dev->mode_config.mutex); |
| 486 | drm_mode_object_put(dev, &connector->base); | 487 | drm_mode_object_put(dev, &connector->base); |
| 487 | list_del(&connector->head); | 488 | list_del(&connector->head); |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index fe8697447f32..1fe4e1d344fd 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | #include "drmP.h" | 32 | #include "drmP.h" |
| 33 | #include "drm_crtc.h" | 33 | #include "drm_crtc.h" |
| 34 | #include "drm_crtc_helper.h" | 34 | #include "drm_crtc_helper.h" |
| 35 | #include "drm_fb_helper.h" | ||
| 35 | 36 | ||
| 36 | static void drm_mode_validate_flag(struct drm_connector *connector, | 37 | static void drm_mode_validate_flag(struct drm_connector *connector, |
| 37 | int flags) | 38 | int flags) |
| @@ -90,7 +91,15 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, | |||
| 90 | list_for_each_entry_safe(mode, t, &connector->modes, head) | 91 | list_for_each_entry_safe(mode, t, &connector->modes, head) |
| 91 | mode->status = MODE_UNVERIFIED; | 92 | mode->status = MODE_UNVERIFIED; |
| 92 | 93 | ||
| 93 | connector->status = connector->funcs->detect(connector); | 94 | if (connector->force) { |
| 95 | if (connector->force == DRM_FORCE_ON) | ||
| 96 | connector->status = connector_status_connected; | ||
| 97 | else | ||
| 98 | connector->status = connector_status_disconnected; | ||
| 99 | if (connector->funcs->force) | ||
| 100 | connector->funcs->force(connector); | ||
| 101 | } else | ||
| 102 | connector->status = connector->funcs->detect(connector); | ||
| 94 | 103 | ||
| 95 | if (connector->status == connector_status_disconnected) { | 104 | if (connector->status == connector_status_disconnected) { |
| 96 | DRM_DEBUG_KMS("%s is disconnected\n", | 105 | DRM_DEBUG_KMS("%s is disconnected\n", |
| @@ -267,6 +276,65 @@ static struct drm_display_mode *drm_has_preferred_mode(struct drm_connector *con | |||
| 267 | return NULL; | 276 | return NULL; |
| 268 | } | 277 | } |
| 269 | 278 | ||
| 279 | static bool drm_has_cmdline_mode(struct drm_connector *connector) | ||
| 280 | { | ||
| 281 | struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private; | ||
| 282 | struct drm_fb_helper_cmdline_mode *cmdline_mode; | ||
| 283 | |||
| 284 | if (!fb_help_conn) | ||
| 285 | return false; | ||
| 286 | |||
| 287 | cmdline_mode = &fb_help_conn->cmdline_mode; | ||
| 288 | return cmdline_mode->specified; | ||
| 289 | } | ||
| 290 | |||
| 291 | static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_connector *connector, int width, int height) | ||
| 292 | { | ||
| 293 | struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private; | ||
| 294 | struct drm_fb_helper_cmdline_mode *cmdline_mode; | ||
| 295 | struct drm_display_mode *mode = NULL; | ||
| 296 | |||
| 297 | if (!fb_help_conn) | ||
| 298 | return mode; | ||
| 299 | |||
| 300 | cmdline_mode = &fb_help_conn->cmdline_mode; | ||
| 301 | if (cmdline_mode->specified == false) | ||
| 302 | return mode; | ||
| 303 | |||
| 304 | /* attempt to find a matching mode in the list of modes | ||
| 305 | * we have gotten so far, if not add a CVT mode that conforms | ||
| 306 | */ | ||
| 307 | if (cmdline_mode->rb || cmdline_mode->margins) | ||
| 308 | goto create_mode; | ||
| 309 | |||
| 310 | list_for_each_entry(mode, &connector->modes, head) { | ||
| 311 | /* check width/height */ | ||
| 312 | if (mode->hdisplay != cmdline_mode->xres || | ||
| 313 | mode->vdisplay != cmdline_mode->yres) | ||
| 314 | continue; | ||
| 315 | |||
| 316 | if (cmdline_mode->refresh_specified) { | ||
| 317 | if (mode->vrefresh != cmdline_mode->refresh) | ||
| 318 | continue; | ||
| 319 | } | ||
| 320 | |||
| 321 | if (cmdline_mode->interlace) { | ||
| 322 | if (!(mode->flags & DRM_MODE_FLAG_INTERLACE)) | ||
| 323 | continue; | ||
| 324 | } | ||
| 325 | return mode; | ||
| 326 | } | ||
| 327 | |||
| 328 | create_mode: | ||
| 329 | mode = drm_cvt_mode(connector->dev, cmdline_mode->xres, | ||
| 330 | cmdline_mode->yres, | ||
| 331 | cmdline_mode->refresh_specified ? cmdline_mode->refresh : 60, | ||
| 332 | cmdline_mode->rb, cmdline_mode->interlace, | ||
| 333 | cmdline_mode->margins); | ||
| 334 | list_add(&mode->head, &connector->modes); | ||
| 335 | return mode; | ||
| 336 | } | ||
| 337 | |||
| 270 | static bool drm_connector_enabled(struct drm_connector *connector, bool strict) | 338 | static bool drm_connector_enabled(struct drm_connector *connector, bool strict) |
| 271 | { | 339 | { |
| 272 | bool enable; | 340 | bool enable; |
| @@ -317,10 +385,16 @@ static bool drm_target_preferred(struct drm_device *dev, | |||
| 317 | continue; | 385 | continue; |
| 318 | } | 386 | } |
| 319 | 387 | ||
| 320 | DRM_DEBUG_KMS("looking for preferred mode on connector %d\n", | 388 | DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n", |
| 321 | connector->base.id); | 389 | connector->base.id); |
| 322 | 390 | ||
| 323 | modes[i] = drm_has_preferred_mode(connector, width, height); | 391 | /* got for command line mode first */ |
| 392 | modes[i] = drm_pick_cmdline_mode(connector, width, height); | ||
| 393 | if (!modes[i]) { | ||
| 394 | DRM_DEBUG_KMS("looking for preferred mode on connector %d\n", | ||
| 395 | connector->base.id); | ||
| 396 | modes[i] = drm_has_preferred_mode(connector, width, height); | ||
| 397 | } | ||
| 324 | /* No preferred modes, pick one off the list */ | 398 | /* No preferred modes, pick one off the list */ |
| 325 | if (!modes[i] && !list_empty(&connector->modes)) { | 399 | if (!modes[i] && !list_empty(&connector->modes)) { |
| 326 | list_for_each_entry(modes[i], &connector->modes, head) | 400 | list_for_each_entry(modes[i], &connector->modes, head) |
| @@ -369,6 +443,8 @@ static int drm_pick_crtcs(struct drm_device *dev, | |||
| 369 | my_score = 1; | 443 | my_score = 1; |
| 370 | if (connector->status == connector_status_connected) | 444 | if (connector->status == connector_status_connected) |
| 371 | my_score++; | 445 | my_score++; |
| 446 | if (drm_has_cmdline_mode(connector)) | ||
| 447 | my_score++; | ||
| 372 | if (drm_has_preferred_mode(connector, width, height)) | 448 | if (drm_has_preferred_mode(connector, width, height)) |
| 373 | my_score++; | 449 | my_score++; |
| 374 | 450 | ||
| @@ -943,6 +1019,8 @@ bool drm_helper_initial_config(struct drm_device *dev) | |||
| 943 | { | 1019 | { |
| 944 | int count = 0; | 1020 | int count = 0; |
| 945 | 1021 | ||
| 1022 | drm_fb_helper_parse_command_line(dev); | ||
| 1023 | |||
| 946 | count = drm_helper_probe_connector_modes(dev, | 1024 | count = drm_helper_probe_connector_modes(dev, |
| 947 | dev->mode_config.max_width, | 1025 | dev->mode_config.max_width, |
| 948 | dev->mode_config.max_height); | 1026 | dev->mode_config.max_height); |
| @@ -950,7 +1028,7 @@ bool drm_helper_initial_config(struct drm_device *dev) | |||
| 950 | /* | 1028 | /* |
| 951 | * we shouldn't end up with no modes here. | 1029 | * we shouldn't end up with no modes here. |
| 952 | */ | 1030 | */ |
| 953 | WARN(!count, "Connected connector with 0 modes\n"); | 1031 | WARN(!count, "No connectors reported connected with modes\n"); |
| 954 | 1032 | ||
| 955 | drm_setup_crtcs(dev); | 1033 | drm_setup_crtcs(dev); |
| 956 | 1034 | ||
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 90d76bacff17..3c0d2b3aed76 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
| @@ -109,7 +109,9 @@ static struct edid_quirk { | |||
| 109 | 109 | ||
| 110 | 110 | ||
| 111 | /* Valid EDID header has these bytes */ | 111 | /* Valid EDID header has these bytes */ |
| 112 | static u8 edid_header[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; | 112 | static const u8 edid_header[] = { |
| 113 | 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 | ||
| 114 | }; | ||
| 113 | 115 | ||
| 114 | /** | 116 | /** |
| 115 | * edid_is_valid - sanity check EDID data | 117 | * edid_is_valid - sanity check EDID data |
| @@ -500,6 +502,19 @@ static struct drm_display_mode *drm_find_dmt(struct drm_device *dev, | |||
| 500 | } | 502 | } |
| 501 | return mode; | 503 | return mode; |
| 502 | } | 504 | } |
| 505 | |||
| 506 | /* | ||
| 507 | * 0 is reserved. The spec says 0x01 fill for unused timings. Some old | ||
| 508 | * monitors fill with ascii space (0x20) instead. | ||
| 509 | */ | ||
| 510 | static int | ||
| 511 | bad_std_timing(u8 a, u8 b) | ||
| 512 | { | ||
| 513 | return (a == 0x00 && b == 0x00) || | ||
| 514 | (a == 0x01 && b == 0x01) || | ||
| 515 | (a == 0x20 && b == 0x20); | ||
| 516 | } | ||
| 517 | |||
| 503 | /** | 518 | /** |
| 504 | * drm_mode_std - convert standard mode info (width, height, refresh) into mode | 519 | * drm_mode_std - convert standard mode info (width, height, refresh) into mode |
| 505 | * @t: standard timing params | 520 | * @t: standard timing params |
| @@ -513,6 +528,7 @@ static struct drm_display_mode *drm_find_dmt(struct drm_device *dev, | |||
| 513 | */ | 528 | */ |
| 514 | struct drm_display_mode *drm_mode_std(struct drm_device *dev, | 529 | struct drm_display_mode *drm_mode_std(struct drm_device *dev, |
| 515 | struct std_timing *t, | 530 | struct std_timing *t, |
| 531 | int revision, | ||
| 516 | int timing_level) | 532 | int timing_level) |
| 517 | { | 533 | { |
| 518 | struct drm_display_mode *mode; | 534 | struct drm_display_mode *mode; |
| @@ -523,14 +539,20 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev, | |||
| 523 | unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK) | 539 | unsigned vfreq = (t->vfreq_aspect & EDID_TIMING_VFREQ_MASK) |
| 524 | >> EDID_TIMING_VFREQ_SHIFT; | 540 | >> EDID_TIMING_VFREQ_SHIFT; |
| 525 | 541 | ||
| 542 | if (bad_std_timing(t->hsize, t->vfreq_aspect)) | ||
| 543 | return NULL; | ||
| 544 | |||
| 526 | /* According to the EDID spec, the hdisplay = hsize * 8 + 248 */ | 545 | /* According to the EDID spec, the hdisplay = hsize * 8 + 248 */ |
| 527 | hsize = t->hsize * 8 + 248; | 546 | hsize = t->hsize * 8 + 248; |
| 528 | /* vrefresh_rate = vfreq + 60 */ | 547 | /* vrefresh_rate = vfreq + 60 */ |
| 529 | vrefresh_rate = vfreq + 60; | 548 | vrefresh_rate = vfreq + 60; |
| 530 | /* the vdisplay is calculated based on the aspect ratio */ | 549 | /* the vdisplay is calculated based on the aspect ratio */ |
| 531 | if (aspect_ratio == 0) | 550 | if (aspect_ratio == 0) { |
| 532 | vsize = (hsize * 10) / 16; | 551 | if (revision < 3) |
| 533 | else if (aspect_ratio == 1) | 552 | vsize = hsize; |
| 553 | else | ||
| 554 | vsize = (hsize * 10) / 16; | ||
| 555 | } else if (aspect_ratio == 1) | ||
| 534 | vsize = (hsize * 3) / 4; | 556 | vsize = (hsize * 3) / 4; |
| 535 | else if (aspect_ratio == 2) | 557 | else if (aspect_ratio == 2) |
| 536 | vsize = (hsize * 4) / 5; | 558 | vsize = (hsize * 4) / 5; |
| @@ -538,7 +560,8 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev, | |||
| 538 | vsize = (hsize * 9) / 16; | 560 | vsize = (hsize * 9) / 16; |
| 539 | /* HDTV hack */ | 561 | /* HDTV hack */ |
| 540 | if (hsize == 1360 && vsize == 765 && vrefresh_rate == 60) { | 562 | if (hsize == 1360 && vsize == 765 && vrefresh_rate == 60) { |
| 541 | mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); | 563 | mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0, |
| 564 | false); | ||
| 542 | mode->hdisplay = 1366; | 565 | mode->hdisplay = 1366; |
| 543 | mode->vsync_start = mode->vsync_start - 1; | 566 | mode->vsync_start = mode->vsync_start - 1; |
| 544 | mode->vsync_end = mode->vsync_end - 1; | 567 | mode->vsync_end = mode->vsync_end - 1; |
| @@ -557,7 +580,8 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev, | |||
| 557 | mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); | 580 | mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); |
| 558 | break; | 581 | break; |
| 559 | case LEVEL_CVT: | 582 | case LEVEL_CVT: |
| 560 | mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); | 583 | mode = drm_cvt_mode(dev, hsize, vsize, vrefresh_rate, 0, 0, |
| 584 | false); | ||
| 561 | break; | 585 | break; |
| 562 | } | 586 | } |
| 563 | return mode; | 587 | return mode; |
| @@ -779,7 +803,7 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid | |||
| 779 | continue; | 803 | continue; |
| 780 | 804 | ||
| 781 | newmode = drm_mode_std(dev, &edid->standard_timings[i], | 805 | newmode = drm_mode_std(dev, &edid->standard_timings[i], |
| 782 | timing_level); | 806 | edid->revision, timing_level); |
| 783 | if (newmode) { | 807 | if (newmode) { |
| 784 | drm_mode_probed_add(connector, newmode); | 808 | drm_mode_probed_add(connector, newmode); |
| 785 | modes++; | 809 | modes++; |
| @@ -829,13 +853,13 @@ static int add_detailed_info(struct drm_connector *connector, | |||
| 829 | case EDID_DETAIL_MONITOR_CPDATA: | 853 | case EDID_DETAIL_MONITOR_CPDATA: |
| 830 | break; | 854 | break; |
| 831 | case EDID_DETAIL_STD_MODES: | 855 | case EDID_DETAIL_STD_MODES: |
| 832 | /* Five modes per detailed section */ | 856 | for (j = 0; j < 6; i++) { |
| 833 | for (j = 0; j < 5; i++) { | ||
| 834 | struct std_timing *std; | 857 | struct std_timing *std; |
| 835 | struct drm_display_mode *newmode; | 858 | struct drm_display_mode *newmode; |
| 836 | 859 | ||
| 837 | std = &data->data.timings[j]; | 860 | std = &data->data.timings[j]; |
| 838 | newmode = drm_mode_std(dev, std, | 861 | newmode = drm_mode_std(dev, std, |
| 862 | edid->revision, | ||
| 839 | timing_level); | 863 | timing_level); |
| 840 | if (newmode) { | 864 | if (newmode) { |
| 841 | drm_mode_probed_add(connector, newmode); | 865 | drm_mode_probed_add(connector, newmode); |
| @@ -964,7 +988,9 @@ static int add_detailed_info_eedid(struct drm_connector *connector, | |||
| 964 | struct drm_display_mode *newmode; | 988 | struct drm_display_mode *newmode; |
| 965 | 989 | ||
| 966 | std = &data->data.timings[j]; | 990 | std = &data->data.timings[j]; |
| 967 | newmode = drm_mode_std(dev, std, timing_level); | 991 | newmode = drm_mode_std(dev, std, |
| 992 | edid->revision, | ||
| 993 | timing_level); | ||
| 968 | if (newmode) { | 994 | if (newmode) { |
| 969 | drm_mode_probed_add(connector, newmode); | 995 | drm_mode_probed_add(connector, newmode); |
| 970 | modes++; | 996 | modes++; |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 2c4671314884..819ddcbfcce5 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
| @@ -40,6 +40,199 @@ MODULE_LICENSE("GPL and additional rights"); | |||
| 40 | 40 | ||
| 41 | static LIST_HEAD(kernel_fb_helper_list); | 41 | static LIST_HEAD(kernel_fb_helper_list); |
| 42 | 42 | ||
| 43 | int drm_fb_helper_add_connector(struct drm_connector *connector) | ||
| 44 | { | ||
| 45 | connector->fb_helper_private = kzalloc(sizeof(struct drm_fb_helper_connector), GFP_KERNEL); | ||
| 46 | if (!connector->fb_helper_private) | ||
| 47 | return -ENOMEM; | ||
| 48 | |||
| 49 | return 0; | ||
| 50 | } | ||
| 51 | EXPORT_SYMBOL(drm_fb_helper_add_connector); | ||
| 52 | |||
| 53 | static int my_atoi(const char *name) | ||
| 54 | { | ||
| 55 | int val = 0; | ||
| 56 | |||
| 57 | for (;; name++) { | ||
| 58 | switch (*name) { | ||
| 59 | case '0' ... '9': | ||
| 60 | val = 10*val+(*name-'0'); | ||
| 61 | break; | ||
| 62 | default: | ||
| 63 | return val; | ||
| 64 | } | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | /** | ||
| 69 | * drm_fb_helper_connector_parse_command_line - parse command line for connector | ||
| 70 | * @connector - connector to parse line for | ||
| 71 | * @mode_option - per connector mode option | ||
| 72 | * | ||
| 73 | * This parses the connector specific then generic command lines for | ||
| 74 | * modes and options to configure the connector. | ||
| 75 | * | ||
| 76 | * This uses the same parameters as the fb modedb.c, except for extra | ||
| 77 | * <xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd] | ||
| 78 | * | ||
| 79 | * enable/enable Digital/disable bit at the end | ||
| 80 | */ | ||
| 81 | static bool drm_fb_helper_connector_parse_command_line(struct drm_connector *connector, | ||
| 82 | const char *mode_option) | ||
| 83 | { | ||
| 84 | const char *name; | ||
| 85 | unsigned int namelen; | ||
| 86 | int res_specified = 0, bpp_specified = 0, refresh_specified = 0; | ||
| 87 | unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0; | ||
| 88 | int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0; | ||
| 89 | int i; | ||
| 90 | enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; | ||
| 91 | struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private; | ||
| 92 | struct drm_fb_helper_cmdline_mode *cmdline_mode; | ||
| 93 | |||
| 94 | if (!fb_help_conn) | ||
| 95 | return false; | ||
| 96 | |||
| 97 | cmdline_mode = &fb_help_conn->cmdline_mode; | ||
| 98 | if (!mode_option) | ||
| 99 | mode_option = fb_mode_option; | ||
| 100 | |||
| 101 | if (!mode_option) { | ||
| 102 | cmdline_mode->specified = false; | ||
| 103 | return false; | ||
| 104 | } | ||
| 105 | |||
| 106 | name = mode_option; | ||
| 107 | namelen = strlen(name); | ||
| 108 | for (i = namelen-1; i >= 0; i--) { | ||
| 109 | switch (name[i]) { | ||
| 110 | case '@': | ||
| 111 | namelen = i; | ||
| 112 | if (!refresh_specified && !bpp_specified && | ||
| 113 | !yres_specified) { | ||
| 114 | refresh = my_atoi(&name[i+1]); | ||
| 115 | refresh_specified = 1; | ||
| 116 | if (cvt || rb) | ||
| 117 | cvt = 0; | ||
| 118 | } else | ||
| 119 | goto done; | ||
| 120 | break; | ||
| 121 | case '-': | ||
| 122 | namelen = i; | ||
| 123 | if (!bpp_specified && !yres_specified) { | ||
| 124 | bpp = my_atoi(&name[i+1]); | ||
| 125 | bpp_specified = 1; | ||
| 126 | if (cvt || rb) | ||
| 127 | cvt = 0; | ||
| 128 | } else | ||
| 129 | goto done; | ||
| 130 | break; | ||
| 131 | case 'x': | ||
| 132 | if (!yres_specified) { | ||
| 133 | yres = my_atoi(&name[i+1]); | ||
| 134 | yres_specified = 1; | ||
| 135 | } else | ||
| 136 | goto done; | ||
| 137 | case '0' ... '9': | ||
| 138 | break; | ||
| 139 | case 'M': | ||
| 140 | if (!yres_specified) | ||
| 141 | cvt = 1; | ||
| 142 | break; | ||
| 143 | case 'R': | ||
| 144 | if (!cvt) | ||
| 145 | rb = 1; | ||
| 146 | break; | ||
| 147 | case 'm': | ||
| 148 | if (!cvt) | ||
| 149 | margins = 1; | ||
| 150 | break; | ||
| 151 | case 'i': | ||
| 152 | if (!cvt) | ||
| 153 | interlace = 1; | ||
| 154 | break; | ||
| 155 | case 'e': | ||
| 156 | force = DRM_FORCE_ON; | ||
| 157 | break; | ||
| 158 | case 'D': | ||
| 159 | if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) || | ||
| 160 | (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB)) | ||
| 161 | force = DRM_FORCE_ON; | ||
| 162 | else | ||
| 163 | force = DRM_FORCE_ON_DIGITAL; | ||
| 164 | break; | ||
| 165 | case 'd': | ||
| 166 | force = DRM_FORCE_OFF; | ||
| 167 | break; | ||
| 168 | default: | ||
| 169 | goto done; | ||
| 170 | } | ||
| 171 | } | ||
| 172 | if (i < 0 && yres_specified) { | ||
| 173 | xres = my_atoi(name); | ||
| 174 | res_specified = 1; | ||
| 175 | } | ||
| 176 | done: | ||
| 177 | |||
| 178 | DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n", | ||
| 179 | drm_get_connector_name(connector), xres, yres, | ||
| 180 | (refresh) ? refresh : 60, (rb) ? " reduced blanking" : | ||
| 181 | "", (margins) ? " with margins" : "", (interlace) ? | ||
| 182 | " interlaced" : ""); | ||
| 183 | |||
| 184 | if (force) { | ||
| 185 | const char *s; | ||
| 186 | switch (force) { | ||
| 187 | case DRM_FORCE_OFF: s = "OFF"; break; | ||
| 188 | case DRM_FORCE_ON_DIGITAL: s = "ON - dig"; break; | ||
| 189 | default: | ||
| 190 | case DRM_FORCE_ON: s = "ON"; break; | ||
| 191 | } | ||
| 192 | |||
| 193 | DRM_INFO("forcing %s connector %s\n", | ||
| 194 | drm_get_connector_name(connector), s); | ||
| 195 | connector->force = force; | ||
| 196 | } | ||
| 197 | |||
| 198 | if (res_specified) { | ||
| 199 | cmdline_mode->specified = true; | ||
| 200 | cmdline_mode->xres = xres; | ||
| 201 | cmdline_mode->yres = yres; | ||
| 202 | } | ||
| 203 | |||
| 204 | if (refresh_specified) { | ||
| 205 | cmdline_mode->refresh_specified = true; | ||
| 206 | cmdline_mode->refresh = refresh; | ||
| 207 | } | ||
| 208 | |||
| 209 | if (bpp_specified) { | ||
| 210 | cmdline_mode->bpp_specified = true; | ||
| 211 | cmdline_mode->bpp = bpp; | ||
| 212 | } | ||
| 213 | cmdline_mode->rb = rb ? true : false; | ||
| 214 | cmdline_mode->cvt = cvt ? true : false; | ||
| 215 | cmdline_mode->interlace = interlace ? true : false; | ||
| 216 | |||
| 217 | return true; | ||
| 218 | } | ||
| 219 | |||
| 220 | int drm_fb_helper_parse_command_line(struct drm_device *dev) | ||
| 221 | { | ||
| 222 | struct drm_connector *connector; | ||
| 223 | |||
| 224 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 225 | char *option = NULL; | ||
| 226 | |||
| 227 | /* do something on return - turn off connector maybe */ | ||
| 228 | if (fb_get_options(drm_get_connector_name(connector), &option)) | ||
| 229 | continue; | ||
| 230 | |||
| 231 | drm_fb_helper_connector_parse_command_line(connector, option); | ||
| 232 | } | ||
| 233 | return 0; | ||
| 234 | } | ||
| 235 | |||
| 43 | bool drm_fb_helper_force_kernel_mode(void) | 236 | bool drm_fb_helper_force_kernel_mode(void) |
| 44 | { | 237 | { |
| 45 | int i = 0; | 238 | int i = 0; |
| @@ -87,6 +280,7 @@ void drm_fb_helper_restore(void) | |||
| 87 | } | 280 | } |
| 88 | EXPORT_SYMBOL(drm_fb_helper_restore); | 281 | EXPORT_SYMBOL(drm_fb_helper_restore); |
| 89 | 282 | ||
| 283 | #ifdef CONFIG_MAGIC_SYSRQ | ||
| 90 | static void drm_fb_helper_restore_work_fn(struct work_struct *ignored) | 284 | static void drm_fb_helper_restore_work_fn(struct work_struct *ignored) |
| 91 | { | 285 | { |
| 92 | drm_fb_helper_restore(); | 286 | drm_fb_helper_restore(); |
| @@ -103,6 +297,7 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { | |||
| 103 | .help_msg = "force-fb(V)", | 297 | .help_msg = "force-fb(V)", |
| 104 | .action_msg = "Restore framebuffer console", | 298 | .action_msg = "Restore framebuffer console", |
| 105 | }; | 299 | }; |
| 300 | #endif | ||
| 106 | 301 | ||
| 107 | static void drm_fb_helper_on(struct fb_info *info) | 302 | static void drm_fb_helper_on(struct fb_info *info) |
| 108 | { | 303 | { |
| @@ -484,6 +679,8 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev, | |||
| 484 | uint32_t fb_height, | 679 | uint32_t fb_height, |
| 485 | uint32_t surface_width, | 680 | uint32_t surface_width, |
| 486 | uint32_t surface_height, | 681 | uint32_t surface_height, |
| 682 | uint32_t surface_depth, | ||
| 683 | uint32_t surface_bpp, | ||
| 487 | struct drm_framebuffer **fb_ptr)) | 684 | struct drm_framebuffer **fb_ptr)) |
| 488 | { | 685 | { |
| 489 | struct drm_crtc *crtc; | 686 | struct drm_crtc *crtc; |
| @@ -497,8 +694,43 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev, | |||
| 497 | struct drm_framebuffer *fb; | 694 | struct drm_framebuffer *fb; |
| 498 | struct drm_mode_set *modeset = NULL; | 695 | struct drm_mode_set *modeset = NULL; |
| 499 | struct drm_fb_helper *fb_helper; | 696 | struct drm_fb_helper *fb_helper; |
| 697 | uint32_t surface_depth = 24, surface_bpp = 32; | ||
| 500 | 698 | ||
| 501 | /* first up get a count of crtcs now in use and new min/maxes width/heights */ | 699 | /* first up get a count of crtcs now in use and new min/maxes width/heights */ |
| 700 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 701 | struct drm_fb_helper_connector *fb_help_conn = connector->fb_helper_private; | ||
| 702 | |||
| 703 | struct drm_fb_helper_cmdline_mode *cmdline_mode; | ||
| 704 | |||
| 705 | if (!fb_help_conn) | ||
| 706 | continue; | ||
| 707 | |||
| 708 | cmdline_mode = &fb_help_conn->cmdline_mode; | ||
| 709 | |||
| 710 | if (cmdline_mode->bpp_specified) { | ||
| 711 | switch (cmdline_mode->bpp) { | ||
| 712 | case 8: | ||
| 713 | surface_depth = surface_bpp = 8; | ||
| 714 | break; | ||
| 715 | case 15: | ||
| 716 | surface_depth = 15; | ||
| 717 | surface_bpp = 16; | ||
| 718 | break; | ||
| 719 | case 16: | ||
| 720 | surface_depth = surface_bpp = 16; | ||
| 721 | break; | ||
| 722 | case 24: | ||
| 723 | surface_depth = surface_bpp = 24; | ||
| 724 | break; | ||
| 725 | case 32: | ||
| 726 | surface_depth = 24; | ||
| 727 | surface_bpp = 32; | ||
| 728 | break; | ||
| 729 | } | ||
| 730 | break; | ||
| 731 | } | ||
| 732 | } | ||
| 733 | |||
| 502 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 734 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
| 503 | if (drm_helper_crtc_in_use(crtc)) { | 735 | if (drm_helper_crtc_in_use(crtc)) { |
| 504 | if (crtc->desired_mode) { | 736 | if (crtc->desired_mode) { |
| @@ -527,7 +759,8 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev, | |||
| 527 | /* do we have an fb already? */ | 759 | /* do we have an fb already? */ |
| 528 | if (list_empty(&dev->mode_config.fb_kernel_list)) { | 760 | if (list_empty(&dev->mode_config.fb_kernel_list)) { |
| 529 | ret = (*fb_create)(dev, fb_width, fb_height, surface_width, | 761 | ret = (*fb_create)(dev, fb_width, fb_height, surface_width, |
| 530 | surface_height, &fb); | 762 | surface_height, surface_depth, surface_bpp, |
| 763 | &fb); | ||
| 531 | if (ret) | 764 | if (ret) |
| 532 | return -EINVAL; | 765 | return -EINVAL; |
| 533 | new_fb = 1; | 766 | new_fb = 1; |
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 49404ce1666e..51f677215f1d 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
| @@ -88,7 +88,7 @@ EXPORT_SYMBOL(drm_mode_debug_printmodeline); | |||
| 88 | #define HV_FACTOR 1000 | 88 | #define HV_FACTOR 1000 |
| 89 | struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, | 89 | struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, |
| 90 | int vdisplay, int vrefresh, | 90 | int vdisplay, int vrefresh, |
| 91 | bool reduced, bool interlaced) | 91 | bool reduced, bool interlaced, bool margins) |
| 92 | { | 92 | { |
| 93 | /* 1) top/bottom margin size (% of height) - default: 1.8, */ | 93 | /* 1) top/bottom margin size (% of height) - default: 1.8, */ |
| 94 | #define CVT_MARGIN_PERCENTAGE 18 | 94 | #define CVT_MARGIN_PERCENTAGE 18 |
| @@ -101,7 +101,6 @@ struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, | |||
| 101 | /* Pixel Clock step (kHz) */ | 101 | /* Pixel Clock step (kHz) */ |
| 102 | #define CVT_CLOCK_STEP 250 | 102 | #define CVT_CLOCK_STEP 250 |
| 103 | struct drm_display_mode *drm_mode; | 103 | struct drm_display_mode *drm_mode; |
| 104 | bool margins = false; | ||
| 105 | unsigned int vfieldrate, hperiod; | 104 | unsigned int vfieldrate, hperiod; |
| 106 | int hdisplay_rnd, hmargin, vdisplay_rnd, vmargin, vsync; | 105 | int hdisplay_rnd, hmargin, vdisplay_rnd, vmargin, vsync; |
| 107 | int interlace; | 106 | int interlace; |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 7ba4a232a97f..e85d7e9eed7d 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
| @@ -110,6 +110,7 @@ EXPORT_SYMBOL(intelfb_resize); | |||
| 110 | static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | 110 | static int intelfb_create(struct drm_device *dev, uint32_t fb_width, |
| 111 | uint32_t fb_height, uint32_t surface_width, | 111 | uint32_t fb_height, uint32_t surface_width, |
| 112 | uint32_t surface_height, | 112 | uint32_t surface_height, |
| 113 | uint32_t surface_depth, uint32_t surface_bpp, | ||
| 113 | struct drm_framebuffer **fb_p) | 114 | struct drm_framebuffer **fb_p) |
| 114 | { | 115 | { |
| 115 | struct fb_info *info; | 116 | struct fb_info *info; |
| @@ -125,9 +126,9 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
| 125 | mode_cmd.width = surface_width; | 126 | mode_cmd.width = surface_width; |
| 126 | mode_cmd.height = surface_height; | 127 | mode_cmd.height = surface_height; |
| 127 | 128 | ||
| 128 | mode_cmd.bpp = 32; | 129 | mode_cmd.bpp = surface_bpp; |
| 129 | mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 1) / 8), 64); | 130 | mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 1) / 8), 64); |
| 130 | mode_cmd.depth = 24; | 131 | mode_cmd.depth = surface_depth; |
| 131 | 132 | ||
| 132 | size = mode_cmd.pitch * mode_cmd.height; | 133 | size = mode_cmd.pitch * mode_cmd.height; |
| 133 | size = ALIGN(size, PAGE_SIZE); | 134 | size = ALIGN(size, PAGE_SIZE); |
diff --git a/drivers/gpu/drm/radeon/.gitignore b/drivers/gpu/drm/radeon/.gitignore new file mode 100644 index 000000000000..403eb3a5891f --- /dev/null +++ b/drivers/gpu/drm/radeon/.gitignore | |||
| @@ -0,0 +1,3 @@ | |||
| 1 | mkregtable | ||
| 2 | *_reg_safe.h | ||
| 3 | |||
diff --git a/drivers/gpu/drm/radeon/avivod.h b/drivers/gpu/drm/radeon/avivod.h index e2b92c445bab..d4e6e6e4a938 100644 --- a/drivers/gpu/drm/radeon/avivod.h +++ b/drivers/gpu/drm/radeon/avivod.h | |||
| @@ -57,13 +57,4 @@ | |||
| 57 | #define VGA_RENDER_CONTROL 0x0300 | 57 | #define VGA_RENDER_CONTROL 0x0300 |
| 58 | #define VGA_VSTATUS_CNTL_MASK 0x00030000 | 58 | #define VGA_VSTATUS_CNTL_MASK 0x00030000 |
| 59 | 59 | ||
| 60 | /* AVIVO disable VGA rendering */ | ||
| 61 | static inline void radeon_avivo_vga_render_disable(struct radeon_device *rdev) | ||
| 62 | { | ||
| 63 | u32 vga_render; | ||
| 64 | vga_render = RREG32(VGA_RENDER_CONTROL); | ||
| 65 | vga_render &= ~VGA_VSTATUS_CNTL_MASK; | ||
| 66 | WREG32(VGA_RENDER_CONTROL, vga_render); | ||
| 67 | } | ||
| 68 | |||
| 69 | #endif | 60 | #endif |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index be51c5f7d0f6..e6cce24de802 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
| @@ -863,13 +863,11 @@ int r100_cs_parse_packet0(struct radeon_cs_parser *p, | |||
| 863 | void r100_cs_dump_packet(struct radeon_cs_parser *p, | 863 | void r100_cs_dump_packet(struct radeon_cs_parser *p, |
| 864 | struct radeon_cs_packet *pkt) | 864 | struct radeon_cs_packet *pkt) |
| 865 | { | 865 | { |
| 866 | struct radeon_cs_chunk *ib_chunk; | ||
| 867 | volatile uint32_t *ib; | 866 | volatile uint32_t *ib; |
| 868 | unsigned i; | 867 | unsigned i; |
| 869 | unsigned idx; | 868 | unsigned idx; |
| 870 | 869 | ||
| 871 | ib = p->ib->ptr; | 870 | ib = p->ib->ptr; |
| 872 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
| 873 | idx = pkt->idx; | 871 | idx = pkt->idx; |
| 874 | for (i = 0; i <= (pkt->count + 1); i++, idx++) { | 872 | for (i = 0; i <= (pkt->count + 1); i++, idx++) { |
| 875 | DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]); | 873 | DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]); |
| @@ -896,7 +894,7 @@ int r100_cs_packet_parse(struct radeon_cs_parser *p, | |||
| 896 | idx, ib_chunk->length_dw); | 894 | idx, ib_chunk->length_dw); |
| 897 | return -EINVAL; | 895 | return -EINVAL; |
| 898 | } | 896 | } |
| 899 | header = ib_chunk->kdata[idx]; | 897 | header = radeon_get_ib_value(p, idx); |
| 900 | pkt->idx = idx; | 898 | pkt->idx = idx; |
| 901 | pkt->type = CP_PACKET_GET_TYPE(header); | 899 | pkt->type = CP_PACKET_GET_TYPE(header); |
| 902 | pkt->count = CP_PACKET_GET_COUNT(header); | 900 | pkt->count = CP_PACKET_GET_COUNT(header); |
| @@ -939,7 +937,6 @@ int r100_cs_packet_parse(struct radeon_cs_parser *p, | |||
| 939 | */ | 937 | */ |
| 940 | int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) | 938 | int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) |
| 941 | { | 939 | { |
| 942 | struct radeon_cs_chunk *ib_chunk; | ||
| 943 | struct drm_mode_object *obj; | 940 | struct drm_mode_object *obj; |
| 944 | struct drm_crtc *crtc; | 941 | struct drm_crtc *crtc; |
| 945 | struct radeon_crtc *radeon_crtc; | 942 | struct radeon_crtc *radeon_crtc; |
| @@ -947,8 +944,9 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) | |||
| 947 | int crtc_id; | 944 | int crtc_id; |
| 948 | int r; | 945 | int r; |
| 949 | uint32_t header, h_idx, reg; | 946 | uint32_t header, h_idx, reg; |
| 947 | volatile uint32_t *ib; | ||
| 950 | 948 | ||
| 951 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | 949 | ib = p->ib->ptr; |
| 952 | 950 | ||
| 953 | /* parse the wait until */ | 951 | /* parse the wait until */ |
| 954 | r = r100_cs_packet_parse(p, &waitreloc, p->idx); | 952 | r = r100_cs_packet_parse(p, &waitreloc, p->idx); |
| @@ -963,24 +961,24 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) | |||
| 963 | return r; | 961 | return r; |
| 964 | } | 962 | } |
| 965 | 963 | ||
| 966 | if (ib_chunk->kdata[waitreloc.idx + 1] != RADEON_WAIT_CRTC_VLINE) { | 964 | if (radeon_get_ib_value(p, waitreloc.idx + 1) != RADEON_WAIT_CRTC_VLINE) { |
| 967 | DRM_ERROR("vline wait had illegal wait until\n"); | 965 | DRM_ERROR("vline wait had illegal wait until\n"); |
| 968 | r = -EINVAL; | 966 | r = -EINVAL; |
| 969 | return r; | 967 | return r; |
| 970 | } | 968 | } |
| 971 | 969 | ||
| 972 | /* jump over the NOP */ | 970 | /* jump over the NOP */ |
| 973 | r = r100_cs_packet_parse(p, &p3reloc, p->idx); | 971 | r = r100_cs_packet_parse(p, &p3reloc, p->idx + waitreloc.count + 2); |
| 974 | if (r) | 972 | if (r) |
| 975 | return r; | 973 | return r; |
| 976 | 974 | ||
| 977 | h_idx = p->idx - 2; | 975 | h_idx = p->idx - 2; |
| 978 | p->idx += waitreloc.count; | 976 | p->idx += waitreloc.count + 2; |
| 979 | p->idx += p3reloc.count; | 977 | p->idx += p3reloc.count + 2; |
| 980 | 978 | ||
| 981 | header = ib_chunk->kdata[h_idx]; | 979 | header = radeon_get_ib_value(p, h_idx); |
| 982 | crtc_id = ib_chunk->kdata[h_idx + 5]; | 980 | crtc_id = radeon_get_ib_value(p, h_idx + 5); |
| 983 | reg = ib_chunk->kdata[h_idx] >> 2; | 981 | reg = header >> 2; |
| 984 | mutex_lock(&p->rdev->ddev->mode_config.mutex); | 982 | mutex_lock(&p->rdev->ddev->mode_config.mutex); |
| 985 | obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); | 983 | obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); |
| 986 | if (!obj) { | 984 | if (!obj) { |
| @@ -994,16 +992,16 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) | |||
| 994 | 992 | ||
| 995 | if (!crtc->enabled) { | 993 | if (!crtc->enabled) { |
| 996 | /* if the CRTC isn't enabled - we need to nop out the wait until */ | 994 | /* if the CRTC isn't enabled - we need to nop out the wait until */ |
| 997 | ib_chunk->kdata[h_idx + 2] = PACKET2(0); | 995 | ib[h_idx + 2] = PACKET2(0); |
| 998 | ib_chunk->kdata[h_idx + 3] = PACKET2(0); | 996 | ib[h_idx + 3] = PACKET2(0); |
| 999 | } else if (crtc_id == 1) { | 997 | } else if (crtc_id == 1) { |
| 1000 | switch (reg) { | 998 | switch (reg) { |
| 1001 | case AVIVO_D1MODE_VLINE_START_END: | 999 | case AVIVO_D1MODE_VLINE_START_END: |
| 1002 | header &= R300_CP_PACKET0_REG_MASK; | 1000 | header &= ~R300_CP_PACKET0_REG_MASK; |
| 1003 | header |= AVIVO_D2MODE_VLINE_START_END >> 2; | 1001 | header |= AVIVO_D2MODE_VLINE_START_END >> 2; |
| 1004 | break; | 1002 | break; |
| 1005 | case RADEON_CRTC_GUI_TRIG_VLINE: | 1003 | case RADEON_CRTC_GUI_TRIG_VLINE: |
| 1006 | header &= R300_CP_PACKET0_REG_MASK; | 1004 | header &= ~R300_CP_PACKET0_REG_MASK; |
| 1007 | header |= RADEON_CRTC2_GUI_TRIG_VLINE >> 2; | 1005 | header |= RADEON_CRTC2_GUI_TRIG_VLINE >> 2; |
| 1008 | break; | 1006 | break; |
| 1009 | default: | 1007 | default: |
| @@ -1011,8 +1009,8 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) | |||
| 1011 | r = -EINVAL; | 1009 | r = -EINVAL; |
| 1012 | goto out; | 1010 | goto out; |
| 1013 | } | 1011 | } |
| 1014 | ib_chunk->kdata[h_idx] = header; | 1012 | ib[h_idx] = header; |
| 1015 | ib_chunk->kdata[h_idx + 3] |= RADEON_ENG_DISPLAY_SELECT_CRTC1; | 1013 | ib[h_idx + 3] |= RADEON_ENG_DISPLAY_SELECT_CRTC1; |
| 1016 | } | 1014 | } |
| 1017 | out: | 1015 | out: |
| 1018 | mutex_unlock(&p->rdev->ddev->mode_config.mutex); | 1016 | mutex_unlock(&p->rdev->ddev->mode_config.mutex); |
| @@ -1033,7 +1031,6 @@ out: | |||
| 1033 | int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, | 1031 | int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, |
| 1034 | struct radeon_cs_reloc **cs_reloc) | 1032 | struct radeon_cs_reloc **cs_reloc) |
| 1035 | { | 1033 | { |
| 1036 | struct radeon_cs_chunk *ib_chunk; | ||
| 1037 | struct radeon_cs_chunk *relocs_chunk; | 1034 | struct radeon_cs_chunk *relocs_chunk; |
| 1038 | struct radeon_cs_packet p3reloc; | 1035 | struct radeon_cs_packet p3reloc; |
| 1039 | unsigned idx; | 1036 | unsigned idx; |
| @@ -1044,7 +1041,6 @@ int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, | |||
| 1044 | return -EINVAL; | 1041 | return -EINVAL; |
| 1045 | } | 1042 | } |
| 1046 | *cs_reloc = NULL; | 1043 | *cs_reloc = NULL; |
| 1047 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
| 1048 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; | 1044 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; |
| 1049 | r = r100_cs_packet_parse(p, &p3reloc, p->idx); | 1045 | r = r100_cs_packet_parse(p, &p3reloc, p->idx); |
| 1050 | if (r) { | 1046 | if (r) { |
| @@ -1057,7 +1053,7 @@ int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, | |||
| 1057 | r100_cs_dump_packet(p, &p3reloc); | 1053 | r100_cs_dump_packet(p, &p3reloc); |
| 1058 | return -EINVAL; | 1054 | return -EINVAL; |
| 1059 | } | 1055 | } |
| 1060 | idx = ib_chunk->kdata[p3reloc.idx + 1]; | 1056 | idx = radeon_get_ib_value(p, p3reloc.idx + 1); |
| 1061 | if (idx >= relocs_chunk->length_dw) { | 1057 | if (idx >= relocs_chunk->length_dw) { |
| 1062 | DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", | 1058 | DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", |
| 1063 | idx, relocs_chunk->length_dw); | 1059 | idx, relocs_chunk->length_dw); |
| @@ -1126,7 +1122,6 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1126 | struct radeon_cs_packet *pkt, | 1122 | struct radeon_cs_packet *pkt, |
| 1127 | unsigned idx, unsigned reg) | 1123 | unsigned idx, unsigned reg) |
| 1128 | { | 1124 | { |
| 1129 | struct radeon_cs_chunk *ib_chunk; | ||
| 1130 | struct radeon_cs_reloc *reloc; | 1125 | struct radeon_cs_reloc *reloc; |
| 1131 | struct r100_cs_track *track; | 1126 | struct r100_cs_track *track; |
| 1132 | volatile uint32_t *ib; | 1127 | volatile uint32_t *ib; |
| @@ -1134,11 +1129,13 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1134 | int r; | 1129 | int r; |
| 1135 | int i, face; | 1130 | int i, face; |
| 1136 | u32 tile_flags = 0; | 1131 | u32 tile_flags = 0; |
| 1132 | u32 idx_value; | ||
| 1137 | 1133 | ||
| 1138 | ib = p->ib->ptr; | 1134 | ib = p->ib->ptr; |
| 1139 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
| 1140 | track = (struct r100_cs_track *)p->track; | 1135 | track = (struct r100_cs_track *)p->track; |
| 1141 | 1136 | ||
| 1137 | idx_value = radeon_get_ib_value(p, idx); | ||
| 1138 | |||
| 1142 | switch (reg) { | 1139 | switch (reg) { |
| 1143 | case RADEON_CRTC_GUI_TRIG_VLINE: | 1140 | case RADEON_CRTC_GUI_TRIG_VLINE: |
| 1144 | r = r100_cs_packet_parse_vline(p); | 1141 | r = r100_cs_packet_parse_vline(p); |
| @@ -1166,8 +1163,8 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1166 | return r; | 1163 | return r; |
| 1167 | } | 1164 | } |
| 1168 | track->zb.robj = reloc->robj; | 1165 | track->zb.robj = reloc->robj; |
| 1169 | track->zb.offset = ib_chunk->kdata[idx]; | 1166 | track->zb.offset = idx_value; |
| 1170 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 1167 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 1171 | break; | 1168 | break; |
| 1172 | case RADEON_RB3D_COLOROFFSET: | 1169 | case RADEON_RB3D_COLOROFFSET: |
| 1173 | r = r100_cs_packet_next_reloc(p, &reloc); | 1170 | r = r100_cs_packet_next_reloc(p, &reloc); |
| @@ -1178,8 +1175,8 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1178 | return r; | 1175 | return r; |
| 1179 | } | 1176 | } |
| 1180 | track->cb[0].robj = reloc->robj; | 1177 | track->cb[0].robj = reloc->robj; |
| 1181 | track->cb[0].offset = ib_chunk->kdata[idx]; | 1178 | track->cb[0].offset = idx_value; |
| 1182 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 1179 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 1183 | break; | 1180 | break; |
| 1184 | case RADEON_PP_TXOFFSET_0: | 1181 | case RADEON_PP_TXOFFSET_0: |
| 1185 | case RADEON_PP_TXOFFSET_1: | 1182 | case RADEON_PP_TXOFFSET_1: |
| @@ -1192,7 +1189,7 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1192 | r100_cs_dump_packet(p, pkt); | 1189 | r100_cs_dump_packet(p, pkt); |
| 1193 | return r; | 1190 | return r; |
| 1194 | } | 1191 | } |
| 1195 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 1192 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 1196 | track->textures[i].robj = reloc->robj; | 1193 | track->textures[i].robj = reloc->robj; |
| 1197 | break; | 1194 | break; |
| 1198 | case RADEON_PP_CUBIC_OFFSET_T0_0: | 1195 | case RADEON_PP_CUBIC_OFFSET_T0_0: |
| @@ -1208,8 +1205,8 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1208 | r100_cs_dump_packet(p, pkt); | 1205 | r100_cs_dump_packet(p, pkt); |
| 1209 | return r; | 1206 | return r; |
| 1210 | } | 1207 | } |
| 1211 | track->textures[0].cube_info[i].offset = ib_chunk->kdata[idx]; | 1208 | track->textures[0].cube_info[i].offset = idx_value; |
| 1212 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 1209 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 1213 | track->textures[0].cube_info[i].robj = reloc->robj; | 1210 | track->textures[0].cube_info[i].robj = reloc->robj; |
| 1214 | break; | 1211 | break; |
| 1215 | case RADEON_PP_CUBIC_OFFSET_T1_0: | 1212 | case RADEON_PP_CUBIC_OFFSET_T1_0: |
| @@ -1225,8 +1222,8 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1225 | r100_cs_dump_packet(p, pkt); | 1222 | r100_cs_dump_packet(p, pkt); |
| 1226 | return r; | 1223 | return r; |
| 1227 | } | 1224 | } |
| 1228 | track->textures[1].cube_info[i].offset = ib_chunk->kdata[idx]; | 1225 | track->textures[1].cube_info[i].offset = idx_value; |
| 1229 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 1226 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 1230 | track->textures[1].cube_info[i].robj = reloc->robj; | 1227 | track->textures[1].cube_info[i].robj = reloc->robj; |
| 1231 | break; | 1228 | break; |
| 1232 | case RADEON_PP_CUBIC_OFFSET_T2_0: | 1229 | case RADEON_PP_CUBIC_OFFSET_T2_0: |
| @@ -1242,12 +1239,12 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1242 | r100_cs_dump_packet(p, pkt); | 1239 | r100_cs_dump_packet(p, pkt); |
| 1243 | return r; | 1240 | return r; |
| 1244 | } | 1241 | } |
| 1245 | track->textures[2].cube_info[i].offset = ib_chunk->kdata[idx]; | 1242 | track->textures[2].cube_info[i].offset = idx_value; |
| 1246 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 1243 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 1247 | track->textures[2].cube_info[i].robj = reloc->robj; | 1244 | track->textures[2].cube_info[i].robj = reloc->robj; |
| 1248 | break; | 1245 | break; |
| 1249 | case RADEON_RE_WIDTH_HEIGHT: | 1246 | case RADEON_RE_WIDTH_HEIGHT: |
| 1250 | track->maxy = ((ib_chunk->kdata[idx] >> 16) & 0x7FF); | 1247 | track->maxy = ((idx_value >> 16) & 0x7FF); |
| 1251 | break; | 1248 | break; |
| 1252 | case RADEON_RB3D_COLORPITCH: | 1249 | case RADEON_RB3D_COLORPITCH: |
| 1253 | r = r100_cs_packet_next_reloc(p, &reloc); | 1250 | r = r100_cs_packet_next_reloc(p, &reloc); |
| @@ -1263,17 +1260,17 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1263 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | 1260 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
| 1264 | tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; | 1261 | tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; |
| 1265 | 1262 | ||
| 1266 | tmp = ib_chunk->kdata[idx] & ~(0x7 << 16); | 1263 | tmp = idx_value & ~(0x7 << 16); |
| 1267 | tmp |= tile_flags; | 1264 | tmp |= tile_flags; |
| 1268 | ib[idx] = tmp; | 1265 | ib[idx] = tmp; |
| 1269 | 1266 | ||
| 1270 | track->cb[0].pitch = ib_chunk->kdata[idx] & RADEON_COLORPITCH_MASK; | 1267 | track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; |
| 1271 | break; | 1268 | break; |
| 1272 | case RADEON_RB3D_DEPTHPITCH: | 1269 | case RADEON_RB3D_DEPTHPITCH: |
| 1273 | track->zb.pitch = ib_chunk->kdata[idx] & RADEON_DEPTHPITCH_MASK; | 1270 | track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; |
| 1274 | break; | 1271 | break; |
| 1275 | case RADEON_RB3D_CNTL: | 1272 | case RADEON_RB3D_CNTL: |
| 1276 | switch ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { | 1273 | switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { |
| 1277 | case 7: | 1274 | case 7: |
| 1278 | case 8: | 1275 | case 8: |
| 1279 | case 9: | 1276 | case 9: |
| @@ -1291,13 +1288,13 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1291 | break; | 1288 | break; |
| 1292 | default: | 1289 | default: |
| 1293 | DRM_ERROR("Invalid color buffer format (%d) !\n", | 1290 | DRM_ERROR("Invalid color buffer format (%d) !\n", |
| 1294 | ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); | 1291 | ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); |
| 1295 | return -EINVAL; | 1292 | return -EINVAL; |
| 1296 | } | 1293 | } |
| 1297 | track->z_enabled = !!(ib_chunk->kdata[idx] & RADEON_Z_ENABLE); | 1294 | track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); |
| 1298 | break; | 1295 | break; |
| 1299 | case RADEON_RB3D_ZSTENCILCNTL: | 1296 | case RADEON_RB3D_ZSTENCILCNTL: |
| 1300 | switch (ib_chunk->kdata[idx] & 0xf) { | 1297 | switch (idx_value & 0xf) { |
| 1301 | case 0: | 1298 | case 0: |
| 1302 | track->zb.cpp = 2; | 1299 | track->zb.cpp = 2; |
| 1303 | break; | 1300 | break; |
| @@ -1321,44 +1318,44 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1321 | r100_cs_dump_packet(p, pkt); | 1318 | r100_cs_dump_packet(p, pkt); |
| 1322 | return r; | 1319 | return r; |
| 1323 | } | 1320 | } |
| 1324 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 1321 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 1325 | break; | 1322 | break; |
| 1326 | case RADEON_PP_CNTL: | 1323 | case RADEON_PP_CNTL: |
| 1327 | { | 1324 | { |
| 1328 | uint32_t temp = ib_chunk->kdata[idx] >> 4; | 1325 | uint32_t temp = idx_value >> 4; |
| 1329 | for (i = 0; i < track->num_texture; i++) | 1326 | for (i = 0; i < track->num_texture; i++) |
| 1330 | track->textures[i].enabled = !!(temp & (1 << i)); | 1327 | track->textures[i].enabled = !!(temp & (1 << i)); |
| 1331 | } | 1328 | } |
| 1332 | break; | 1329 | break; |
| 1333 | case RADEON_SE_VF_CNTL: | 1330 | case RADEON_SE_VF_CNTL: |
| 1334 | track->vap_vf_cntl = ib_chunk->kdata[idx]; | 1331 | track->vap_vf_cntl = idx_value; |
| 1335 | break; | 1332 | break; |
| 1336 | case RADEON_SE_VTX_FMT: | 1333 | case RADEON_SE_VTX_FMT: |
| 1337 | track->vtx_size = r100_get_vtx_size(ib_chunk->kdata[idx]); | 1334 | track->vtx_size = r100_get_vtx_size(idx_value); |
| 1338 | break; | 1335 | break; |
| 1339 | case RADEON_PP_TEX_SIZE_0: | 1336 | case RADEON_PP_TEX_SIZE_0: |
| 1340 | case RADEON_PP_TEX_SIZE_1: | 1337 | case RADEON_PP_TEX_SIZE_1: |
| 1341 | case RADEON_PP_TEX_SIZE_2: | 1338 | case RADEON_PP_TEX_SIZE_2: |
| 1342 | i = (reg - RADEON_PP_TEX_SIZE_0) / 8; | 1339 | i = (reg - RADEON_PP_TEX_SIZE_0) / 8; |
| 1343 | track->textures[i].width = (ib_chunk->kdata[idx] & RADEON_TEX_USIZE_MASK) + 1; | 1340 | track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; |
| 1344 | track->textures[i].height = ((ib_chunk->kdata[idx] & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; | 1341 | track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; |
| 1345 | break; | 1342 | break; |
| 1346 | case RADEON_PP_TEX_PITCH_0: | 1343 | case RADEON_PP_TEX_PITCH_0: |
| 1347 | case RADEON_PP_TEX_PITCH_1: | 1344 | case RADEON_PP_TEX_PITCH_1: |
| 1348 | case RADEON_PP_TEX_PITCH_2: | 1345 | case RADEON_PP_TEX_PITCH_2: |
| 1349 | i = (reg - RADEON_PP_TEX_PITCH_0) / 8; | 1346 | i = (reg - RADEON_PP_TEX_PITCH_0) / 8; |
| 1350 | track->textures[i].pitch = ib_chunk->kdata[idx] + 32; | 1347 | track->textures[i].pitch = idx_value + 32; |
| 1351 | break; | 1348 | break; |
| 1352 | case RADEON_PP_TXFILTER_0: | 1349 | case RADEON_PP_TXFILTER_0: |
| 1353 | case RADEON_PP_TXFILTER_1: | 1350 | case RADEON_PP_TXFILTER_1: |
| 1354 | case RADEON_PP_TXFILTER_2: | 1351 | case RADEON_PP_TXFILTER_2: |
| 1355 | i = (reg - RADEON_PP_TXFILTER_0) / 24; | 1352 | i = (reg - RADEON_PP_TXFILTER_0) / 24; |
| 1356 | track->textures[i].num_levels = ((ib_chunk->kdata[idx] & RADEON_MAX_MIP_LEVEL_MASK) | 1353 | track->textures[i].num_levels = ((idx_value & RADEON_MAX_MIP_LEVEL_MASK) |
| 1357 | >> RADEON_MAX_MIP_LEVEL_SHIFT); | 1354 | >> RADEON_MAX_MIP_LEVEL_SHIFT); |
| 1358 | tmp = (ib_chunk->kdata[idx] >> 23) & 0x7; | 1355 | tmp = (idx_value >> 23) & 0x7; |
| 1359 | if (tmp == 2 || tmp == 6) | 1356 | if (tmp == 2 || tmp == 6) |
| 1360 | track->textures[i].roundup_w = false; | 1357 | track->textures[i].roundup_w = false; |
| 1361 | tmp = (ib_chunk->kdata[idx] >> 27) & 0x7; | 1358 | tmp = (idx_value >> 27) & 0x7; |
| 1362 | if (tmp == 2 || tmp == 6) | 1359 | if (tmp == 2 || tmp == 6) |
| 1363 | track->textures[i].roundup_h = false; | 1360 | track->textures[i].roundup_h = false; |
| 1364 | break; | 1361 | break; |
| @@ -1366,16 +1363,16 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1366 | case RADEON_PP_TXFORMAT_1: | 1363 | case RADEON_PP_TXFORMAT_1: |
| 1367 | case RADEON_PP_TXFORMAT_2: | 1364 | case RADEON_PP_TXFORMAT_2: |
| 1368 | i = (reg - RADEON_PP_TXFORMAT_0) / 24; | 1365 | i = (reg - RADEON_PP_TXFORMAT_0) / 24; |
| 1369 | if (ib_chunk->kdata[idx] & RADEON_TXFORMAT_NON_POWER2) { | 1366 | if (idx_value & RADEON_TXFORMAT_NON_POWER2) { |
| 1370 | track->textures[i].use_pitch = 1; | 1367 | track->textures[i].use_pitch = 1; |
| 1371 | } else { | 1368 | } else { |
| 1372 | track->textures[i].use_pitch = 0; | 1369 | track->textures[i].use_pitch = 0; |
| 1373 | track->textures[i].width = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); | 1370 | track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); |
| 1374 | track->textures[i].height = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); | 1371 | track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); |
| 1375 | } | 1372 | } |
| 1376 | if (ib_chunk->kdata[idx] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) | 1373 | if (idx_value & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) |
| 1377 | track->textures[i].tex_coord_type = 2; | 1374 | track->textures[i].tex_coord_type = 2; |
| 1378 | switch ((ib_chunk->kdata[idx] & RADEON_TXFORMAT_FORMAT_MASK)) { | 1375 | switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) { |
| 1379 | case RADEON_TXFORMAT_I8: | 1376 | case RADEON_TXFORMAT_I8: |
| 1380 | case RADEON_TXFORMAT_RGB332: | 1377 | case RADEON_TXFORMAT_RGB332: |
| 1381 | case RADEON_TXFORMAT_Y8: | 1378 | case RADEON_TXFORMAT_Y8: |
| @@ -1402,13 +1399,13 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 1402 | track->textures[i].cpp = 4; | 1399 | track->textures[i].cpp = 4; |
| 1403 | break; | 1400 | break; |
| 1404 | } | 1401 | } |
| 1405 | track->textures[i].cube_info[4].width = 1 << ((ib_chunk->kdata[idx] >> 16) & 0xf); | 1402 | track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); |
| 1406 | track->textures[i].cube_info[4].height = 1 << ((ib_chunk->kdata[idx] >> 20) & 0xf); | 1403 | track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); |
| 1407 | break; | 1404 | break; |
| 1408 | case RADEON_PP_CUBIC_FACES_0: | 1405 | case RADEON_PP_CUBIC_FACES_0: |
| 1409 | case RADEON_PP_CUBIC_FACES_1: | 1406 | case RADEON_PP_CUBIC_FACES_1: |
| 1410 | case RADEON_PP_CUBIC_FACES_2: | 1407 | case RADEON_PP_CUBIC_FACES_2: |
| 1411 | tmp = ib_chunk->kdata[idx]; | 1408 | tmp = idx_value; |
| 1412 | i = (reg - RADEON_PP_CUBIC_FACES_0) / 4; | 1409 | i = (reg - RADEON_PP_CUBIC_FACES_0) / 4; |
| 1413 | for (face = 0; face < 4; face++) { | 1410 | for (face = 0; face < 4; face++) { |
| 1414 | track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); | 1411 | 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, | |||
| 1427 | struct radeon_cs_packet *pkt, | 1424 | struct radeon_cs_packet *pkt, |
| 1428 | struct radeon_object *robj) | 1425 | struct radeon_object *robj) |
| 1429 | { | 1426 | { |
| 1430 | struct radeon_cs_chunk *ib_chunk; | ||
| 1431 | unsigned idx; | 1427 | unsigned idx; |
| 1432 | 1428 | u32 value; | |
| 1433 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
| 1434 | idx = pkt->idx + 1; | 1429 | idx = pkt->idx + 1; |
| 1435 | if ((ib_chunk->kdata[idx+2] + 1) > radeon_object_size(robj)) { | 1430 | value = radeon_get_ib_value(p, idx + 2); |
| 1431 | if ((value + 1) > radeon_object_size(robj)) { | ||
| 1436 | DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER " | 1432 | DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER " |
| 1437 | "(need %u have %lu) !\n", | 1433 | "(need %u have %lu) !\n", |
| 1438 | ib_chunk->kdata[idx+2] + 1, | 1434 | value + 1, |
| 1439 | radeon_object_size(robj)); | 1435 | radeon_object_size(robj)); |
| 1440 | return -EINVAL; | 1436 | return -EINVAL; |
| 1441 | } | 1437 | } |
| @@ -1445,59 +1441,20 @@ int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, | |||
| 1445 | static int r100_packet3_check(struct radeon_cs_parser *p, | 1441 | static int r100_packet3_check(struct radeon_cs_parser *p, |
| 1446 | struct radeon_cs_packet *pkt) | 1442 | struct radeon_cs_packet *pkt) |
| 1447 | { | 1443 | { |
| 1448 | struct radeon_cs_chunk *ib_chunk; | ||
| 1449 | struct radeon_cs_reloc *reloc; | 1444 | struct radeon_cs_reloc *reloc; |
| 1450 | struct r100_cs_track *track; | 1445 | struct r100_cs_track *track; |
| 1451 | unsigned idx; | 1446 | unsigned idx; |
| 1452 | unsigned i, c; | ||
| 1453 | volatile uint32_t *ib; | 1447 | volatile uint32_t *ib; |
| 1454 | int r; | 1448 | int r; |
| 1455 | 1449 | ||
| 1456 | ib = p->ib->ptr; | 1450 | ib = p->ib->ptr; |
| 1457 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
| 1458 | idx = pkt->idx + 1; | 1451 | idx = pkt->idx + 1; |
| 1459 | track = (struct r100_cs_track *)p->track; | 1452 | track = (struct r100_cs_track *)p->track; |
| 1460 | switch (pkt->opcode) { | 1453 | switch (pkt->opcode) { |
| 1461 | case PACKET3_3D_LOAD_VBPNTR: | 1454 | case PACKET3_3D_LOAD_VBPNTR: |
| 1462 | c = ib_chunk->kdata[idx++]; | 1455 | r = r100_packet3_load_vbpntr(p, pkt, idx); |
| 1463 | track->num_arrays = c; | 1456 | if (r) |
| 1464 | for (i = 0; i < (c - 1); i += 2, idx += 3) { | 1457 | return r; |
| 1465 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
| 1466 | if (r) { | ||
| 1467 | DRM_ERROR("No reloc for packet3 %d\n", | ||
| 1468 | pkt->opcode); | ||
| 1469 | r100_cs_dump_packet(p, pkt); | ||
| 1470 | return r; | ||
| 1471 | } | ||
| 1472 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); | ||
| 1473 | track->arrays[i + 0].robj = reloc->robj; | ||
| 1474 | track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8; | ||
| 1475 | track->arrays[i + 0].esize &= 0x7F; | ||
| 1476 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
| 1477 | if (r) { | ||
| 1478 | DRM_ERROR("No reloc for packet3 %d\n", | ||
| 1479 | pkt->opcode); | ||
| 1480 | r100_cs_dump_packet(p, pkt); | ||
| 1481 | return r; | ||
| 1482 | } | ||
| 1483 | ib[idx+2] = ib_chunk->kdata[idx+2] + ((u32)reloc->lobj.gpu_offset); | ||
| 1484 | track->arrays[i + 1].robj = reloc->robj; | ||
| 1485 | track->arrays[i + 1].esize = ib_chunk->kdata[idx] >> 24; | ||
| 1486 | track->arrays[i + 1].esize &= 0x7F; | ||
| 1487 | } | ||
| 1488 | if (c & 1) { | ||
| 1489 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
| 1490 | if (r) { | ||
| 1491 | DRM_ERROR("No reloc for packet3 %d\n", | ||
| 1492 | pkt->opcode); | ||
| 1493 | r100_cs_dump_packet(p, pkt); | ||
| 1494 | return r; | ||
| 1495 | } | ||
| 1496 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); | ||
| 1497 | track->arrays[i + 0].robj = reloc->robj; | ||
| 1498 | track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8; | ||
| 1499 | track->arrays[i + 0].esize &= 0x7F; | ||
| 1500 | } | ||
| 1501 | break; | 1458 | break; |
| 1502 | case PACKET3_INDX_BUFFER: | 1459 | case PACKET3_INDX_BUFFER: |
| 1503 | r = r100_cs_packet_next_reloc(p, &reloc); | 1460 | r = r100_cs_packet_next_reloc(p, &reloc); |
| @@ -1506,7 +1463,7 @@ static int r100_packet3_check(struct radeon_cs_parser *p, | |||
| 1506 | r100_cs_dump_packet(p, pkt); | 1463 | r100_cs_dump_packet(p, pkt); |
| 1507 | return r; | 1464 | return r; |
| 1508 | } | 1465 | } |
| 1509 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); | 1466 | ib[idx+1] = radeon_get_ib_value(p, idx+1) + ((u32)reloc->lobj.gpu_offset); |
| 1510 | r = r100_cs_track_check_pkt3_indx_buffer(p, pkt, reloc->robj); | 1467 | r = r100_cs_track_check_pkt3_indx_buffer(p, pkt, reloc->robj); |
| 1511 | if (r) { | 1468 | if (r) { |
| 1512 | return r; | 1469 | return r; |
| @@ -1520,27 +1477,27 @@ static int r100_packet3_check(struct radeon_cs_parser *p, | |||
| 1520 | r100_cs_dump_packet(p, pkt); | 1477 | r100_cs_dump_packet(p, pkt); |
| 1521 | return r; | 1478 | return r; |
| 1522 | } | 1479 | } |
| 1523 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 1480 | ib[idx] = radeon_get_ib_value(p, idx) + ((u32)reloc->lobj.gpu_offset); |
| 1524 | track->num_arrays = 1; | 1481 | track->num_arrays = 1; |
| 1525 | track->vtx_size = r100_get_vtx_size(ib_chunk->kdata[idx+2]); | 1482 | track->vtx_size = r100_get_vtx_size(radeon_get_ib_value(p, idx + 2)); |
| 1526 | 1483 | ||
| 1527 | track->arrays[0].robj = reloc->robj; | 1484 | track->arrays[0].robj = reloc->robj; |
| 1528 | track->arrays[0].esize = track->vtx_size; | 1485 | track->arrays[0].esize = track->vtx_size; |
| 1529 | 1486 | ||
| 1530 | track->max_indx = ib_chunk->kdata[idx+1]; | 1487 | track->max_indx = radeon_get_ib_value(p, idx+1); |
| 1531 | 1488 | ||
| 1532 | track->vap_vf_cntl = ib_chunk->kdata[idx+3]; | 1489 | track->vap_vf_cntl = radeon_get_ib_value(p, idx+3); |
| 1533 | track->immd_dwords = pkt->count - 1; | 1490 | track->immd_dwords = pkt->count - 1; |
| 1534 | r = r100_cs_track_check(p->rdev, track); | 1491 | r = r100_cs_track_check(p->rdev, track); |
| 1535 | if (r) | 1492 | if (r) |
| 1536 | return r; | 1493 | return r; |
| 1537 | break; | 1494 | break; |
| 1538 | case PACKET3_3D_DRAW_IMMD: | 1495 | case PACKET3_3D_DRAW_IMMD: |
| 1539 | if (((ib_chunk->kdata[idx+1] >> 4) & 0x3) != 3) { | 1496 | if (((radeon_get_ib_value(p, idx + 1) >> 4) & 0x3) != 3) { |
| 1540 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); | 1497 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); |
| 1541 | return -EINVAL; | 1498 | return -EINVAL; |
| 1542 | } | 1499 | } |
| 1543 | track->vap_vf_cntl = ib_chunk->kdata[idx+1]; | 1500 | track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); |
| 1544 | track->immd_dwords = pkt->count - 1; | 1501 | track->immd_dwords = pkt->count - 1; |
| 1545 | r = r100_cs_track_check(p->rdev, track); | 1502 | r = r100_cs_track_check(p->rdev, track); |
| 1546 | if (r) | 1503 | if (r) |
| @@ -1548,11 +1505,11 @@ static int r100_packet3_check(struct radeon_cs_parser *p, | |||
| 1548 | break; | 1505 | break; |
| 1549 | /* triggers drawing using in-packet vertex data */ | 1506 | /* triggers drawing using in-packet vertex data */ |
| 1550 | case PACKET3_3D_DRAW_IMMD_2: | 1507 | case PACKET3_3D_DRAW_IMMD_2: |
| 1551 | if (((ib_chunk->kdata[idx] >> 4) & 0x3) != 3) { | 1508 | if (((radeon_get_ib_value(p, idx) >> 4) & 0x3) != 3) { |
| 1552 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); | 1509 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); |
| 1553 | return -EINVAL; | 1510 | return -EINVAL; |
| 1554 | } | 1511 | } |
| 1555 | track->vap_vf_cntl = ib_chunk->kdata[idx]; | 1512 | track->vap_vf_cntl = radeon_get_ib_value(p, idx); |
| 1556 | track->immd_dwords = pkt->count; | 1513 | track->immd_dwords = pkt->count; |
| 1557 | r = r100_cs_track_check(p->rdev, track); | 1514 | r = r100_cs_track_check(p->rdev, track); |
| 1558 | if (r) | 1515 | if (r) |
| @@ -1560,28 +1517,28 @@ static int r100_packet3_check(struct radeon_cs_parser *p, | |||
| 1560 | break; | 1517 | break; |
| 1561 | /* triggers drawing using in-packet vertex data */ | 1518 | /* triggers drawing using in-packet vertex data */ |
| 1562 | case PACKET3_3D_DRAW_VBUF_2: | 1519 | case PACKET3_3D_DRAW_VBUF_2: |
| 1563 | track->vap_vf_cntl = ib_chunk->kdata[idx]; | 1520 | track->vap_vf_cntl = radeon_get_ib_value(p, idx); |
| 1564 | r = r100_cs_track_check(p->rdev, track); | 1521 | r = r100_cs_track_check(p->rdev, track); |
| 1565 | if (r) | 1522 | if (r) |
| 1566 | return r; | 1523 | return r; |
| 1567 | break; | 1524 | break; |
| 1568 | /* triggers drawing of vertex buffers setup elsewhere */ | 1525 | /* triggers drawing of vertex buffers setup elsewhere */ |
| 1569 | case PACKET3_3D_DRAW_INDX_2: | 1526 | case PACKET3_3D_DRAW_INDX_2: |
| 1570 | track->vap_vf_cntl = ib_chunk->kdata[idx]; | 1527 | track->vap_vf_cntl = radeon_get_ib_value(p, idx); |
| 1571 | r = r100_cs_track_check(p->rdev, track); | 1528 | r = r100_cs_track_check(p->rdev, track); |
| 1572 | if (r) | 1529 | if (r) |
| 1573 | return r; | 1530 | return r; |
| 1574 | break; | 1531 | break; |
| 1575 | /* triggers drawing using indices to vertex buffer */ | 1532 | /* triggers drawing using indices to vertex buffer */ |
| 1576 | case PACKET3_3D_DRAW_VBUF: | 1533 | case PACKET3_3D_DRAW_VBUF: |
| 1577 | track->vap_vf_cntl = ib_chunk->kdata[idx + 1]; | 1534 | track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); |
| 1578 | r = r100_cs_track_check(p->rdev, track); | 1535 | r = r100_cs_track_check(p->rdev, track); |
| 1579 | if (r) | 1536 | if (r) |
| 1580 | return r; | 1537 | return r; |
| 1581 | break; | 1538 | break; |
| 1582 | /* triggers drawing of vertex buffers setup elsewhere */ | 1539 | /* triggers drawing of vertex buffers setup elsewhere */ |
| 1583 | case PACKET3_3D_DRAW_INDX: | 1540 | case PACKET3_3D_DRAW_INDX: |
| 1584 | track->vap_vf_cntl = ib_chunk->kdata[idx + 1]; | 1541 | track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); |
| 1585 | r = r100_cs_track_check(p->rdev, track); | 1542 | r = r100_cs_track_check(p->rdev, track); |
| 1586 | if (r) | 1543 | if (r) |
| 1587 | return r; | 1544 | return r; |
diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h index 70a82eda394a..0daf0d76a891 100644 --- a/drivers/gpu/drm/radeon/r100_track.h +++ b/drivers/gpu/drm/radeon/r100_track.h | |||
| @@ -84,6 +84,8 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 84 | struct radeon_cs_packet *pkt, | 84 | struct radeon_cs_packet *pkt, |
| 85 | unsigned idx, unsigned reg); | 85 | unsigned idx, unsigned reg); |
| 86 | 86 | ||
| 87 | |||
| 88 | |||
| 87 | static inline int r100_reloc_pitch_offset(struct radeon_cs_parser *p, | 89 | static inline int r100_reloc_pitch_offset(struct radeon_cs_parser *p, |
| 88 | struct radeon_cs_packet *pkt, | 90 | struct radeon_cs_packet *pkt, |
| 89 | unsigned idx, | 91 | unsigned idx, |
| @@ -93,9 +95,7 @@ static inline int r100_reloc_pitch_offset(struct radeon_cs_parser *p, | |||
| 93 | u32 tile_flags = 0; | 95 | u32 tile_flags = 0; |
| 94 | u32 tmp; | 96 | u32 tmp; |
| 95 | struct radeon_cs_reloc *reloc; | 97 | struct radeon_cs_reloc *reloc; |
| 96 | struct radeon_cs_chunk *ib_chunk; | 98 | u32 value; |
| 97 | |||
| 98 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
| 99 | 99 | ||
| 100 | r = r100_cs_packet_next_reloc(p, &reloc); | 100 | r = r100_cs_packet_next_reloc(p, &reloc); |
| 101 | if (r) { | 101 | if (r) { |
| @@ -104,7 +104,8 @@ static inline int r100_reloc_pitch_offset(struct radeon_cs_parser *p, | |||
| 104 | r100_cs_dump_packet(p, pkt); | 104 | r100_cs_dump_packet(p, pkt); |
| 105 | return r; | 105 | return r; |
| 106 | } | 106 | } |
| 107 | tmp = ib_chunk->kdata[idx] & 0x003fffff; | 107 | value = radeon_get_ib_value(p, idx); |
| 108 | tmp = value & 0x003fffff; | ||
| 108 | tmp += (((u32)reloc->lobj.gpu_offset) >> 10); | 109 | tmp += (((u32)reloc->lobj.gpu_offset) >> 10); |
| 109 | 110 | ||
| 110 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | 111 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
| @@ -119,6 +120,64 @@ static inline int r100_reloc_pitch_offset(struct radeon_cs_parser *p, | |||
| 119 | } | 120 | } |
| 120 | 121 | ||
| 121 | tmp |= tile_flags; | 122 | tmp |= tile_flags; |
| 122 | p->ib->ptr[idx] = (ib_chunk->kdata[idx] & 0x3fc00000) | tmp; | 123 | p->ib->ptr[idx] = (value & 0x3fc00000) | tmp; |
| 123 | return 0; | 124 | return 0; |
| 124 | } | 125 | } |
| 126 | |||
| 127 | static inline int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, | ||
| 128 | struct radeon_cs_packet *pkt, | ||
| 129 | int idx) | ||
| 130 | { | ||
| 131 | unsigned c, i; | ||
| 132 | struct radeon_cs_reloc *reloc; | ||
| 133 | struct r100_cs_track *track; | ||
| 134 | int r = 0; | ||
| 135 | volatile uint32_t *ib; | ||
| 136 | u32 idx_value; | ||
| 137 | |||
| 138 | ib = p->ib->ptr; | ||
| 139 | track = (struct r100_cs_track *)p->track; | ||
| 140 | c = radeon_get_ib_value(p, idx++) & 0x1F; | ||
| 141 | track->num_arrays = c; | ||
| 142 | for (i = 0; i < (c - 1); i+=2, idx+=3) { | ||
| 143 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
| 144 | if (r) { | ||
| 145 | DRM_ERROR("No reloc for packet3 %d\n", | ||
| 146 | pkt->opcode); | ||
| 147 | r100_cs_dump_packet(p, pkt); | ||
| 148 | return r; | ||
| 149 | } | ||
| 150 | idx_value = radeon_get_ib_value(p, idx); | ||
| 151 | ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset); | ||
| 152 | |||
| 153 | track->arrays[i + 0].esize = idx_value >> 8; | ||
| 154 | track->arrays[i + 0].robj = reloc->robj; | ||
| 155 | track->arrays[i + 0].esize &= 0x7F; | ||
| 156 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
| 157 | if (r) { | ||
| 158 | DRM_ERROR("No reloc for packet3 %d\n", | ||
| 159 | pkt->opcode); | ||
| 160 | r100_cs_dump_packet(p, pkt); | ||
| 161 | return r; | ||
| 162 | } | ||
| 163 | ib[idx+2] = radeon_get_ib_value(p, idx + 2) + ((u32)reloc->lobj.gpu_offset); | ||
| 164 | track->arrays[i + 1].robj = reloc->robj; | ||
| 165 | track->arrays[i + 1].esize = idx_value >> 24; | ||
| 166 | track->arrays[i + 1].esize &= 0x7F; | ||
| 167 | } | ||
| 168 | if (c & 1) { | ||
| 169 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
| 170 | if (r) { | ||
| 171 | DRM_ERROR("No reloc for packet3 %d\n", | ||
| 172 | pkt->opcode); | ||
| 173 | r100_cs_dump_packet(p, pkt); | ||
| 174 | return r; | ||
| 175 | } | ||
| 176 | idx_value = radeon_get_ib_value(p, idx); | ||
| 177 | ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset); | ||
| 178 | track->arrays[i + 0].robj = reloc->robj; | ||
| 179 | track->arrays[i + 0].esize = idx_value >> 8; | ||
| 180 | track->arrays[i + 0].esize &= 0x7F; | ||
| 181 | } | ||
| 182 | return r; | ||
| 183 | } | ||
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index 568c74bfba3d..cf7fea5ff2e5 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c | |||
| @@ -96,7 +96,6 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 96 | struct radeon_cs_packet *pkt, | 96 | struct radeon_cs_packet *pkt, |
| 97 | unsigned idx, unsigned reg) | 97 | unsigned idx, unsigned reg) |
| 98 | { | 98 | { |
| 99 | struct radeon_cs_chunk *ib_chunk; | ||
| 100 | struct radeon_cs_reloc *reloc; | 99 | struct radeon_cs_reloc *reloc; |
| 101 | struct r100_cs_track *track; | 100 | struct r100_cs_track *track; |
| 102 | volatile uint32_t *ib; | 101 | volatile uint32_t *ib; |
| @@ -105,11 +104,11 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 105 | int i; | 104 | int i; |
| 106 | int face; | 105 | int face; |
| 107 | u32 tile_flags = 0; | 106 | u32 tile_flags = 0; |
| 107 | u32 idx_value; | ||
| 108 | 108 | ||
| 109 | ib = p->ib->ptr; | 109 | ib = p->ib->ptr; |
| 110 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
| 111 | track = (struct r100_cs_track *)p->track; | 110 | track = (struct r100_cs_track *)p->track; |
| 112 | 111 | idx_value = radeon_get_ib_value(p, idx); | |
| 113 | switch (reg) { | 112 | switch (reg) { |
| 114 | case RADEON_CRTC_GUI_TRIG_VLINE: | 113 | case RADEON_CRTC_GUI_TRIG_VLINE: |
| 115 | r = r100_cs_packet_parse_vline(p); | 114 | r = r100_cs_packet_parse_vline(p); |
| @@ -137,8 +136,8 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 137 | return r; | 136 | return r; |
| 138 | } | 137 | } |
| 139 | track->zb.robj = reloc->robj; | 138 | track->zb.robj = reloc->robj; |
| 140 | track->zb.offset = ib_chunk->kdata[idx]; | 139 | track->zb.offset = idx_value; |
| 141 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 140 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 142 | break; | 141 | break; |
| 143 | case RADEON_RB3D_COLOROFFSET: | 142 | case RADEON_RB3D_COLOROFFSET: |
| 144 | r = r100_cs_packet_next_reloc(p, &reloc); | 143 | r = r100_cs_packet_next_reloc(p, &reloc); |
| @@ -149,8 +148,8 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 149 | return r; | 148 | return r; |
| 150 | } | 149 | } |
| 151 | track->cb[0].robj = reloc->robj; | 150 | track->cb[0].robj = reloc->robj; |
| 152 | track->cb[0].offset = ib_chunk->kdata[idx]; | 151 | track->cb[0].offset = idx_value; |
| 153 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 152 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 154 | break; | 153 | break; |
| 155 | case R200_PP_TXOFFSET_0: | 154 | case R200_PP_TXOFFSET_0: |
| 156 | case R200_PP_TXOFFSET_1: | 155 | case R200_PP_TXOFFSET_1: |
| @@ -166,7 +165,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 166 | r100_cs_dump_packet(p, pkt); | 165 | r100_cs_dump_packet(p, pkt); |
| 167 | return r; | 166 | return r; |
| 168 | } | 167 | } |
| 169 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 168 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 170 | track->textures[i].robj = reloc->robj; | 169 | track->textures[i].robj = reloc->robj; |
| 171 | break; | 170 | break; |
| 172 | case R200_PP_CUBIC_OFFSET_F1_0: | 171 | case R200_PP_CUBIC_OFFSET_F1_0: |
| @@ -208,12 +207,12 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 208 | r100_cs_dump_packet(p, pkt); | 207 | r100_cs_dump_packet(p, pkt); |
| 209 | return r; | 208 | return r; |
| 210 | } | 209 | } |
| 211 | track->textures[i].cube_info[face - 1].offset = ib_chunk->kdata[idx]; | 210 | track->textures[i].cube_info[face - 1].offset = idx_value; |
| 212 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 211 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 213 | track->textures[i].cube_info[face - 1].robj = reloc->robj; | 212 | track->textures[i].cube_info[face - 1].robj = reloc->robj; |
| 214 | break; | 213 | break; |
| 215 | case RADEON_RE_WIDTH_HEIGHT: | 214 | case RADEON_RE_WIDTH_HEIGHT: |
| 216 | track->maxy = ((ib_chunk->kdata[idx] >> 16) & 0x7FF); | 215 | track->maxy = ((idx_value >> 16) & 0x7FF); |
| 217 | break; | 216 | break; |
| 218 | case RADEON_RB3D_COLORPITCH: | 217 | case RADEON_RB3D_COLORPITCH: |
| 219 | r = r100_cs_packet_next_reloc(p, &reloc); | 218 | r = r100_cs_packet_next_reloc(p, &reloc); |
| @@ -229,17 +228,17 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 229 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | 228 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
| 230 | tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; | 229 | tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; |
| 231 | 230 | ||
| 232 | tmp = ib_chunk->kdata[idx] & ~(0x7 << 16); | 231 | tmp = idx_value & ~(0x7 << 16); |
| 233 | tmp |= tile_flags; | 232 | tmp |= tile_flags; |
| 234 | ib[idx] = tmp; | 233 | ib[idx] = tmp; |
| 235 | 234 | ||
| 236 | track->cb[0].pitch = ib_chunk->kdata[idx] & RADEON_COLORPITCH_MASK; | 235 | track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; |
| 237 | break; | 236 | break; |
| 238 | case RADEON_RB3D_DEPTHPITCH: | 237 | case RADEON_RB3D_DEPTHPITCH: |
| 239 | track->zb.pitch = ib_chunk->kdata[idx] & RADEON_DEPTHPITCH_MASK; | 238 | track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; |
| 240 | break; | 239 | break; |
| 241 | case RADEON_RB3D_CNTL: | 240 | case RADEON_RB3D_CNTL: |
| 242 | switch ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { | 241 | switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { |
| 243 | case 7: | 242 | case 7: |
| 244 | case 8: | 243 | case 8: |
| 245 | case 9: | 244 | case 9: |
| @@ -257,18 +256,18 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 257 | break; | 256 | break; |
| 258 | default: | 257 | default: |
| 259 | DRM_ERROR("Invalid color buffer format (%d) !\n", | 258 | DRM_ERROR("Invalid color buffer format (%d) !\n", |
| 260 | ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); | 259 | ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); |
| 261 | return -EINVAL; | 260 | return -EINVAL; |
| 262 | } | 261 | } |
| 263 | if (ib_chunk->kdata[idx] & RADEON_DEPTHXY_OFFSET_ENABLE) { | 262 | if (idx_value & RADEON_DEPTHXY_OFFSET_ENABLE) { |
| 264 | DRM_ERROR("No support for depth xy offset in kms\n"); | 263 | DRM_ERROR("No support for depth xy offset in kms\n"); |
| 265 | return -EINVAL; | 264 | return -EINVAL; |
| 266 | } | 265 | } |
| 267 | 266 | ||
| 268 | track->z_enabled = !!(ib_chunk->kdata[idx] & RADEON_Z_ENABLE); | 267 | track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); |
| 269 | break; | 268 | break; |
| 270 | case RADEON_RB3D_ZSTENCILCNTL: | 269 | case RADEON_RB3D_ZSTENCILCNTL: |
| 271 | switch (ib_chunk->kdata[idx] & 0xf) { | 270 | switch (idx_value & 0xf) { |
| 272 | case 0: | 271 | case 0: |
| 273 | track->zb.cpp = 2; | 272 | track->zb.cpp = 2; |
| 274 | break; | 273 | break; |
| @@ -292,27 +291,27 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 292 | r100_cs_dump_packet(p, pkt); | 291 | r100_cs_dump_packet(p, pkt); |
| 293 | return r; | 292 | return r; |
| 294 | } | 293 | } |
| 295 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 294 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 296 | break; | 295 | break; |
| 297 | case RADEON_PP_CNTL: | 296 | case RADEON_PP_CNTL: |
| 298 | { | 297 | { |
| 299 | uint32_t temp = ib_chunk->kdata[idx] >> 4; | 298 | uint32_t temp = idx_value >> 4; |
| 300 | for (i = 0; i < track->num_texture; i++) | 299 | for (i = 0; i < track->num_texture; i++) |
| 301 | track->textures[i].enabled = !!(temp & (1 << i)); | 300 | track->textures[i].enabled = !!(temp & (1 << i)); |
| 302 | } | 301 | } |
| 303 | break; | 302 | break; |
| 304 | case RADEON_SE_VF_CNTL: | 303 | case RADEON_SE_VF_CNTL: |
| 305 | track->vap_vf_cntl = ib_chunk->kdata[idx]; | 304 | track->vap_vf_cntl = idx_value; |
| 306 | break; | 305 | break; |
| 307 | case 0x210c: | 306 | case 0x210c: |
| 308 | /* VAP_VF_MAX_VTX_INDX */ | 307 | /* VAP_VF_MAX_VTX_INDX */ |
| 309 | track->max_indx = ib_chunk->kdata[idx] & 0x00FFFFFFUL; | 308 | track->max_indx = idx_value & 0x00FFFFFFUL; |
| 310 | break; | 309 | break; |
| 311 | case R200_SE_VTX_FMT_0: | 310 | case R200_SE_VTX_FMT_0: |
| 312 | track->vtx_size = r200_get_vtx_size_0(ib_chunk->kdata[idx]); | 311 | track->vtx_size = r200_get_vtx_size_0(idx_value); |
| 313 | break; | 312 | break; |
| 314 | case R200_SE_VTX_FMT_1: | 313 | case R200_SE_VTX_FMT_1: |
| 315 | track->vtx_size += r200_get_vtx_size_1(ib_chunk->kdata[idx]); | 314 | track->vtx_size += r200_get_vtx_size_1(idx_value); |
| 316 | break; | 315 | break; |
| 317 | case R200_PP_TXSIZE_0: | 316 | case R200_PP_TXSIZE_0: |
| 318 | case R200_PP_TXSIZE_1: | 317 | case R200_PP_TXSIZE_1: |
| @@ -321,8 +320,8 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 321 | case R200_PP_TXSIZE_4: | 320 | case R200_PP_TXSIZE_4: |
| 322 | case R200_PP_TXSIZE_5: | 321 | case R200_PP_TXSIZE_5: |
| 323 | i = (reg - R200_PP_TXSIZE_0) / 32; | 322 | i = (reg - R200_PP_TXSIZE_0) / 32; |
| 324 | track->textures[i].width = (ib_chunk->kdata[idx] & RADEON_TEX_USIZE_MASK) + 1; | 323 | track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; |
| 325 | track->textures[i].height = ((ib_chunk->kdata[idx] & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; | 324 | track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; |
| 326 | break; | 325 | break; |
| 327 | case R200_PP_TXPITCH_0: | 326 | case R200_PP_TXPITCH_0: |
| 328 | case R200_PP_TXPITCH_1: | 327 | case R200_PP_TXPITCH_1: |
| @@ -331,7 +330,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 331 | case R200_PP_TXPITCH_4: | 330 | case R200_PP_TXPITCH_4: |
| 332 | case R200_PP_TXPITCH_5: | 331 | case R200_PP_TXPITCH_5: |
| 333 | i = (reg - R200_PP_TXPITCH_0) / 32; | 332 | i = (reg - R200_PP_TXPITCH_0) / 32; |
| 334 | track->textures[i].pitch = ib_chunk->kdata[idx] + 32; | 333 | track->textures[i].pitch = idx_value + 32; |
| 335 | break; | 334 | break; |
| 336 | case R200_PP_TXFILTER_0: | 335 | case R200_PP_TXFILTER_0: |
| 337 | case R200_PP_TXFILTER_1: | 336 | case R200_PP_TXFILTER_1: |
| @@ -340,12 +339,12 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 340 | case R200_PP_TXFILTER_4: | 339 | case R200_PP_TXFILTER_4: |
| 341 | case R200_PP_TXFILTER_5: | 340 | case R200_PP_TXFILTER_5: |
| 342 | i = (reg - R200_PP_TXFILTER_0) / 32; | 341 | i = (reg - R200_PP_TXFILTER_0) / 32; |
| 343 | track->textures[i].num_levels = ((ib_chunk->kdata[idx] & R200_MAX_MIP_LEVEL_MASK) | 342 | track->textures[i].num_levels = ((idx_value & R200_MAX_MIP_LEVEL_MASK) |
| 344 | >> R200_MAX_MIP_LEVEL_SHIFT); | 343 | >> R200_MAX_MIP_LEVEL_SHIFT); |
| 345 | tmp = (ib_chunk->kdata[idx] >> 23) & 0x7; | 344 | tmp = (idx_value >> 23) & 0x7; |
| 346 | if (tmp == 2 || tmp == 6) | 345 | if (tmp == 2 || tmp == 6) |
| 347 | track->textures[i].roundup_w = false; | 346 | track->textures[i].roundup_w = false; |
| 348 | tmp = (ib_chunk->kdata[idx] >> 27) & 0x7; | 347 | tmp = (idx_value >> 27) & 0x7; |
| 349 | if (tmp == 2 || tmp == 6) | 348 | if (tmp == 2 || tmp == 6) |
| 350 | track->textures[i].roundup_h = false; | 349 | track->textures[i].roundup_h = false; |
| 351 | break; | 350 | break; |
| @@ -364,8 +363,8 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 364 | case R200_PP_TXFORMAT_X_4: | 363 | case R200_PP_TXFORMAT_X_4: |
| 365 | case R200_PP_TXFORMAT_X_5: | 364 | case R200_PP_TXFORMAT_X_5: |
| 366 | i = (reg - R200_PP_TXFORMAT_X_0) / 32; | 365 | i = (reg - R200_PP_TXFORMAT_X_0) / 32; |
| 367 | track->textures[i].txdepth = ib_chunk->kdata[idx] & 0x7; | 366 | track->textures[i].txdepth = idx_value & 0x7; |
| 368 | tmp = (ib_chunk->kdata[idx] >> 16) & 0x3; | 367 | tmp = (idx_value >> 16) & 0x3; |
| 369 | /* 2D, 3D, CUBE */ | 368 | /* 2D, 3D, CUBE */ |
| 370 | switch (tmp) { | 369 | switch (tmp) { |
| 371 | case 0: | 370 | case 0: |
| @@ -389,14 +388,14 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 389 | case R200_PP_TXFORMAT_4: | 388 | case R200_PP_TXFORMAT_4: |
| 390 | case R200_PP_TXFORMAT_5: | 389 | case R200_PP_TXFORMAT_5: |
| 391 | i = (reg - R200_PP_TXFORMAT_0) / 32; | 390 | i = (reg - R200_PP_TXFORMAT_0) / 32; |
| 392 | if (ib_chunk->kdata[idx] & R200_TXFORMAT_NON_POWER2) { | 391 | if (idx_value & R200_TXFORMAT_NON_POWER2) { |
| 393 | track->textures[i].use_pitch = 1; | 392 | track->textures[i].use_pitch = 1; |
| 394 | } else { | 393 | } else { |
| 395 | track->textures[i].use_pitch = 0; | 394 | track->textures[i].use_pitch = 0; |
| 396 | track->textures[i].width = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); | 395 | track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); |
| 397 | track->textures[i].height = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); | 396 | track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); |
| 398 | } | 397 | } |
| 399 | switch ((ib_chunk->kdata[idx] & RADEON_TXFORMAT_FORMAT_MASK)) { | 398 | switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) { |
| 400 | case R200_TXFORMAT_I8: | 399 | case R200_TXFORMAT_I8: |
| 401 | case R200_TXFORMAT_RGB332: | 400 | case R200_TXFORMAT_RGB332: |
| 402 | case R200_TXFORMAT_Y8: | 401 | case R200_TXFORMAT_Y8: |
| @@ -424,8 +423,8 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 424 | track->textures[i].cpp = 4; | 423 | track->textures[i].cpp = 4; |
| 425 | break; | 424 | break; |
| 426 | } | 425 | } |
| 427 | track->textures[i].cube_info[4].width = 1 << ((ib_chunk->kdata[idx] >> 16) & 0xf); | 426 | track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); |
| 428 | track->textures[i].cube_info[4].height = 1 << ((ib_chunk->kdata[idx] >> 20) & 0xf); | 427 | track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); |
| 429 | break; | 428 | break; |
| 430 | case R200_PP_CUBIC_FACES_0: | 429 | case R200_PP_CUBIC_FACES_0: |
| 431 | case R200_PP_CUBIC_FACES_1: | 430 | case R200_PP_CUBIC_FACES_1: |
| @@ -433,7 +432,7 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
| 433 | case R200_PP_CUBIC_FACES_3: | 432 | case R200_PP_CUBIC_FACES_3: |
| 434 | case R200_PP_CUBIC_FACES_4: | 433 | case R200_PP_CUBIC_FACES_4: |
| 435 | case R200_PP_CUBIC_FACES_5: | 434 | case R200_PP_CUBIC_FACES_5: |
| 436 | tmp = ib_chunk->kdata[idx]; | 435 | tmp = idx_value; |
| 437 | i = (reg - R200_PP_CUBIC_FACES_0) / 32; | 436 | i = (reg - R200_PP_CUBIC_FACES_0) / 32; |
| 438 | for (face = 0; face < 4; face++) { | 437 | for (face = 0; face < 4; face++) { |
| 439 | track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); | 438 | track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index bb151ecdf8fc..1ebea8cc8c93 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
| @@ -697,17 +697,18 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 697 | struct radeon_cs_packet *pkt, | 697 | struct radeon_cs_packet *pkt, |
| 698 | unsigned idx, unsigned reg) | 698 | unsigned idx, unsigned reg) |
| 699 | { | 699 | { |
| 700 | struct radeon_cs_chunk *ib_chunk; | ||
| 701 | struct radeon_cs_reloc *reloc; | 700 | struct radeon_cs_reloc *reloc; |
| 702 | struct r100_cs_track *track; | 701 | struct r100_cs_track *track; |
| 703 | volatile uint32_t *ib; | 702 | volatile uint32_t *ib; |
| 704 | uint32_t tmp, tile_flags = 0; | 703 | uint32_t tmp, tile_flags = 0; |
| 705 | unsigned i; | 704 | unsigned i; |
| 706 | int r; | 705 | int r; |
| 706 | u32 idx_value; | ||
| 707 | 707 | ||
| 708 | ib = p->ib->ptr; | 708 | ib = p->ib->ptr; |
| 709 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
| 710 | track = (struct r100_cs_track *)p->track; | 709 | track = (struct r100_cs_track *)p->track; |
| 710 | idx_value = radeon_get_ib_value(p, idx); | ||
| 711 | |||
| 711 | switch(reg) { | 712 | switch(reg) { |
| 712 | case AVIVO_D1MODE_VLINE_START_END: | 713 | case AVIVO_D1MODE_VLINE_START_END: |
| 713 | case RADEON_CRTC_GUI_TRIG_VLINE: | 714 | case RADEON_CRTC_GUI_TRIG_VLINE: |
| @@ -738,8 +739,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 738 | return r; | 739 | return r; |
| 739 | } | 740 | } |
| 740 | track->cb[i].robj = reloc->robj; | 741 | track->cb[i].robj = reloc->robj; |
| 741 | track->cb[i].offset = ib_chunk->kdata[idx]; | 742 | track->cb[i].offset = idx_value; |
| 742 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 743 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 743 | break; | 744 | break; |
| 744 | case R300_ZB_DEPTHOFFSET: | 745 | case R300_ZB_DEPTHOFFSET: |
| 745 | r = r100_cs_packet_next_reloc(p, &reloc); | 746 | r = r100_cs_packet_next_reloc(p, &reloc); |
| @@ -750,8 +751,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 750 | return r; | 751 | return r; |
| 751 | } | 752 | } |
| 752 | track->zb.robj = reloc->robj; | 753 | track->zb.robj = reloc->robj; |
| 753 | track->zb.offset = ib_chunk->kdata[idx]; | 754 | track->zb.offset = idx_value; |
| 754 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 755 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 755 | break; | 756 | break; |
| 756 | case R300_TX_OFFSET_0: | 757 | case R300_TX_OFFSET_0: |
| 757 | case R300_TX_OFFSET_0+4: | 758 | case R300_TX_OFFSET_0+4: |
| @@ -777,32 +778,32 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 777 | r100_cs_dump_packet(p, pkt); | 778 | r100_cs_dump_packet(p, pkt); |
| 778 | return r; | 779 | return r; |
| 779 | } | 780 | } |
| 780 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 781 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 781 | track->textures[i].robj = reloc->robj; | 782 | track->textures[i].robj = reloc->robj; |
| 782 | break; | 783 | break; |
| 783 | /* Tracked registers */ | 784 | /* Tracked registers */ |
| 784 | case 0x2084: | 785 | case 0x2084: |
| 785 | /* VAP_VF_CNTL */ | 786 | /* VAP_VF_CNTL */ |
| 786 | track->vap_vf_cntl = ib_chunk->kdata[idx]; | 787 | track->vap_vf_cntl = idx_value; |
| 787 | break; | 788 | break; |
| 788 | case 0x20B4: | 789 | case 0x20B4: |
| 789 | /* VAP_VTX_SIZE */ | 790 | /* VAP_VTX_SIZE */ |
| 790 | track->vtx_size = ib_chunk->kdata[idx] & 0x7F; | 791 | track->vtx_size = idx_value & 0x7F; |
| 791 | break; | 792 | break; |
| 792 | case 0x2134: | 793 | case 0x2134: |
| 793 | /* VAP_VF_MAX_VTX_INDX */ | 794 | /* VAP_VF_MAX_VTX_INDX */ |
| 794 | track->max_indx = ib_chunk->kdata[idx] & 0x00FFFFFFUL; | 795 | track->max_indx = idx_value & 0x00FFFFFFUL; |
| 795 | break; | 796 | break; |
| 796 | case 0x43E4: | 797 | case 0x43E4: |
| 797 | /* SC_SCISSOR1 */ | 798 | /* SC_SCISSOR1 */ |
| 798 | track->maxy = ((ib_chunk->kdata[idx] >> 13) & 0x1FFF) + 1; | 799 | track->maxy = ((idx_value >> 13) & 0x1FFF) + 1; |
| 799 | if (p->rdev->family < CHIP_RV515) { | 800 | if (p->rdev->family < CHIP_RV515) { |
| 800 | track->maxy -= 1440; | 801 | track->maxy -= 1440; |
| 801 | } | 802 | } |
| 802 | break; | 803 | break; |
| 803 | case 0x4E00: | 804 | case 0x4E00: |
| 804 | /* RB3D_CCTL */ | 805 | /* RB3D_CCTL */ |
| 805 | track->num_cb = ((ib_chunk->kdata[idx] >> 5) & 0x3) + 1; | 806 | track->num_cb = ((idx_value >> 5) & 0x3) + 1; |
| 806 | break; | 807 | break; |
| 807 | case 0x4E38: | 808 | case 0x4E38: |
| 808 | case 0x4E3C: | 809 | case 0x4E3C: |
| @@ -825,13 +826,13 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 825 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | 826 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
| 826 | tile_flags |= R300_COLOR_MICROTILE_ENABLE; | 827 | tile_flags |= R300_COLOR_MICROTILE_ENABLE; |
| 827 | 828 | ||
| 828 | tmp = ib_chunk->kdata[idx] & ~(0x7 << 16); | 829 | tmp = idx_value & ~(0x7 << 16); |
| 829 | tmp |= tile_flags; | 830 | tmp |= tile_flags; |
| 830 | ib[idx] = tmp; | 831 | ib[idx] = tmp; |
| 831 | 832 | ||
| 832 | i = (reg - 0x4E38) >> 2; | 833 | i = (reg - 0x4E38) >> 2; |
| 833 | track->cb[i].pitch = ib_chunk->kdata[idx] & 0x3FFE; | 834 | track->cb[i].pitch = idx_value & 0x3FFE; |
| 834 | switch (((ib_chunk->kdata[idx] >> 21) & 0xF)) { | 835 | switch (((idx_value >> 21) & 0xF)) { |
| 835 | case 9: | 836 | case 9: |
| 836 | case 11: | 837 | case 11: |
| 837 | case 12: | 838 | case 12: |
| @@ -854,13 +855,13 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 854 | break; | 855 | break; |
| 855 | default: | 856 | default: |
| 856 | DRM_ERROR("Invalid color buffer format (%d) !\n", | 857 | DRM_ERROR("Invalid color buffer format (%d) !\n", |
| 857 | ((ib_chunk->kdata[idx] >> 21) & 0xF)); | 858 | ((idx_value >> 21) & 0xF)); |
| 858 | return -EINVAL; | 859 | return -EINVAL; |
| 859 | } | 860 | } |
| 860 | break; | 861 | break; |
| 861 | case 0x4F00: | 862 | case 0x4F00: |
| 862 | /* ZB_CNTL */ | 863 | /* ZB_CNTL */ |
| 863 | if (ib_chunk->kdata[idx] & 2) { | 864 | if (idx_value & 2) { |
| 864 | track->z_enabled = true; | 865 | track->z_enabled = true; |
| 865 | } else { | 866 | } else { |
| 866 | track->z_enabled = false; | 867 | track->z_enabled = false; |
| @@ -868,7 +869,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 868 | break; | 869 | break; |
| 869 | case 0x4F10: | 870 | case 0x4F10: |
| 870 | /* ZB_FORMAT */ | 871 | /* ZB_FORMAT */ |
| 871 | switch ((ib_chunk->kdata[idx] & 0xF)) { | 872 | switch ((idx_value & 0xF)) { |
| 872 | case 0: | 873 | case 0: |
| 873 | case 1: | 874 | case 1: |
| 874 | track->zb.cpp = 2; | 875 | track->zb.cpp = 2; |
| @@ -878,7 +879,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 878 | break; | 879 | break; |
| 879 | default: | 880 | default: |
| 880 | DRM_ERROR("Invalid z buffer format (%d) !\n", | 881 | DRM_ERROR("Invalid z buffer format (%d) !\n", |
| 881 | (ib_chunk->kdata[idx] & 0xF)); | 882 | (idx_value & 0xF)); |
| 882 | return -EINVAL; | 883 | return -EINVAL; |
| 883 | } | 884 | } |
| 884 | break; | 885 | break; |
| @@ -897,17 +898,17 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 897 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | 898 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
| 898 | tile_flags |= R300_DEPTHMICROTILE_TILED;; | 899 | tile_flags |= R300_DEPTHMICROTILE_TILED;; |
| 899 | 900 | ||
| 900 | tmp = ib_chunk->kdata[idx] & ~(0x7 << 16); | 901 | tmp = idx_value & ~(0x7 << 16); |
| 901 | tmp |= tile_flags; | 902 | tmp |= tile_flags; |
| 902 | ib[idx] = tmp; | 903 | ib[idx] = tmp; |
| 903 | 904 | ||
| 904 | track->zb.pitch = ib_chunk->kdata[idx] & 0x3FFC; | 905 | track->zb.pitch = idx_value & 0x3FFC; |
| 905 | break; | 906 | break; |
| 906 | case 0x4104: | 907 | case 0x4104: |
| 907 | for (i = 0; i < 16; i++) { | 908 | for (i = 0; i < 16; i++) { |
| 908 | bool enabled; | 909 | bool enabled; |
| 909 | 910 | ||
| 910 | enabled = !!(ib_chunk->kdata[idx] & (1 << i)); | 911 | enabled = !!(idx_value & (1 << i)); |
| 911 | track->textures[i].enabled = enabled; | 912 | track->textures[i].enabled = enabled; |
| 912 | } | 913 | } |
| 913 | break; | 914 | break; |
| @@ -929,9 +930,9 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 929 | case 0x44FC: | 930 | case 0x44FC: |
| 930 | /* TX_FORMAT1_[0-15] */ | 931 | /* TX_FORMAT1_[0-15] */ |
| 931 | i = (reg - 0x44C0) >> 2; | 932 | i = (reg - 0x44C0) >> 2; |
| 932 | tmp = (ib_chunk->kdata[idx] >> 25) & 0x3; | 933 | tmp = (idx_value >> 25) & 0x3; |
| 933 | track->textures[i].tex_coord_type = tmp; | 934 | track->textures[i].tex_coord_type = tmp; |
| 934 | switch ((ib_chunk->kdata[idx] & 0x1F)) { | 935 | switch ((idx_value & 0x1F)) { |
| 935 | case R300_TX_FORMAT_X8: | 936 | case R300_TX_FORMAT_X8: |
| 936 | case R300_TX_FORMAT_Y4X4: | 937 | case R300_TX_FORMAT_Y4X4: |
| 937 | case R300_TX_FORMAT_Z3Y3X2: | 938 | case R300_TX_FORMAT_Z3Y3X2: |
| @@ -971,7 +972,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 971 | break; | 972 | break; |
| 972 | default: | 973 | default: |
| 973 | DRM_ERROR("Invalid texture format %u\n", | 974 | DRM_ERROR("Invalid texture format %u\n", |
| 974 | (ib_chunk->kdata[idx] & 0x1F)); | 975 | (idx_value & 0x1F)); |
| 975 | return -EINVAL; | 976 | return -EINVAL; |
| 976 | break; | 977 | break; |
| 977 | } | 978 | } |
| @@ -994,11 +995,11 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 994 | case 0x443C: | 995 | case 0x443C: |
| 995 | /* TX_FILTER0_[0-15] */ | 996 | /* TX_FILTER0_[0-15] */ |
| 996 | i = (reg - 0x4400) >> 2; | 997 | i = (reg - 0x4400) >> 2; |
| 997 | tmp = ib_chunk->kdata[idx] & 0x7; | 998 | tmp = idx_value & 0x7; |
| 998 | if (tmp == 2 || tmp == 4 || tmp == 6) { | 999 | if (tmp == 2 || tmp == 4 || tmp == 6) { |
| 999 | track->textures[i].roundup_w = false; | 1000 | track->textures[i].roundup_w = false; |
| 1000 | } | 1001 | } |
| 1001 | tmp = (ib_chunk->kdata[idx] >> 3) & 0x7; | 1002 | tmp = (idx_value >> 3) & 0x7; |
| 1002 | if (tmp == 2 || tmp == 4 || tmp == 6) { | 1003 | if (tmp == 2 || tmp == 4 || tmp == 6) { |
| 1003 | track->textures[i].roundup_h = false; | 1004 | track->textures[i].roundup_h = false; |
| 1004 | } | 1005 | } |
| @@ -1021,12 +1022,12 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 1021 | case 0x453C: | 1022 | case 0x453C: |
| 1022 | /* TX_FORMAT2_[0-15] */ | 1023 | /* TX_FORMAT2_[0-15] */ |
| 1023 | i = (reg - 0x4500) >> 2; | 1024 | i = (reg - 0x4500) >> 2; |
| 1024 | tmp = ib_chunk->kdata[idx] & 0x3FFF; | 1025 | tmp = idx_value & 0x3FFF; |
| 1025 | track->textures[i].pitch = tmp + 1; | 1026 | track->textures[i].pitch = tmp + 1; |
| 1026 | if (p->rdev->family >= CHIP_RV515) { | 1027 | if (p->rdev->family >= CHIP_RV515) { |
| 1027 | tmp = ((ib_chunk->kdata[idx] >> 15) & 1) << 11; | 1028 | tmp = ((idx_value >> 15) & 1) << 11; |
| 1028 | track->textures[i].width_11 = tmp; | 1029 | track->textures[i].width_11 = tmp; |
| 1029 | tmp = ((ib_chunk->kdata[idx] >> 16) & 1) << 11; | 1030 | tmp = ((idx_value >> 16) & 1) << 11; |
| 1030 | track->textures[i].height_11 = tmp; | 1031 | track->textures[i].height_11 = tmp; |
| 1031 | } | 1032 | } |
| 1032 | break; | 1033 | break; |
| @@ -1048,15 +1049,15 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 1048 | case 0x44BC: | 1049 | case 0x44BC: |
| 1049 | /* TX_FORMAT0_[0-15] */ | 1050 | /* TX_FORMAT0_[0-15] */ |
| 1050 | i = (reg - 0x4480) >> 2; | 1051 | i = (reg - 0x4480) >> 2; |
| 1051 | tmp = ib_chunk->kdata[idx] & 0x7FF; | 1052 | tmp = idx_value & 0x7FF; |
| 1052 | track->textures[i].width = tmp + 1; | 1053 | track->textures[i].width = tmp + 1; |
| 1053 | tmp = (ib_chunk->kdata[idx] >> 11) & 0x7FF; | 1054 | tmp = (idx_value >> 11) & 0x7FF; |
| 1054 | track->textures[i].height = tmp + 1; | 1055 | track->textures[i].height = tmp + 1; |
| 1055 | tmp = (ib_chunk->kdata[idx] >> 26) & 0xF; | 1056 | tmp = (idx_value >> 26) & 0xF; |
| 1056 | track->textures[i].num_levels = tmp; | 1057 | track->textures[i].num_levels = tmp; |
| 1057 | tmp = ib_chunk->kdata[idx] & (1 << 31); | 1058 | tmp = idx_value & (1 << 31); |
| 1058 | track->textures[i].use_pitch = !!tmp; | 1059 | track->textures[i].use_pitch = !!tmp; |
| 1059 | tmp = (ib_chunk->kdata[idx] >> 22) & 0xF; | 1060 | tmp = (idx_value >> 22) & 0xF; |
| 1060 | track->textures[i].txdepth = tmp; | 1061 | track->textures[i].txdepth = tmp; |
| 1061 | break; | 1062 | break; |
| 1062 | case R300_ZB_ZPASS_ADDR: | 1063 | case R300_ZB_ZPASS_ADDR: |
| @@ -1067,7 +1068,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 1067 | r100_cs_dump_packet(p, pkt); | 1068 | r100_cs_dump_packet(p, pkt); |
| 1068 | return r; | 1069 | return r; |
| 1069 | } | 1070 | } |
| 1070 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 1071 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
| 1071 | break; | 1072 | break; |
| 1072 | case 0x4be8: | 1073 | case 0x4be8: |
| 1073 | /* valid register only on RV530 */ | 1074 | /* valid register only on RV530 */ |
| @@ -1085,60 +1086,20 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 1085 | static int r300_packet3_check(struct radeon_cs_parser *p, | 1086 | static int r300_packet3_check(struct radeon_cs_parser *p, |
| 1086 | struct radeon_cs_packet *pkt) | 1087 | struct radeon_cs_packet *pkt) |
| 1087 | { | 1088 | { |
| 1088 | struct radeon_cs_chunk *ib_chunk; | ||
| 1089 | |||
| 1090 | struct radeon_cs_reloc *reloc; | 1089 | struct radeon_cs_reloc *reloc; |
| 1091 | struct r100_cs_track *track; | 1090 | struct r100_cs_track *track; |
| 1092 | volatile uint32_t *ib; | 1091 | volatile uint32_t *ib; |
| 1093 | unsigned idx; | 1092 | unsigned idx; |
| 1094 | unsigned i, c; | ||
| 1095 | int r; | 1093 | int r; |
| 1096 | 1094 | ||
| 1097 | ib = p->ib->ptr; | 1095 | ib = p->ib->ptr; |
| 1098 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
| 1099 | idx = pkt->idx + 1; | 1096 | idx = pkt->idx + 1; |
| 1100 | track = (struct r100_cs_track *)p->track; | 1097 | track = (struct r100_cs_track *)p->track; |
| 1101 | switch(pkt->opcode) { | 1098 | switch(pkt->opcode) { |
| 1102 | case PACKET3_3D_LOAD_VBPNTR: | 1099 | case PACKET3_3D_LOAD_VBPNTR: |
| 1103 | c = ib_chunk->kdata[idx++] & 0x1F; | 1100 | r = r100_packet3_load_vbpntr(p, pkt, idx); |
| 1104 | track->num_arrays = c; | 1101 | if (r) |
| 1105 | for (i = 0; i < (c - 1); i+=2, idx+=3) { | 1102 | return r; |
| 1106 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
| 1107 | if (r) { | ||
| 1108 | DRM_ERROR("No reloc for packet3 %d\n", | ||
| 1109 | pkt->opcode); | ||
| 1110 | r100_cs_dump_packet(p, pkt); | ||
| 1111 | return r; | ||
| 1112 | } | ||
| 1113 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); | ||
| 1114 | track->arrays[i + 0].robj = reloc->robj; | ||
| 1115 | track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8; | ||
| 1116 | track->arrays[i + 0].esize &= 0x7F; | ||
| 1117 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
| 1118 | if (r) { | ||
| 1119 | DRM_ERROR("No reloc for packet3 %d\n", | ||
| 1120 | pkt->opcode); | ||
| 1121 | r100_cs_dump_packet(p, pkt); | ||
| 1122 | return r; | ||
| 1123 | } | ||
| 1124 | ib[idx+2] = ib_chunk->kdata[idx+2] + ((u32)reloc->lobj.gpu_offset); | ||
| 1125 | track->arrays[i + 1].robj = reloc->robj; | ||
| 1126 | track->arrays[i + 1].esize = ib_chunk->kdata[idx] >> 24; | ||
| 1127 | track->arrays[i + 1].esize &= 0x7F; | ||
| 1128 | } | ||
| 1129 | if (c & 1) { | ||
| 1130 | r = r100_cs_packet_next_reloc(p, &reloc); | ||
| 1131 | if (r) { | ||
| 1132 | DRM_ERROR("No reloc for packet3 %d\n", | ||
| 1133 | pkt->opcode); | ||
| 1134 | r100_cs_dump_packet(p, pkt); | ||
| 1135 | return r; | ||
| 1136 | } | ||
| 1137 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); | ||
| 1138 | track->arrays[i + 0].robj = reloc->robj; | ||
| 1139 | track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8; | ||
| 1140 | track->arrays[i + 0].esize &= 0x7F; | ||
| 1141 | } | ||
| 1142 | break; | 1103 | break; |
| 1143 | case PACKET3_INDX_BUFFER: | 1104 | case PACKET3_INDX_BUFFER: |
| 1144 | r = r100_cs_packet_next_reloc(p, &reloc); | 1105 | r = r100_cs_packet_next_reloc(p, &reloc); |
| @@ -1147,7 +1108,7 @@ static int r300_packet3_check(struct radeon_cs_parser *p, | |||
| 1147 | r100_cs_dump_packet(p, pkt); | 1108 | r100_cs_dump_packet(p, pkt); |
| 1148 | return r; | 1109 | return r; |
| 1149 | } | 1110 | } |
| 1150 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); | 1111 | ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset); |
| 1151 | r = r100_cs_track_check_pkt3_indx_buffer(p, pkt, reloc->robj); | 1112 | r = r100_cs_track_check_pkt3_indx_buffer(p, pkt, reloc->robj); |
| 1152 | if (r) { | 1113 | if (r) { |
| 1153 | return r; | 1114 | return r; |
| @@ -1158,11 +1119,11 @@ static int r300_packet3_check(struct radeon_cs_parser *p, | |||
| 1158 | /* Number of dwords is vtx_size * (num_vertices - 1) | 1119 | /* Number of dwords is vtx_size * (num_vertices - 1) |
| 1159 | * PRIM_WALK must be equal to 3 vertex data in embedded | 1120 | * PRIM_WALK must be equal to 3 vertex data in embedded |
| 1160 | * in cmd stream */ | 1121 | * in cmd stream */ |
| 1161 | if (((ib_chunk->kdata[idx+1] >> 4) & 0x3) != 3) { | 1122 | if (((radeon_get_ib_value(p, idx + 1) >> 4) & 0x3) != 3) { |
| 1162 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); | 1123 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); |
| 1163 | return -EINVAL; | 1124 | return -EINVAL; |
| 1164 | } | 1125 | } |
| 1165 | track->vap_vf_cntl = ib_chunk->kdata[idx+1]; | 1126 | track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); |
| 1166 | track->immd_dwords = pkt->count - 1; | 1127 | track->immd_dwords = pkt->count - 1; |
| 1167 | r = r100_cs_track_check(p->rdev, track); | 1128 | r = r100_cs_track_check(p->rdev, track); |
| 1168 | if (r) { | 1129 | if (r) { |
| @@ -1173,11 +1134,11 @@ static int r300_packet3_check(struct radeon_cs_parser *p, | |||
| 1173 | /* Number of dwords is vtx_size * (num_vertices - 1) | 1134 | /* Number of dwords is vtx_size * (num_vertices - 1) |
| 1174 | * PRIM_WALK must be equal to 3 vertex data in embedded | 1135 | * PRIM_WALK must be equal to 3 vertex data in embedded |
| 1175 | * in cmd stream */ | 1136 | * in cmd stream */ |
| 1176 | if (((ib_chunk->kdata[idx] >> 4) & 0x3) != 3) { | 1137 | if (((radeon_get_ib_value(p, idx) >> 4) & 0x3) != 3) { |
| 1177 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); | 1138 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); |
| 1178 | return -EINVAL; | 1139 | return -EINVAL; |
| 1179 | } | 1140 | } |
| 1180 | track->vap_vf_cntl = ib_chunk->kdata[idx]; | 1141 | track->vap_vf_cntl = radeon_get_ib_value(p, idx); |
| 1181 | track->immd_dwords = pkt->count; | 1142 | track->immd_dwords = pkt->count; |
| 1182 | r = r100_cs_track_check(p->rdev, track); | 1143 | r = r100_cs_track_check(p->rdev, track); |
| 1183 | if (r) { | 1144 | if (r) { |
| @@ -1185,28 +1146,28 @@ static int r300_packet3_check(struct radeon_cs_parser *p, | |||
| 1185 | } | 1146 | } |
| 1186 | break; | 1147 | break; |
| 1187 | case PACKET3_3D_DRAW_VBUF: | 1148 | case PACKET3_3D_DRAW_VBUF: |
| 1188 | track->vap_vf_cntl = ib_chunk->kdata[idx + 1]; | 1149 | track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); |
| 1189 | r = r100_cs_track_check(p->rdev, track); | 1150 | r = r100_cs_track_check(p->rdev, track); |
| 1190 | if (r) { | 1151 | if (r) { |
| 1191 | return r; | 1152 | return r; |
| 1192 | } | 1153 | } |
| 1193 | break; | 1154 | break; |
| 1194 | case PACKET3_3D_DRAW_VBUF_2: | 1155 | case PACKET3_3D_DRAW_VBUF_2: |
| 1195 | track->vap_vf_cntl = ib_chunk->kdata[idx]; | 1156 | track->vap_vf_cntl = radeon_get_ib_value(p, idx); |
| 1196 | r = r100_cs_track_check(p->rdev, track); | 1157 | r = r100_cs_track_check(p->rdev, track); |
| 1197 | if (r) { | 1158 | if (r) { |
| 1198 | return r; | 1159 | return r; |
| 1199 | } | 1160 | } |
| 1200 | break; | 1161 | break; |
| 1201 | case PACKET3_3D_DRAW_INDX: | 1162 | case PACKET3_3D_DRAW_INDX: |
| 1202 | track->vap_vf_cntl = ib_chunk->kdata[idx + 1]; | 1163 | track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); |
| 1203 | r = r100_cs_track_check(p->rdev, track); | 1164 | r = r100_cs_track_check(p->rdev, track); |
| 1204 | if (r) { | 1165 | if (r) { |
| 1205 | return r; | 1166 | return r; |
| 1206 | } | 1167 | } |
| 1207 | break; | 1168 | break; |
| 1208 | case PACKET3_3D_DRAW_INDX_2: | 1169 | case PACKET3_3D_DRAW_INDX_2: |
| 1209 | track->vap_vf_cntl = ib_chunk->kdata[idx]; | 1170 | track->vap_vf_cntl = radeon_get_ib_value(p, idx); |
| 1210 | r = r100_cs_track_check(p->rdev, track); | 1171 | r = r100_cs_track_check(p->rdev, track); |
| 1211 | if (r) { | 1172 | if (r) { |
| 1212 | return r; | 1173 | return r; |
diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h index e1d5e0331e19..868add6e166d 100644 --- a/drivers/gpu/drm/radeon/r500_reg.h +++ b/drivers/gpu/drm/radeon/r500_reg.h | |||
| @@ -445,6 +445,8 @@ | |||
| 445 | #define AVIVO_D1MODE_VBLANK_STATUS 0x6534 | 445 | #define AVIVO_D1MODE_VBLANK_STATUS 0x6534 |
| 446 | # define AVIVO_VBLANK_ACK (1 << 4) | 446 | # define AVIVO_VBLANK_ACK (1 << 4) |
| 447 | #define AVIVO_D1MODE_VLINE_START_END 0x6538 | 447 | #define AVIVO_D1MODE_VLINE_START_END 0x6538 |
| 448 | #define AVIVO_D1MODE_VLINE_STATUS 0x653c | ||
| 449 | # define AVIVO_D1MODE_VLINE_STAT (1 << 12) | ||
| 448 | #define AVIVO_DxMODE_INT_MASK 0x6540 | 450 | #define AVIVO_DxMODE_INT_MASK 0x6540 |
| 449 | # define AVIVO_D1MODE_INT_MASK (1 << 0) | 451 | # define AVIVO_D1MODE_INT_MASK (1 << 0) |
| 450 | # define AVIVO_D2MODE_INT_MASK (1 << 8) | 452 | # define AVIVO_D2MODE_INT_MASK (1 << 8) |
| @@ -502,6 +504,7 @@ | |||
| 502 | 504 | ||
| 503 | #define AVIVO_D2MODE_VBLANK_STATUS 0x6d34 | 505 | #define AVIVO_D2MODE_VBLANK_STATUS 0x6d34 |
| 504 | #define AVIVO_D2MODE_VLINE_START_END 0x6d38 | 506 | #define AVIVO_D2MODE_VLINE_START_END 0x6d38 |
| 507 | #define AVIVO_D2MODE_VLINE_STATUS 0x6d3c | ||
| 505 | #define AVIVO_D2MODE_VIEWPORT_START 0x6d80 | 508 | #define AVIVO_D2MODE_VIEWPORT_START 0x6d80 |
| 506 | #define AVIVO_D2MODE_VIEWPORT_SIZE 0x6d84 | 509 | #define AVIVO_D2MODE_VIEWPORT_SIZE 0x6d84 |
| 507 | #define AVIVO_D2MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6d88 | 510 | #define AVIVO_D2MODE_EXT_OVERSCAN_LEFT_RIGHT 0x6d88 |
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index d4b0b9d2e39b..0bf13fccdaf2 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c | |||
| @@ -26,108 +26,13 @@ | |||
| 26 | * Jerome Glisse | 26 | * Jerome Glisse |
| 27 | */ | 27 | */ |
| 28 | #include "drmP.h" | 28 | #include "drmP.h" |
| 29 | #include "radeon_reg.h" | ||
| 30 | #include "radeon.h" | 29 | #include "radeon.h" |
| 30 | #include "atom.h" | ||
| 31 | #include "r520d.h" | ||
| 31 | 32 | ||
| 32 | /* r520,rv530,rv560,rv570,r580 depends on : */ | 33 | /* This files gather functions specifics to: r520,rv530,rv560,rv570,r580 */ |
| 33 | void r100_hdp_reset(struct radeon_device *rdev); | ||
| 34 | void r420_pipes_init(struct radeon_device *rdev); | ||
| 35 | void rs600_mc_disable_clients(struct radeon_device *rdev); | ||
| 36 | void rs600_disable_vga(struct radeon_device *rdev); | ||
| 37 | int rv515_debugfs_pipes_info_init(struct radeon_device *rdev); | ||
| 38 | int rv515_debugfs_ga_info_init(struct radeon_device *rdev); | ||
| 39 | 34 | ||
| 40 | /* This files gather functions specifics to: | 35 | static int r520_mc_wait_for_idle(struct radeon_device *rdev) |
| 41 | * r520,rv530,rv560,rv570,r580 | ||
| 42 | * | ||
| 43 | * Some of these functions might be used by newer ASICs. | ||
| 44 | */ | ||
| 45 | void r520_gpu_init(struct radeon_device *rdev); | ||
| 46 | int r520_mc_wait_for_idle(struct radeon_device *rdev); | ||
| 47 | |||
| 48 | |||
| 49 | /* | ||
| 50 | * MC | ||
| 51 | */ | ||
| 52 | int r520_mc_init(struct radeon_device *rdev) | ||
| 53 | { | ||
| 54 | uint32_t tmp; | ||
| 55 | int r; | ||
| 56 | |||
| 57 | if (r100_debugfs_rbbm_init(rdev)) { | ||
| 58 | DRM_ERROR("Failed to register debugfs file for RBBM !\n"); | ||
| 59 | } | ||
| 60 | if (rv515_debugfs_pipes_info_init(rdev)) { | ||
| 61 | DRM_ERROR("Failed to register debugfs file for pipes !\n"); | ||
| 62 | } | ||
| 63 | if (rv515_debugfs_ga_info_init(rdev)) { | ||
| 64 | DRM_ERROR("Failed to register debugfs file for pipes !\n"); | ||
| 65 | } | ||
| 66 | |||
| 67 | r520_gpu_init(rdev); | ||
| 68 | rv370_pcie_gart_disable(rdev); | ||
| 69 | |||
| 70 | /* Setup GPU memory space */ | ||
| 71 | rdev->mc.vram_location = 0xFFFFFFFFUL; | ||
| 72 | rdev->mc.gtt_location = 0xFFFFFFFFUL; | ||
| 73 | if (rdev->flags & RADEON_IS_AGP) { | ||
| 74 | r = radeon_agp_init(rdev); | ||
| 75 | if (r) { | ||
| 76 | printk(KERN_WARNING "[drm] Disabling AGP\n"); | ||
| 77 | rdev->flags &= ~RADEON_IS_AGP; | ||
| 78 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | ||
| 79 | } else { | ||
| 80 | rdev->mc.gtt_location = rdev->mc.agp_base; | ||
| 81 | } | ||
| 82 | } | ||
| 83 | r = radeon_mc_setup(rdev); | ||
| 84 | if (r) { | ||
| 85 | return r; | ||
| 86 | } | ||
| 87 | |||
| 88 | /* Program GPU memory space */ | ||
| 89 | rs600_mc_disable_clients(rdev); | ||
| 90 | if (r520_mc_wait_for_idle(rdev)) { | ||
| 91 | printk(KERN_WARNING "Failed to wait MC idle while " | ||
| 92 | "programming pipes. Bad things might happen.\n"); | ||
| 93 | } | ||
| 94 | /* Write VRAM size in case we are limiting it */ | ||
| 95 | WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size); | ||
| 96 | tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; | ||
| 97 | tmp = REG_SET(R520_MC_FB_TOP, tmp >> 16); | ||
| 98 | tmp |= REG_SET(R520_MC_FB_START, rdev->mc.vram_location >> 16); | ||
| 99 | WREG32_MC(R520_MC_FB_LOCATION, tmp); | ||
| 100 | WREG32(RS690_HDP_FB_LOCATION, rdev->mc.vram_location >> 16); | ||
| 101 | WREG32(0x310, rdev->mc.vram_location); | ||
| 102 | if (rdev->flags & RADEON_IS_AGP) { | ||
| 103 | tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; | ||
| 104 | tmp = REG_SET(R520_MC_AGP_TOP, tmp >> 16); | ||
| 105 | tmp |= REG_SET(R520_MC_AGP_START, rdev->mc.gtt_location >> 16); | ||
| 106 | WREG32_MC(R520_MC_AGP_LOCATION, tmp); | ||
| 107 | WREG32_MC(R520_MC_AGP_BASE, rdev->mc.agp_base); | ||
| 108 | WREG32_MC(R520_MC_AGP_BASE_2, 0); | ||
| 109 | } else { | ||
| 110 | WREG32_MC(R520_MC_AGP_LOCATION, 0x0FFFFFFF); | ||
| 111 | WREG32_MC(R520_MC_AGP_BASE, 0); | ||
| 112 | WREG32_MC(R520_MC_AGP_BASE_2, 0); | ||
| 113 | } | ||
| 114 | return 0; | ||
| 115 | } | ||
| 116 | |||
| 117 | void r520_mc_fini(struct radeon_device *rdev) | ||
| 118 | { | ||
| 119 | } | ||
| 120 | |||
| 121 | |||
| 122 | /* | ||
| 123 | * Global GPU functions | ||
| 124 | */ | ||
| 125 | void r520_errata(struct radeon_device *rdev) | ||
| 126 | { | ||
| 127 | rdev->pll_errata = 0; | ||
| 128 | } | ||
| 129 | |||
| 130 | int r520_mc_wait_for_idle(struct radeon_device *rdev) | ||
| 131 | { | 36 | { |
| 132 | unsigned i; | 37 | unsigned i; |
| 133 | uint32_t tmp; | 38 | uint32_t tmp; |
| @@ -143,12 +48,12 @@ int r520_mc_wait_for_idle(struct radeon_device *rdev) | |||
| 143 | return -1; | 48 | return -1; |
| 144 | } | 49 | } |
| 145 | 50 | ||
| 146 | void r520_gpu_init(struct radeon_device *rdev) | 51 | static void r520_gpu_init(struct radeon_device *rdev) |
| 147 | { | 52 | { |
| 148 | unsigned pipe_select_current, gb_pipe_select, tmp; | 53 | unsigned pipe_select_current, gb_pipe_select, tmp; |
| 149 | 54 | ||
| 150 | r100_hdp_reset(rdev); | 55 | r100_hdp_reset(rdev); |
| 151 | rs600_disable_vga(rdev); | 56 | rv515_vga_render_disable(rdev); |
| 152 | /* | 57 | /* |
| 153 | * DST_PIPE_CONFIG 0x170C | 58 | * DST_PIPE_CONFIG 0x170C |
| 154 | * GB_TILE_CONFIG 0x4018 | 59 | * GB_TILE_CONFIG 0x4018 |
| @@ -186,10 +91,6 @@ void r520_gpu_init(struct radeon_device *rdev) | |||
| 186 | } | 91 | } |
| 187 | } | 92 | } |
| 188 | 93 | ||
| 189 | |||
| 190 | /* | ||
| 191 | * VRAM info | ||
| 192 | */ | ||
| 193 | static void r520_vram_get_type(struct radeon_device *rdev) | 94 | static void r520_vram_get_type(struct radeon_device *rdev) |
| 194 | { | 95 | { |
| 195 | uint32_t tmp; | 96 | uint32_t tmp; |
| @@ -233,7 +134,168 @@ void r520_vram_info(struct radeon_device *rdev) | |||
| 233 | rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); | 134 | rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); |
| 234 | } | 135 | } |
| 235 | 136 | ||
| 236 | void r520_bandwidth_update(struct radeon_device *rdev) | 137 | void r520_mc_program(struct radeon_device *rdev) |
| 138 | { | ||
| 139 | struct rv515_mc_save save; | ||
| 140 | |||
| 141 | /* Stops all mc clients */ | ||
| 142 | rv515_mc_stop(rdev, &save); | ||
| 143 | |||
| 144 | /* Wait for mc idle */ | ||
| 145 | if (r520_mc_wait_for_idle(rdev)) | ||
| 146 | dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); | ||
| 147 | /* Write VRAM size in case we are limiting it */ | ||
| 148 | WREG32(R_0000F8_CONFIG_MEMSIZE, rdev->mc.real_vram_size); | ||
| 149 | /* Program MC, should be a 32bits limited address space */ | ||
| 150 | WREG32_MC(R_000004_MC_FB_LOCATION, | ||
| 151 | S_000004_MC_FB_START(rdev->mc.vram_start >> 16) | | ||
| 152 | S_000004_MC_FB_TOP(rdev->mc.vram_end >> 16)); | ||
| 153 | WREG32(R_000134_HDP_FB_LOCATION, | ||
| 154 | S_000134_HDP_FB_START(rdev->mc.vram_start >> 16)); | ||
| 155 | if (rdev->flags & RADEON_IS_AGP) { | ||
| 156 | WREG32_MC(R_000005_MC_AGP_LOCATION, | ||
| 157 | S_000005_MC_AGP_START(rdev->mc.gtt_start >> 16) | | ||
| 158 | S_000005_MC_AGP_TOP(rdev->mc.gtt_end >> 16)); | ||
| 159 | WREG32_MC(R_000006_AGP_BASE, lower_32_bits(rdev->mc.agp_base)); | ||
| 160 | WREG32_MC(R_000007_AGP_BASE_2, | ||
| 161 | S_000007_AGP_BASE_ADDR_2(upper_32_bits(rdev->mc.agp_base))); | ||
| 162 | } else { | ||
| 163 | WREG32_MC(R_000005_MC_AGP_LOCATION, 0xFFFFFFFF); | ||
| 164 | WREG32_MC(R_000006_AGP_BASE, 0); | ||
| 165 | WREG32_MC(R_000007_AGP_BASE_2, 0); | ||
| 166 | } | ||
| 167 | |||
| 168 | rv515_mc_resume(rdev, &save); | ||
| 169 | } | ||
| 170 | |||
| 171 | static int r520_startup(struct radeon_device *rdev) | ||
| 172 | { | ||
| 173 | int r; | ||
| 174 | |||
| 175 | r520_mc_program(rdev); | ||
| 176 | /* Resume clock */ | ||
| 177 | rv515_clock_startup(rdev); | ||
| 178 | /* Initialize GPU configuration (# pipes, ...) */ | ||
| 179 | r520_gpu_init(rdev); | ||
| 180 | /* Initialize GART (initialize after TTM so we can allocate | ||
| 181 | * memory through TTM but finalize after TTM) */ | ||
| 182 | if (rdev->flags & RADEON_IS_PCIE) { | ||
| 183 | r = rv370_pcie_gart_enable(rdev); | ||
| 184 | if (r) | ||
| 185 | return r; | ||
| 186 | } | ||
| 187 | /* Enable IRQ */ | ||
| 188 | rdev->irq.sw_int = true; | ||
| 189 | r100_irq_set(rdev); | ||
| 190 | /* 1M ring buffer */ | ||
| 191 | r = r100_cp_init(rdev, 1024 * 1024); | ||
| 192 | if (r) { | ||
| 193 | dev_err(rdev->dev, "failled initializing CP (%d).\n", r); | ||
| 194 | return r; | ||
| 195 | } | ||
| 196 | r = r100_wb_init(rdev); | ||
| 197 | if (r) | ||
| 198 | dev_err(rdev->dev, "failled initializing WB (%d).\n", r); | ||
| 199 | r = r100_ib_init(rdev); | ||
| 200 | if (r) { | ||
| 201 | dev_err(rdev->dev, "failled initializing IB (%d).\n", r); | ||
| 202 | return r; | ||
| 203 | } | ||
| 204 | return 0; | ||
| 205 | } | ||
| 206 | |||
| 207 | int r520_resume(struct radeon_device *rdev) | ||
| 237 | { | 208 | { |
| 238 | rv515_bandwidth_avivo_update(rdev); | 209 | /* Make sur GART are not working */ |
| 210 | if (rdev->flags & RADEON_IS_PCIE) | ||
| 211 | rv370_pcie_gart_disable(rdev); | ||
| 212 | /* Resume clock before doing reset */ | ||
| 213 | rv515_clock_startup(rdev); | ||
| 214 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | ||
| 215 | if (radeon_gpu_reset(rdev)) { | ||
| 216 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | ||
| 217 | RREG32(R_000E40_RBBM_STATUS), | ||
| 218 | RREG32(R_0007C0_CP_STAT)); | ||
| 219 | } | ||
| 220 | /* post */ | ||
| 221 | atom_asic_init(rdev->mode_info.atom_context); | ||
| 222 | /* Resume clock after posting */ | ||
| 223 | rv515_clock_startup(rdev); | ||
| 224 | return r520_startup(rdev); | ||
| 225 | } | ||
| 226 | |||
| 227 | int r520_init(struct radeon_device *rdev) | ||
| 228 | { | ||
| 229 | int r; | ||
| 230 | |||
| 231 | rdev->new_init_path = true; | ||
| 232 | /* Initialize scratch registers */ | ||
| 233 | radeon_scratch_init(rdev); | ||
| 234 | /* Initialize surface registers */ | ||
| 235 | radeon_surface_init(rdev); | ||
| 236 | /* TODO: disable VGA need to use VGA request */ | ||
| 237 | /* BIOS*/ | ||
| 238 | if (!radeon_get_bios(rdev)) { | ||
| 239 | if (ASIC_IS_AVIVO(rdev)) | ||
| 240 | return -EINVAL; | ||
| 241 | } | ||
| 242 | if (rdev->is_atom_bios) { | ||
| 243 | r = radeon_atombios_init(rdev); | ||
| 244 | if (r) | ||
| 245 | return r; | ||
| 246 | } else { | ||
| 247 | dev_err(rdev->dev, "Expecting atombios for RV515 GPU\n"); | ||
| 248 | return -EINVAL; | ||
| 249 | } | ||
| 250 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | ||
| 251 | if (radeon_gpu_reset(rdev)) { | ||
| 252 | dev_warn(rdev->dev, | ||
| 253 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | ||
| 254 | RREG32(R_000E40_RBBM_STATUS), | ||
| 255 | RREG32(R_0007C0_CP_STAT)); | ||
| 256 | } | ||
| 257 | /* check if cards are posted or not */ | ||
| 258 | if (!radeon_card_posted(rdev) && rdev->bios) { | ||
| 259 | DRM_INFO("GPU not posted. posting now...\n"); | ||
| 260 | atom_asic_init(rdev->mode_info.atom_context); | ||
| 261 | } | ||
| 262 | /* Initialize clocks */ | ||
| 263 | radeon_get_clock_info(rdev->ddev); | ||
| 264 | /* Get vram informations */ | ||
| 265 | r520_vram_info(rdev); | ||
| 266 | /* Initialize memory controller (also test AGP) */ | ||
| 267 | r = r420_mc_init(rdev); | ||
| 268 | if (r) | ||
| 269 | return r; | ||
| 270 | rv515_debugfs(rdev); | ||
| 271 | /* Fence driver */ | ||
| 272 | r = radeon_fence_driver_init(rdev); | ||
| 273 | if (r) | ||
| 274 | return r; | ||
| 275 | r = radeon_irq_kms_init(rdev); | ||
| 276 | if (r) | ||
| 277 | return r; | ||
| 278 | /* Memory manager */ | ||
| 279 | r = radeon_object_init(rdev); | ||
| 280 | if (r) | ||
| 281 | return r; | ||
| 282 | r = rv370_pcie_gart_init(rdev); | ||
| 283 | if (r) | ||
| 284 | return r; | ||
| 285 | rv515_set_safe_registers(rdev); | ||
| 286 | rdev->accel_working = true; | ||
| 287 | r = r520_startup(rdev); | ||
| 288 | if (r) { | ||
| 289 | /* Somethings want wront with the accel init stop accel */ | ||
| 290 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | ||
| 291 | rv515_suspend(rdev); | ||
| 292 | r100_cp_fini(rdev); | ||
| 293 | r100_wb_fini(rdev); | ||
| 294 | r100_ib_fini(rdev); | ||
| 295 | rv370_pcie_gart_fini(rdev); | ||
| 296 | radeon_agp_fini(rdev); | ||
| 297 | radeon_irq_kms_fini(rdev); | ||
| 298 | rdev->accel_working = false; | ||
| 299 | } | ||
| 300 | return 0; | ||
| 239 | } | 301 | } |
diff --git a/drivers/gpu/drm/radeon/r520d.h b/drivers/gpu/drm/radeon/r520d.h new file mode 100644 index 000000000000..61af61f644bc --- /dev/null +++ b/drivers/gpu/drm/radeon/r520d.h | |||
| @@ -0,0 +1,187 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2008 Advanced Micro Devices, Inc. | ||
| 3 | * Copyright 2008 Red Hat Inc. | ||
| 4 | * Copyright 2009 Jerome Glisse. | ||
| 5 | * | ||
| 6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 7 | * copy of this software and associated documentation files (the "Software"), | ||
| 8 | * to deal in the Software without restriction, including without limitation | ||
| 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 10 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 11 | * Software is furnished to do so, subject to the following conditions: | ||
| 12 | * | ||
| 13 | * The above copyright notice and this permission notice shall be included in | ||
| 14 | * all copies or substantial portions of the Software. | ||
| 15 | * | ||
| 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 19 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 22 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 23 | * | ||
| 24 | * Authors: Dave Airlie | ||
| 25 | * Alex Deucher | ||
| 26 | * Jerome Glisse | ||
| 27 | */ | ||
| 28 | #ifndef __R520D_H__ | ||
| 29 | #define __R520D_H__ | ||
| 30 | |||
| 31 | /* Registers */ | ||
| 32 | #define R_0000F8_CONFIG_MEMSIZE 0x0000F8 | ||
| 33 | #define S_0000F8_CONFIG_MEMSIZE(x) (((x) & 0xFFFFFFFF) << 0) | ||
| 34 | #define G_0000F8_CONFIG_MEMSIZE(x) (((x) >> 0) & 0xFFFFFFFF) | ||
| 35 | #define C_0000F8_CONFIG_MEMSIZE 0x00000000 | ||
| 36 | #define R_000134_HDP_FB_LOCATION 0x000134 | ||
| 37 | #define S_000134_HDP_FB_START(x) (((x) & 0xFFFF) << 0) | ||
| 38 | #define G_000134_HDP_FB_START(x) (((x) >> 0) & 0xFFFF) | ||
| 39 | #define C_000134_HDP_FB_START 0xFFFF0000 | ||
| 40 | #define R_0007C0_CP_STAT 0x0007C0 | ||
| 41 | #define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0) | ||
| 42 | #define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1) | ||
| 43 | #define C_0007C0_MRU_BUSY 0xFFFFFFFE | ||
| 44 | #define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1) | ||
| 45 | #define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1) | ||
| 46 | #define C_0007C0_MWU_BUSY 0xFFFFFFFD | ||
| 47 | #define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2) | ||
| 48 | #define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1) | ||
| 49 | #define C_0007C0_RSIU_BUSY 0xFFFFFFFB | ||
| 50 | #define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3) | ||
| 51 | #define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1) | ||
| 52 | #define C_0007C0_RCIU_BUSY 0xFFFFFFF7 | ||
| 53 | #define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9) | ||
| 54 | #define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1) | ||
| 55 | #define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF | ||
| 56 | #define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10) | ||
| 57 | #define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1) | ||
| 58 | #define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF | ||
| 59 | #define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11) | ||
| 60 | #define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1) | ||
| 61 | #define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF | ||
| 62 | #define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12) | ||
| 63 | #define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1) | ||
| 64 | #define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF | ||
| 65 | #define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13) | ||
| 66 | #define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1) | ||
| 67 | #define C_0007C0_CSI_BUSY 0xFFFFDFFF | ||
| 68 | #define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14) | ||
| 69 | #define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1) | ||
| 70 | #define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF | ||
| 71 | #define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15) | ||
| 72 | #define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1) | ||
| 73 | #define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF | ||
| 74 | #define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28) | ||
| 75 | #define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1) | ||
| 76 | #define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF | ||
| 77 | #define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29) | ||
| 78 | #define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1) | ||
| 79 | #define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF | ||
| 80 | #define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30) | ||
| 81 | #define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1) | ||
| 82 | #define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF | ||
| 83 | #define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31) | ||
| 84 | #define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1) | ||
| 85 | #define C_0007C0_CP_BUSY 0x7FFFFFFF | ||
| 86 | #define R_000E40_RBBM_STATUS 0x000E40 | ||
| 87 | #define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0) | ||
| 88 | #define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F) | ||
| 89 | #define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80 | ||
| 90 | #define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8) | ||
| 91 | #define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1) | ||
| 92 | #define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF | ||
| 93 | #define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9) | ||
| 94 | #define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1) | ||
| 95 | #define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF | ||
| 96 | #define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10) | ||
| 97 | #define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1) | ||
| 98 | #define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF | ||
| 99 | #define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11) | ||
| 100 | #define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1) | ||
| 101 | #define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF | ||
| 102 | #define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12) | ||
| 103 | #define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1) | ||
| 104 | #define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF | ||
| 105 | #define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13) | ||
| 106 | #define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1) | ||
| 107 | #define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF | ||
| 108 | #define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14) | ||
| 109 | #define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1) | ||
| 110 | #define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF | ||
| 111 | #define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15) | ||
| 112 | #define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1) | ||
| 113 | #define C_000E40_ENG_EV_BUSY 0xFFFF7FFF | ||
| 114 | #define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16) | ||
| 115 | #define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1) | ||
| 116 | #define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF | ||
| 117 | #define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17) | ||
| 118 | #define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1) | ||
| 119 | #define C_000E40_E2_BUSY 0xFFFDFFFF | ||
| 120 | #define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18) | ||
| 121 | #define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1) | ||
| 122 | #define C_000E40_RB2D_BUSY 0xFFFBFFFF | ||
| 123 | #define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19) | ||
| 124 | #define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1) | ||
| 125 | #define C_000E40_RB3D_BUSY 0xFFF7FFFF | ||
| 126 | #define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20) | ||
| 127 | #define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1) | ||
| 128 | #define C_000E40_VAP_BUSY 0xFFEFFFFF | ||
| 129 | #define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21) | ||
| 130 | #define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1) | ||
| 131 | #define C_000E40_RE_BUSY 0xFFDFFFFF | ||
| 132 | #define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22) | ||
| 133 | #define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1) | ||
| 134 | #define C_000E40_TAM_BUSY 0xFFBFFFFF | ||
| 135 | #define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23) | ||
| 136 | #define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1) | ||
| 137 | #define C_000E40_TDM_BUSY 0xFF7FFFFF | ||
| 138 | #define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24) | ||
| 139 | #define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1) | ||
| 140 | #define C_000E40_PB_BUSY 0xFEFFFFFF | ||
| 141 | #define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25) | ||
| 142 | #define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1) | ||
| 143 | #define C_000E40_TIM_BUSY 0xFDFFFFFF | ||
| 144 | #define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26) | ||
| 145 | #define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1) | ||
| 146 | #define C_000E40_GA_BUSY 0xFBFFFFFF | ||
| 147 | #define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27) | ||
| 148 | #define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1) | ||
| 149 | #define C_000E40_CBA2D_BUSY 0xF7FFFFFF | ||
| 150 | #define S_000E40_RBBM_HIBUSY(x) (((x) & 0x1) << 28) | ||
| 151 | #define G_000E40_RBBM_HIBUSY(x) (((x) >> 28) & 0x1) | ||
| 152 | #define C_000E40_RBBM_HIBUSY 0xEFFFFFFF | ||
| 153 | #define S_000E40_SKID_CFBUSY(x) (((x) & 0x1) << 29) | ||
| 154 | #define G_000E40_SKID_CFBUSY(x) (((x) >> 29) & 0x1) | ||
| 155 | #define C_000E40_SKID_CFBUSY 0xDFFFFFFF | ||
| 156 | #define S_000E40_VAP_VF_BUSY(x) (((x) & 0x1) << 30) | ||
| 157 | #define G_000E40_VAP_VF_BUSY(x) (((x) >> 30) & 0x1) | ||
| 158 | #define C_000E40_VAP_VF_BUSY 0xBFFFFFFF | ||
| 159 | #define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31) | ||
| 160 | #define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1) | ||
| 161 | #define C_000E40_GUI_ACTIVE 0x7FFFFFFF | ||
| 162 | |||
| 163 | |||
| 164 | #define R_000004_MC_FB_LOCATION 0x000004 | ||
| 165 | #define S_000004_MC_FB_START(x) (((x) & 0xFFFF) << 0) | ||
| 166 | #define G_000004_MC_FB_START(x) (((x) >> 0) & 0xFFFF) | ||
| 167 | #define C_000004_MC_FB_START 0xFFFF0000 | ||
| 168 | #define S_000004_MC_FB_TOP(x) (((x) & 0xFFFF) << 16) | ||
| 169 | #define G_000004_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF) | ||
| 170 | #define C_000004_MC_FB_TOP 0x0000FFFF | ||
| 171 | #define R_000005_MC_AGP_LOCATION 0x000005 | ||
| 172 | #define S_000005_MC_AGP_START(x) (((x) & 0xFFFF) << 0) | ||
| 173 | #define G_000005_MC_AGP_START(x) (((x) >> 0) & 0xFFFF) | ||
| 174 | #define C_000005_MC_AGP_START 0xFFFF0000 | ||
| 175 | #define S_000005_MC_AGP_TOP(x) (((x) & 0xFFFF) << 16) | ||
| 176 | #define G_000005_MC_AGP_TOP(x) (((x) >> 16) & 0xFFFF) | ||
| 177 | #define C_000005_MC_AGP_TOP 0x0000FFFF | ||
| 178 | #define R_000006_AGP_BASE 0x000006 | ||
| 179 | #define S_000006_AGP_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0) | ||
| 180 | #define G_000006_AGP_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF) | ||
| 181 | #define C_000006_AGP_BASE_ADDR 0x00000000 | ||
| 182 | #define R_000007_AGP_BASE_2 0x000007 | ||
| 183 | #define S_000007_AGP_BASE_ADDR_2(x) (((x) & 0xF) << 0) | ||
| 184 | #define G_000007_AGP_BASE_ADDR_2(x) (((x) >> 0) & 0xF) | ||
| 185 | #define C_000007_AGP_BASE_ADDR_2 0xFFFFFFF0 | ||
| 186 | |||
| 187 | #endif | ||
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index eab31c1d6df1..2e4e60edbff4 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -33,8 +33,8 @@ | |||
| 33 | #include "radeon.h" | 33 | #include "radeon.h" |
| 34 | #include "radeon_mode.h" | 34 | #include "radeon_mode.h" |
| 35 | #include "r600d.h" | 35 | #include "r600d.h" |
| 36 | #include "avivod.h" | ||
| 37 | #include "atom.h" | 36 | #include "atom.h" |
| 37 | #include "avivod.h" | ||
| 38 | 38 | ||
| 39 | #define PFP_UCODE_SIZE 576 | 39 | #define PFP_UCODE_SIZE 576 |
| 40 | #define PM4_UCODE_SIZE 1792 | 40 | #define PM4_UCODE_SIZE 1792 |
| @@ -342,7 +342,7 @@ static void r600_mc_resume(struct radeon_device *rdev) | |||
| 342 | 342 | ||
| 343 | /* we need to own VRAM, so turn off the VGA renderer here | 343 | /* we need to own VRAM, so turn off the VGA renderer here |
| 344 | * to stop it overwriting our objects */ | 344 | * to stop it overwriting our objects */ |
| 345 | radeon_avivo_vga_render_disable(rdev); | 345 | rv515_vga_render_disable(rdev); |
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | int r600_mc_init(struct radeon_device *rdev) | 348 | int r600_mc_init(struct radeon_device *rdev) |
| @@ -380,6 +380,13 @@ int r600_mc_init(struct radeon_device *rdev) | |||
| 380 | /* Setup GPU memory space */ | 380 | /* Setup GPU memory space */ |
| 381 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); | 381 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); |
| 382 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | 382 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); |
| 383 | |||
| 384 | if (rdev->mc.mc_vram_size > rdev->mc.aper_size) | ||
| 385 | rdev->mc.mc_vram_size = rdev->mc.aper_size; | ||
| 386 | |||
| 387 | if (rdev->mc.real_vram_size > rdev->mc.aper_size) | ||
| 388 | rdev->mc.real_vram_size = rdev->mc.aper_size; | ||
| 389 | |||
| 383 | if (rdev->flags & RADEON_IS_AGP) { | 390 | if (rdev->flags & RADEON_IS_AGP) { |
| 384 | r = radeon_agp_init(rdev); | 391 | r = radeon_agp_init(rdev); |
| 385 | if (r) | 392 | if (r) |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 33b89cd8743e..d28970db6a2d 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
| @@ -28,7 +28,6 @@ | |||
| 28 | #include "drmP.h" | 28 | #include "drmP.h" |
| 29 | #include "radeon.h" | 29 | #include "radeon.h" |
| 30 | #include "r600d.h" | 30 | #include "r600d.h" |
| 31 | #include "avivod.h" | ||
| 32 | 31 | ||
| 33 | static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p, | 32 | static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p, |
| 34 | struct radeon_cs_reloc **cs_reloc); | 33 | struct radeon_cs_reloc **cs_reloc); |
| @@ -57,7 +56,7 @@ int r600_cs_packet_parse(struct radeon_cs_parser *p, | |||
| 57 | idx, ib_chunk->length_dw); | 56 | idx, ib_chunk->length_dw); |
| 58 | return -EINVAL; | 57 | return -EINVAL; |
| 59 | } | 58 | } |
| 60 | header = ib_chunk->kdata[idx]; | 59 | header = radeon_get_ib_value(p, idx); |
| 61 | pkt->idx = idx; | 60 | pkt->idx = idx; |
| 62 | pkt->type = CP_PACKET_GET_TYPE(header); | 61 | pkt->type = CP_PACKET_GET_TYPE(header); |
| 63 | pkt->count = CP_PACKET_GET_COUNT(header); | 62 | pkt->count = CP_PACKET_GET_COUNT(header); |
| @@ -98,7 +97,6 @@ int r600_cs_packet_parse(struct radeon_cs_parser *p, | |||
| 98 | static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p, | 97 | static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p, |
| 99 | struct radeon_cs_reloc **cs_reloc) | 98 | struct radeon_cs_reloc **cs_reloc) |
| 100 | { | 99 | { |
| 101 | struct radeon_cs_chunk *ib_chunk; | ||
| 102 | struct radeon_cs_chunk *relocs_chunk; | 100 | struct radeon_cs_chunk *relocs_chunk; |
| 103 | struct radeon_cs_packet p3reloc; | 101 | struct radeon_cs_packet p3reloc; |
| 104 | unsigned idx; | 102 | unsigned idx; |
| @@ -109,7 +107,6 @@ static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p, | |||
| 109 | return -EINVAL; | 107 | return -EINVAL; |
| 110 | } | 108 | } |
| 111 | *cs_reloc = NULL; | 109 | *cs_reloc = NULL; |
| 112 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
| 113 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; | 110 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; |
| 114 | r = r600_cs_packet_parse(p, &p3reloc, p->idx); | 111 | r = r600_cs_packet_parse(p, &p3reloc, p->idx); |
| 115 | if (r) { | 112 | if (r) { |
| @@ -121,7 +118,7 @@ static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p, | |||
| 121 | p3reloc.idx); | 118 | p3reloc.idx); |
| 122 | return -EINVAL; | 119 | return -EINVAL; |
| 123 | } | 120 | } |
| 124 | idx = ib_chunk->kdata[p3reloc.idx + 1]; | 121 | idx = radeon_get_ib_value(p, p3reloc.idx + 1); |
| 125 | if (idx >= relocs_chunk->length_dw) { | 122 | if (idx >= relocs_chunk->length_dw) { |
| 126 | DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", | 123 | DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", |
| 127 | idx, relocs_chunk->length_dw); | 124 | idx, relocs_chunk->length_dw); |
| @@ -146,7 +143,6 @@ static int r600_cs_packet_next_reloc_mm(struct radeon_cs_parser *p, | |||
| 146 | static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, | 143 | static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, |
| 147 | struct radeon_cs_reloc **cs_reloc) | 144 | struct radeon_cs_reloc **cs_reloc) |
| 148 | { | 145 | { |
| 149 | struct radeon_cs_chunk *ib_chunk; | ||
| 150 | struct radeon_cs_chunk *relocs_chunk; | 146 | struct radeon_cs_chunk *relocs_chunk; |
| 151 | struct radeon_cs_packet p3reloc; | 147 | struct radeon_cs_packet p3reloc; |
| 152 | unsigned idx; | 148 | unsigned idx; |
| @@ -157,7 +153,6 @@ static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, | |||
| 157 | return -EINVAL; | 153 | return -EINVAL; |
| 158 | } | 154 | } |
| 159 | *cs_reloc = NULL; | 155 | *cs_reloc = NULL; |
| 160 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
| 161 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; | 156 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; |
| 162 | r = r600_cs_packet_parse(p, &p3reloc, p->idx); | 157 | r = r600_cs_packet_parse(p, &p3reloc, p->idx); |
| 163 | if (r) { | 158 | if (r) { |
| @@ -169,7 +164,7 @@ static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, | |||
| 169 | p3reloc.idx); | 164 | p3reloc.idx); |
| 170 | return -EINVAL; | 165 | return -EINVAL; |
| 171 | } | 166 | } |
| 172 | idx = ib_chunk->kdata[p3reloc.idx + 1]; | 167 | idx = radeon_get_ib_value(p, p3reloc.idx + 1); |
| 173 | if (idx >= relocs_chunk->length_dw) { | 168 | if (idx >= relocs_chunk->length_dw) { |
| 174 | DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", | 169 | DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", |
| 175 | idx, relocs_chunk->length_dw); | 170 | idx, relocs_chunk->length_dw); |
| @@ -181,13 +176,136 @@ static int r600_cs_packet_next_reloc_nomm(struct radeon_cs_parser *p, | |||
| 181 | return 0; | 176 | return 0; |
| 182 | } | 177 | } |
| 183 | 178 | ||
| 179 | /** | ||
| 180 | * r600_cs_packet_next_vline() - parse userspace VLINE packet | ||
| 181 | * @parser: parser structure holding parsing context. | ||
| 182 | * | ||
| 183 | * Userspace sends a special sequence for VLINE waits. | ||
| 184 | * PACKET0 - VLINE_START_END + value | ||
| 185 | * PACKET3 - WAIT_REG_MEM poll vline status reg | ||
| 186 | * RELOC (P3) - crtc_id in reloc. | ||
| 187 | * | ||
| 188 | * This function parses this and relocates the VLINE START END | ||
| 189 | * and WAIT_REG_MEM packets to the correct crtc. | ||
| 190 | * It also detects a switched off crtc and nulls out the | ||
| 191 | * wait in that case. | ||
| 192 | */ | ||
| 193 | static int r600_cs_packet_parse_vline(struct radeon_cs_parser *p) | ||
| 194 | { | ||
| 195 | struct drm_mode_object *obj; | ||
| 196 | struct drm_crtc *crtc; | ||
| 197 | struct radeon_crtc *radeon_crtc; | ||
| 198 | struct radeon_cs_packet p3reloc, wait_reg_mem; | ||
| 199 | int crtc_id; | ||
| 200 | int r; | ||
| 201 | uint32_t header, h_idx, reg, wait_reg_mem_info; | ||
| 202 | volatile uint32_t *ib; | ||
| 203 | |||
| 204 | ib = p->ib->ptr; | ||
| 205 | |||
| 206 | /* parse the WAIT_REG_MEM */ | ||
| 207 | r = r600_cs_packet_parse(p, &wait_reg_mem, p->idx); | ||
| 208 | if (r) | ||
| 209 | return r; | ||
| 210 | |||
| 211 | /* check its a WAIT_REG_MEM */ | ||
| 212 | if (wait_reg_mem.type != PACKET_TYPE3 || | ||
| 213 | wait_reg_mem.opcode != PACKET3_WAIT_REG_MEM) { | ||
| 214 | DRM_ERROR("vline wait missing WAIT_REG_MEM segment\n"); | ||
| 215 | r = -EINVAL; | ||
| 216 | return r; | ||
| 217 | } | ||
| 218 | |||
| 219 | wait_reg_mem_info = radeon_get_ib_value(p, wait_reg_mem.idx + 1); | ||
| 220 | /* bit 4 is reg (0) or mem (1) */ | ||
| 221 | if (wait_reg_mem_info & 0x10) { | ||
| 222 | DRM_ERROR("vline WAIT_REG_MEM waiting on MEM rather than REG\n"); | ||
| 223 | r = -EINVAL; | ||
| 224 | return r; | ||
| 225 | } | ||
| 226 | /* waiting for value to be equal */ | ||
| 227 | if ((wait_reg_mem_info & 0x7) != 0x3) { | ||
| 228 | DRM_ERROR("vline WAIT_REG_MEM function not equal\n"); | ||
| 229 | r = -EINVAL; | ||
| 230 | return r; | ||
| 231 | } | ||
| 232 | if ((radeon_get_ib_value(p, wait_reg_mem.idx + 2) << 2) != AVIVO_D1MODE_VLINE_STATUS) { | ||
| 233 | DRM_ERROR("vline WAIT_REG_MEM bad reg\n"); | ||
| 234 | r = -EINVAL; | ||
| 235 | return r; | ||
| 236 | } | ||
| 237 | |||
| 238 | if (radeon_get_ib_value(p, wait_reg_mem.idx + 5) != AVIVO_D1MODE_VLINE_STAT) { | ||
| 239 | DRM_ERROR("vline WAIT_REG_MEM bad bit mask\n"); | ||
| 240 | r = -EINVAL; | ||
| 241 | return r; | ||
| 242 | } | ||
| 243 | |||
| 244 | /* jump over the NOP */ | ||
| 245 | r = r600_cs_packet_parse(p, &p3reloc, p->idx + wait_reg_mem.count + 2); | ||
| 246 | if (r) | ||
| 247 | return r; | ||
| 248 | |||
| 249 | h_idx = p->idx - 2; | ||
| 250 | p->idx += wait_reg_mem.count + 2; | ||
| 251 | p->idx += p3reloc.count + 2; | ||
| 252 | |||
| 253 | header = radeon_get_ib_value(p, h_idx); | ||
| 254 | crtc_id = radeon_get_ib_value(p, h_idx + 2 + 7 + 1); | ||
| 255 | reg = header >> 2; | ||
| 256 | mutex_lock(&p->rdev->ddev->mode_config.mutex); | ||
| 257 | obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); | ||
| 258 | if (!obj) { | ||
| 259 | DRM_ERROR("cannot find crtc %d\n", crtc_id); | ||
| 260 | r = -EINVAL; | ||
| 261 | goto out; | ||
| 262 | } | ||
| 263 | crtc = obj_to_crtc(obj); | ||
| 264 | radeon_crtc = to_radeon_crtc(crtc); | ||
| 265 | crtc_id = radeon_crtc->crtc_id; | ||
| 266 | |||
| 267 | if (!crtc->enabled) { | ||
| 268 | /* if the CRTC isn't enabled - we need to nop out the WAIT_REG_MEM */ | ||
| 269 | ib[h_idx + 2] = PACKET2(0); | ||
| 270 | ib[h_idx + 3] = PACKET2(0); | ||
| 271 | ib[h_idx + 4] = PACKET2(0); | ||
| 272 | ib[h_idx + 5] = PACKET2(0); | ||
| 273 | ib[h_idx + 6] = PACKET2(0); | ||
| 274 | ib[h_idx + 7] = PACKET2(0); | ||
| 275 | ib[h_idx + 8] = PACKET2(0); | ||
| 276 | } else if (crtc_id == 1) { | ||
| 277 | switch (reg) { | ||
| 278 | case AVIVO_D1MODE_VLINE_START_END: | ||
| 279 | header &= ~R600_CP_PACKET0_REG_MASK; | ||
| 280 | header |= AVIVO_D2MODE_VLINE_START_END >> 2; | ||
| 281 | break; | ||
| 282 | default: | ||
| 283 | DRM_ERROR("unknown crtc reloc\n"); | ||
| 284 | r = -EINVAL; | ||
| 285 | goto out; | ||
| 286 | } | ||
| 287 | ib[h_idx] = header; | ||
| 288 | ib[h_idx + 4] = AVIVO_D2MODE_VLINE_STATUS >> 2; | ||
| 289 | } | ||
| 290 | out: | ||
| 291 | mutex_unlock(&p->rdev->ddev->mode_config.mutex); | ||
| 292 | return r; | ||
| 293 | } | ||
| 294 | |||
| 184 | static int r600_packet0_check(struct radeon_cs_parser *p, | 295 | static int r600_packet0_check(struct radeon_cs_parser *p, |
| 185 | struct radeon_cs_packet *pkt, | 296 | struct radeon_cs_packet *pkt, |
| 186 | unsigned idx, unsigned reg) | 297 | unsigned idx, unsigned reg) |
| 187 | { | 298 | { |
| 299 | int r; | ||
| 300 | |||
| 188 | switch (reg) { | 301 | switch (reg) { |
| 189 | case AVIVO_D1MODE_VLINE_START_END: | 302 | case AVIVO_D1MODE_VLINE_START_END: |
| 190 | case AVIVO_D2MODE_VLINE_START_END: | 303 | r = r600_cs_packet_parse_vline(p); |
| 304 | if (r) { | ||
| 305 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", | ||
| 306 | idx, reg); | ||
| 307 | return r; | ||
| 308 | } | ||
| 191 | break; | 309 | break; |
| 192 | default: | 310 | default: |
| 193 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", | 311 | 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, | |||
| 218 | static int r600_packet3_check(struct radeon_cs_parser *p, | 336 | static int r600_packet3_check(struct radeon_cs_parser *p, |
| 219 | struct radeon_cs_packet *pkt) | 337 | struct radeon_cs_packet *pkt) |
| 220 | { | 338 | { |
| 221 | struct radeon_cs_chunk *ib_chunk; | ||
| 222 | struct radeon_cs_reloc *reloc; | 339 | struct radeon_cs_reloc *reloc; |
| 223 | volatile u32 *ib; | 340 | volatile u32 *ib; |
| 224 | unsigned idx; | 341 | unsigned idx; |
| 225 | unsigned i; | 342 | unsigned i; |
| 226 | unsigned start_reg, end_reg, reg; | 343 | unsigned start_reg, end_reg, reg; |
| 227 | int r; | 344 | int r; |
| 345 | u32 idx_value; | ||
| 228 | 346 | ||
| 229 | ib = p->ib->ptr; | 347 | ib = p->ib->ptr; |
| 230 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
| 231 | idx = pkt->idx + 1; | 348 | idx = pkt->idx + 1; |
| 349 | idx_value = radeon_get_ib_value(p, idx); | ||
| 350 | |||
| 232 | switch (pkt->opcode) { | 351 | switch (pkt->opcode) { |
| 233 | case PACKET3_START_3D_CMDBUF: | 352 | case PACKET3_START_3D_CMDBUF: |
| 234 | if (p->family >= CHIP_RV770 || pkt->count) { | 353 | if (p->family >= CHIP_RV770 || pkt->count) { |
| @@ -259,8 +378,8 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 259 | DRM_ERROR("bad DRAW_INDEX\n"); | 378 | DRM_ERROR("bad DRAW_INDEX\n"); |
| 260 | return -EINVAL; | 379 | return -EINVAL; |
| 261 | } | 380 | } |
| 262 | ib[idx+0] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); | 381 | ib[idx+0] = idx_value + (u32)(reloc->lobj.gpu_offset & 0xffffffff); |
| 263 | ib[idx+1] = upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | 382 | ib[idx+1] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; |
| 264 | break; | 383 | break; |
| 265 | case PACKET3_DRAW_INDEX_AUTO: | 384 | case PACKET3_DRAW_INDEX_AUTO: |
| 266 | if (pkt->count != 1) { | 385 | if (pkt->count != 1) { |
| @@ -281,14 +400,14 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 281 | return -EINVAL; | 400 | return -EINVAL; |
| 282 | } | 401 | } |
| 283 | /* bit 4 is reg (0) or mem (1) */ | 402 | /* bit 4 is reg (0) or mem (1) */ |
| 284 | if (ib_chunk->kdata[idx+0] & 0x10) { | 403 | if (idx_value & 0x10) { |
| 285 | r = r600_cs_packet_next_reloc(p, &reloc); | 404 | r = r600_cs_packet_next_reloc(p, &reloc); |
| 286 | if (r) { | 405 | if (r) { |
| 287 | DRM_ERROR("bad WAIT_REG_MEM\n"); | 406 | DRM_ERROR("bad WAIT_REG_MEM\n"); |
| 288 | return -EINVAL; | 407 | return -EINVAL; |
| 289 | } | 408 | } |
| 290 | ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); | 409 | ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); |
| 291 | ib[idx+2] = upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | 410 | ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; |
| 292 | } | 411 | } |
| 293 | break; | 412 | break; |
| 294 | case PACKET3_SURFACE_SYNC: | 413 | case PACKET3_SURFACE_SYNC: |
| @@ -297,8 +416,8 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 297 | return -EINVAL; | 416 | return -EINVAL; |
| 298 | } | 417 | } |
| 299 | /* 0xffffffff/0x0 is flush all cache flag */ | 418 | /* 0xffffffff/0x0 is flush all cache flag */ |
| 300 | if (ib_chunk->kdata[idx+1] != 0xffffffff || | 419 | if (radeon_get_ib_value(p, idx + 1) != 0xffffffff || |
| 301 | ib_chunk->kdata[idx+2] != 0) { | 420 | radeon_get_ib_value(p, idx + 2) != 0) { |
| 302 | r = r600_cs_packet_next_reloc(p, &reloc); | 421 | r = r600_cs_packet_next_reloc(p, &reloc); |
| 303 | if (r) { | 422 | if (r) { |
| 304 | DRM_ERROR("bad SURFACE_SYNC\n"); | 423 | DRM_ERROR("bad SURFACE_SYNC\n"); |
| @@ -319,7 +438,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 319 | return -EINVAL; | 438 | return -EINVAL; |
| 320 | } | 439 | } |
| 321 | ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); | 440 | ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); |
| 322 | ib[idx+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | 441 | ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; |
| 323 | } | 442 | } |
| 324 | break; | 443 | break; |
| 325 | case PACKET3_EVENT_WRITE_EOP: | 444 | case PACKET3_EVENT_WRITE_EOP: |
| @@ -333,10 +452,10 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 333 | return -EINVAL; | 452 | return -EINVAL; |
| 334 | } | 453 | } |
| 335 | ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); | 454 | ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); |
| 336 | ib[idx+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | 455 | ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; |
| 337 | break; | 456 | break; |
| 338 | case PACKET3_SET_CONFIG_REG: | 457 | case PACKET3_SET_CONFIG_REG: |
| 339 | start_reg = (ib[idx+0] << 2) + PACKET3_SET_CONFIG_REG_OFFSET; | 458 | start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_OFFSET; |
| 340 | end_reg = 4 * pkt->count + start_reg - 4; | 459 | end_reg = 4 * pkt->count + start_reg - 4; |
| 341 | if ((start_reg < PACKET3_SET_CONFIG_REG_OFFSET) || | 460 | if ((start_reg < PACKET3_SET_CONFIG_REG_OFFSET) || |
| 342 | (start_reg >= PACKET3_SET_CONFIG_REG_END) || | 461 | (start_reg >= PACKET3_SET_CONFIG_REG_END) || |
| @@ -356,7 +475,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 356 | } | 475 | } |
| 357 | break; | 476 | break; |
| 358 | case PACKET3_SET_CONTEXT_REG: | 477 | case PACKET3_SET_CONTEXT_REG: |
| 359 | start_reg = (ib[idx+0] << 2) + PACKET3_SET_CONTEXT_REG_OFFSET; | 478 | start_reg = (idx_value << 2) + PACKET3_SET_CONTEXT_REG_OFFSET; |
| 360 | end_reg = 4 * pkt->count + start_reg - 4; | 479 | end_reg = 4 * pkt->count + start_reg - 4; |
| 361 | if ((start_reg < PACKET3_SET_CONTEXT_REG_OFFSET) || | 480 | if ((start_reg < PACKET3_SET_CONTEXT_REG_OFFSET) || |
| 362 | (start_reg >= PACKET3_SET_CONTEXT_REG_END) || | 481 | (start_reg >= PACKET3_SET_CONTEXT_REG_END) || |
| @@ -421,7 +540,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 421 | DRM_ERROR("bad SET_RESOURCE\n"); | 540 | DRM_ERROR("bad SET_RESOURCE\n"); |
| 422 | return -EINVAL; | 541 | return -EINVAL; |
| 423 | } | 542 | } |
| 424 | start_reg = (ib[idx+0] << 2) + PACKET3_SET_RESOURCE_OFFSET; | 543 | start_reg = (idx_value << 2) + PACKET3_SET_RESOURCE_OFFSET; |
| 425 | end_reg = 4 * pkt->count + start_reg - 4; | 544 | end_reg = 4 * pkt->count + start_reg - 4; |
| 426 | if ((start_reg < PACKET3_SET_RESOURCE_OFFSET) || | 545 | if ((start_reg < PACKET3_SET_RESOURCE_OFFSET) || |
| 427 | (start_reg >= PACKET3_SET_RESOURCE_END) || | 546 | (start_reg >= PACKET3_SET_RESOURCE_END) || |
| @@ -430,7 +549,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 430 | return -EINVAL; | 549 | return -EINVAL; |
| 431 | } | 550 | } |
| 432 | for (i = 0; i < (pkt->count / 7); i++) { | 551 | for (i = 0; i < (pkt->count / 7); i++) { |
| 433 | switch (G__SQ_VTX_CONSTANT_TYPE(ib[idx+(i*7)+6+1])) { | 552 | switch (G__SQ_VTX_CONSTANT_TYPE(radeon_get_ib_value(p, idx+(i*7)+6+1))) { |
| 434 | case SQ_TEX_VTX_VALID_TEXTURE: | 553 | case SQ_TEX_VTX_VALID_TEXTURE: |
| 435 | /* tex base */ | 554 | /* tex base */ |
| 436 | r = r600_cs_packet_next_reloc(p, &reloc); | 555 | r = r600_cs_packet_next_reloc(p, &reloc); |
| @@ -455,7 +574,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 455 | return -EINVAL; | 574 | return -EINVAL; |
| 456 | } | 575 | } |
| 457 | ib[idx+1+(i*7)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff); | 576 | ib[idx+1+(i*7)+0] += (u32)((reloc->lobj.gpu_offset) & 0xffffffff); |
| 458 | ib[idx+1+(i*7)+2] |= upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | 577 | ib[idx+1+(i*7)+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; |
| 459 | break; | 578 | break; |
| 460 | case SQ_TEX_VTX_INVALID_TEXTURE: | 579 | case SQ_TEX_VTX_INVALID_TEXTURE: |
| 461 | case SQ_TEX_VTX_INVALID_BUFFER: | 580 | case SQ_TEX_VTX_INVALID_BUFFER: |
| @@ -466,7 +585,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 466 | } | 585 | } |
| 467 | break; | 586 | break; |
| 468 | case PACKET3_SET_ALU_CONST: | 587 | case PACKET3_SET_ALU_CONST: |
| 469 | start_reg = (ib[idx+0] << 2) + PACKET3_SET_ALU_CONST_OFFSET; | 588 | start_reg = (idx_value << 2) + PACKET3_SET_ALU_CONST_OFFSET; |
| 470 | end_reg = 4 * pkt->count + start_reg - 4; | 589 | end_reg = 4 * pkt->count + start_reg - 4; |
| 471 | if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) || | 590 | if ((start_reg < PACKET3_SET_ALU_CONST_OFFSET) || |
| 472 | (start_reg >= PACKET3_SET_ALU_CONST_END) || | 591 | (start_reg >= PACKET3_SET_ALU_CONST_END) || |
| @@ -476,7 +595,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 476 | } | 595 | } |
| 477 | break; | 596 | break; |
| 478 | case PACKET3_SET_BOOL_CONST: | 597 | case PACKET3_SET_BOOL_CONST: |
| 479 | start_reg = (ib[idx+0] << 2) + PACKET3_SET_BOOL_CONST_OFFSET; | 598 | start_reg = (idx_value << 2) + PACKET3_SET_BOOL_CONST_OFFSET; |
| 480 | end_reg = 4 * pkt->count + start_reg - 4; | 599 | end_reg = 4 * pkt->count + start_reg - 4; |
| 481 | if ((start_reg < PACKET3_SET_BOOL_CONST_OFFSET) || | 600 | if ((start_reg < PACKET3_SET_BOOL_CONST_OFFSET) || |
| 482 | (start_reg >= PACKET3_SET_BOOL_CONST_END) || | 601 | (start_reg >= PACKET3_SET_BOOL_CONST_END) || |
| @@ -486,7 +605,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 486 | } | 605 | } |
| 487 | break; | 606 | break; |
| 488 | case PACKET3_SET_LOOP_CONST: | 607 | case PACKET3_SET_LOOP_CONST: |
| 489 | start_reg = (ib[idx+0] << 2) + PACKET3_SET_LOOP_CONST_OFFSET; | 608 | start_reg = (idx_value << 2) + PACKET3_SET_LOOP_CONST_OFFSET; |
| 490 | end_reg = 4 * pkt->count + start_reg - 4; | 609 | end_reg = 4 * pkt->count + start_reg - 4; |
| 491 | if ((start_reg < PACKET3_SET_LOOP_CONST_OFFSET) || | 610 | if ((start_reg < PACKET3_SET_LOOP_CONST_OFFSET) || |
| 492 | (start_reg >= PACKET3_SET_LOOP_CONST_END) || | 611 | (start_reg >= PACKET3_SET_LOOP_CONST_END) || |
| @@ -496,7 +615,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 496 | } | 615 | } |
| 497 | break; | 616 | break; |
| 498 | case PACKET3_SET_CTL_CONST: | 617 | case PACKET3_SET_CTL_CONST: |
| 499 | start_reg = (ib[idx+0] << 2) + PACKET3_SET_CTL_CONST_OFFSET; | 618 | start_reg = (idx_value << 2) + PACKET3_SET_CTL_CONST_OFFSET; |
| 500 | end_reg = 4 * pkt->count + start_reg - 4; | 619 | end_reg = 4 * pkt->count + start_reg - 4; |
| 501 | if ((start_reg < PACKET3_SET_CTL_CONST_OFFSET) || | 620 | if ((start_reg < PACKET3_SET_CTL_CONST_OFFSET) || |
| 502 | (start_reg >= PACKET3_SET_CTL_CONST_END) || | 621 | (start_reg >= PACKET3_SET_CTL_CONST_END) || |
| @@ -510,7 +629,7 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
| 510 | DRM_ERROR("bad SET_SAMPLER\n"); | 629 | DRM_ERROR("bad SET_SAMPLER\n"); |
| 511 | return -EINVAL; | 630 | return -EINVAL; |
| 512 | } | 631 | } |
| 513 | start_reg = (ib[idx+0] << 2) + PACKET3_SET_SAMPLER_OFFSET; | 632 | start_reg = (idx_value << 2) + PACKET3_SET_SAMPLER_OFFSET; |
| 514 | end_reg = 4 * pkt->count + start_reg - 4; | 633 | end_reg = 4 * pkt->count + start_reg - 4; |
| 515 | if ((start_reg < PACKET3_SET_SAMPLER_OFFSET) || | 634 | if ((start_reg < PACKET3_SET_SAMPLER_OFFSET) || |
| 516 | (start_reg >= PACKET3_SET_SAMPLER_END) || | 635 | (start_reg >= PACKET3_SET_SAMPLER_END) || |
| @@ -602,6 +721,8 @@ static void r600_cs_parser_fini(struct radeon_cs_parser *parser, int error) | |||
| 602 | kfree(parser->relocs); | 721 | kfree(parser->relocs); |
| 603 | for (i = 0; i < parser->nchunks; i++) { | 722 | for (i = 0; i < parser->nchunks; i++) { |
| 604 | kfree(parser->chunks[i].kdata); | 723 | kfree(parser->chunks[i].kdata); |
| 724 | kfree(parser->chunks[i].kpage[0]); | ||
| 725 | kfree(parser->chunks[i].kpage[1]); | ||
| 605 | } | 726 | } |
| 606 | kfree(parser->chunks); | 727 | kfree(parser->chunks); |
| 607 | kfree(parser->chunks_array); | 728 | kfree(parser->chunks_array); |
| @@ -639,7 +760,6 @@ int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp, | |||
| 639 | * uncached). */ | 760 | * uncached). */ |
| 640 | ib_chunk = &parser.chunks[parser.chunk_ib_idx]; | 761 | ib_chunk = &parser.chunks[parser.chunk_ib_idx]; |
| 641 | parser.ib->length_dw = ib_chunk->length_dw; | 762 | parser.ib->length_dw = ib_chunk->length_dw; |
| 642 | memcpy((void *)parser.ib->ptr, ib_chunk->kdata, ib_chunk->length_dw*4); | ||
| 643 | *l = parser.ib->length_dw; | 763 | *l = parser.ib->length_dw; |
| 644 | r = r600_cs_parse(&parser); | 764 | r = r600_cs_parse(&parser); |
| 645 | if (r) { | 765 | if (r) { |
| @@ -647,6 +767,12 @@ int r600_cs_legacy(struct drm_device *dev, void *data, struct drm_file *filp, | |||
| 647 | r600_cs_parser_fini(&parser, r); | 767 | r600_cs_parser_fini(&parser, r); |
| 648 | return r; | 768 | return r; |
| 649 | } | 769 | } |
| 770 | r = radeon_cs_finish_pages(&parser); | ||
| 771 | if (r) { | ||
| 772 | DRM_ERROR("Invalid command stream !\n"); | ||
| 773 | r600_cs_parser_fini(&parser, r); | ||
| 774 | return r; | ||
| 775 | } | ||
| 650 | r600_cs_parser_fini(&parser, r); | 776 | r600_cs_parser_fini(&parser, r); |
| 651 | return r; | 777 | return r; |
| 652 | } | 778 | } |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 6311b1362594..950b346e343f 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -44,6 +44,24 @@ | |||
| 44 | * - TESTING, TESTING, TESTING | 44 | * - TESTING, TESTING, TESTING |
| 45 | */ | 45 | */ |
| 46 | 46 | ||
| 47 | /* Initialization path: | ||
| 48 | * We expect that acceleration initialization might fail for various | ||
| 49 | * reasons even thought we work hard to make it works on most | ||
| 50 | * configurations. In order to still have a working userspace in such | ||
| 51 | * situation the init path must succeed up to the memory controller | ||
| 52 | * initialization point. Failure before this point are considered as | ||
| 53 | * fatal error. Here is the init callchain : | ||
| 54 | * radeon_device_init perform common structure, mutex initialization | ||
| 55 | * asic_init setup the GPU memory layout and perform all | ||
| 56 | * one time initialization (failure in this | ||
| 57 | * function are considered fatal) | ||
| 58 | * asic_startup setup the GPU acceleration, in order to | ||
| 59 | * follow guideline the first thing this | ||
| 60 | * function should do is setting the GPU | ||
| 61 | * memory controller (only MC setup failure | ||
| 62 | * are considered as fatal) | ||
| 63 | */ | ||
| 64 | |||
| 47 | #include <asm/atomic.h> | 65 | #include <asm/atomic.h> |
| 48 | #include <linux/wait.h> | 66 | #include <linux/wait.h> |
| 49 | #include <linux/list.h> | 67 | #include <linux/list.h> |
| @@ -342,7 +360,7 @@ struct radeon_ib { | |||
| 342 | unsigned long idx; | 360 | unsigned long idx; |
| 343 | uint64_t gpu_addr; | 361 | uint64_t gpu_addr; |
| 344 | struct radeon_fence *fence; | 362 | struct radeon_fence *fence; |
| 345 | volatile uint32_t *ptr; | 363 | uint32_t *ptr; |
| 346 | uint32_t length_dw; | 364 | uint32_t length_dw; |
| 347 | }; | 365 | }; |
| 348 | 366 | ||
| @@ -415,7 +433,12 @@ struct radeon_cs_reloc { | |||
| 415 | struct radeon_cs_chunk { | 433 | struct radeon_cs_chunk { |
| 416 | uint32_t chunk_id; | 434 | uint32_t chunk_id; |
| 417 | uint32_t length_dw; | 435 | uint32_t length_dw; |
| 436 | int kpage_idx[2]; | ||
| 437 | uint32_t *kpage[2]; | ||
| 418 | uint32_t *kdata; | 438 | uint32_t *kdata; |
| 439 | void __user *user_ptr; | ||
| 440 | int last_copied_page; | ||
| 441 | int last_page_index; | ||
| 419 | }; | 442 | }; |
| 420 | 443 | ||
| 421 | struct radeon_cs_parser { | 444 | struct radeon_cs_parser { |
| @@ -438,8 +461,38 @@ struct radeon_cs_parser { | |||
| 438 | struct radeon_ib *ib; | 461 | struct radeon_ib *ib; |
| 439 | void *track; | 462 | void *track; |
| 440 | unsigned family; | 463 | unsigned family; |
| 464 | int parser_error; | ||
| 441 | }; | 465 | }; |
| 442 | 466 | ||
| 467 | extern int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx); | ||
| 468 | extern int radeon_cs_finish_pages(struct radeon_cs_parser *p); | ||
| 469 | |||
| 470 | |||
| 471 | static inline u32 radeon_get_ib_value(struct radeon_cs_parser *p, int idx) | ||
| 472 | { | ||
| 473 | struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx]; | ||
| 474 | u32 pg_idx, pg_offset; | ||
| 475 | u32 idx_value = 0; | ||
| 476 | int new_page; | ||
| 477 | |||
| 478 | pg_idx = (idx * 4) / PAGE_SIZE; | ||
| 479 | pg_offset = (idx * 4) % PAGE_SIZE; | ||
| 480 | |||
| 481 | if (ibc->kpage_idx[0] == pg_idx) | ||
| 482 | return ibc->kpage[0][pg_offset/4]; | ||
| 483 | if (ibc->kpage_idx[1] == pg_idx) | ||
| 484 | return ibc->kpage[1][pg_offset/4]; | ||
| 485 | |||
| 486 | new_page = radeon_cs_update_pages(p, pg_idx); | ||
| 487 | if (new_page < 0) { | ||
| 488 | p->parser_error = new_page; | ||
| 489 | return 0; | ||
| 490 | } | ||
| 491 | |||
| 492 | idx_value = ibc->kpage[new_page][pg_offset/4]; | ||
| 493 | return idx_value; | ||
| 494 | } | ||
| 495 | |||
| 443 | struct radeon_cs_packet { | 496 | struct radeon_cs_packet { |
| 444 | unsigned idx; | 497 | unsigned idx; |
| 445 | unsigned type; | 498 | unsigned type; |
| @@ -943,6 +996,7 @@ extern void radeon_clocks_fini(struct radeon_device *rdev); | |||
| 943 | extern void radeon_scratch_init(struct radeon_device *rdev); | 996 | extern void radeon_scratch_init(struct radeon_device *rdev); |
| 944 | extern void radeon_surface_init(struct radeon_device *rdev); | 997 | extern void radeon_surface_init(struct radeon_device *rdev); |
| 945 | extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data); | 998 | extern int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data); |
| 999 | extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); | ||
| 946 | 1000 | ||
| 947 | /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */ | 1001 | /* r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */ |
| 948 | struct r100_mc_save { | 1002 | struct r100_mc_save { |
| @@ -974,6 +1028,9 @@ extern void r100_vram_init_sizes(struct radeon_device *rdev); | |||
| 974 | extern void r100_wb_disable(struct radeon_device *rdev); | 1028 | extern void r100_wb_disable(struct radeon_device *rdev); |
| 975 | extern void r100_wb_fini(struct radeon_device *rdev); | 1029 | extern void r100_wb_fini(struct radeon_device *rdev); |
| 976 | extern int r100_wb_init(struct radeon_device *rdev); | 1030 | extern int r100_wb_init(struct radeon_device *rdev); |
| 1031 | extern void r100_hdp_reset(struct radeon_device *rdev); | ||
| 1032 | extern int r100_rb2d_reset(struct radeon_device *rdev); | ||
| 1033 | extern int r100_cp_reset(struct radeon_device *rdev); | ||
| 977 | 1034 | ||
| 978 | /* r300,r350,rv350,rv370,rv380 */ | 1035 | /* r300,r350,rv350,rv370,rv380 */ |
| 979 | extern void r300_set_reg_safe(struct radeon_device *rdev); | 1036 | extern void r300_set_reg_safe(struct radeon_device *rdev); |
| @@ -985,12 +1042,29 @@ extern int rv370_pcie_gart_enable(struct radeon_device *rdev); | |||
| 985 | extern void rv370_pcie_gart_disable(struct radeon_device *rdev); | 1042 | extern void rv370_pcie_gart_disable(struct radeon_device *rdev); |
| 986 | 1043 | ||
| 987 | /* r420,r423,rv410 */ | 1044 | /* r420,r423,rv410 */ |
| 1045 | extern int r420_mc_init(struct radeon_device *rdev); | ||
| 988 | extern u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg); | 1046 | extern u32 r420_mc_rreg(struct radeon_device *rdev, u32 reg); |
| 989 | extern void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v); | 1047 | extern void r420_mc_wreg(struct radeon_device *rdev, u32 reg, u32 v); |
| 990 | extern int r420_debugfs_pipes_info_init(struct radeon_device *rdev); | 1048 | extern int r420_debugfs_pipes_info_init(struct radeon_device *rdev); |
| 1049 | extern void r420_pipes_init(struct radeon_device *rdev); | ||
| 991 | 1050 | ||
| 992 | /* rv515 */ | 1051 | /* rv515 */ |
| 1052 | struct rv515_mc_save { | ||
| 1053 | u32 d1vga_control; | ||
| 1054 | u32 d2vga_control; | ||
| 1055 | u32 vga_render_control; | ||
| 1056 | u32 vga_hdp_control; | ||
| 1057 | u32 d1crtc_control; | ||
| 1058 | u32 d2crtc_control; | ||
| 1059 | }; | ||
| 993 | extern void rv515_bandwidth_avivo_update(struct radeon_device *rdev); | 1060 | extern void rv515_bandwidth_avivo_update(struct radeon_device *rdev); |
| 1061 | extern void rv515_vga_render_disable(struct radeon_device *rdev); | ||
| 1062 | extern void rv515_set_safe_registers(struct radeon_device *rdev); | ||
| 1063 | extern void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save); | ||
| 1064 | extern void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save); | ||
| 1065 | extern void rv515_clock_startup(struct radeon_device *rdev); | ||
| 1066 | extern void rv515_debugfs(struct radeon_device *rdev); | ||
| 1067 | extern int rv515_suspend(struct radeon_device *rdev); | ||
| 994 | 1068 | ||
| 995 | /* rs690, rs740 */ | 1069 | /* rs690, rs740 */ |
| 996 | extern void rs690_line_buffer_adjust(struct radeon_device *rdev, | 1070 | extern void rs690_line_buffer_adjust(struct radeon_device *rdev, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 8968f78fa1e3..c8a4e7b5663d 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
| @@ -420,41 +420,43 @@ static struct radeon_asic rs690_asic = { | |||
| 420 | * rv515 | 420 | * rv515 |
| 421 | */ | 421 | */ |
| 422 | int rv515_init(struct radeon_device *rdev); | 422 | int rv515_init(struct radeon_device *rdev); |
| 423 | void rv515_errata(struct radeon_device *rdev); | 423 | void rv515_fini(struct radeon_device *rdev); |
| 424 | void rv515_vram_info(struct radeon_device *rdev); | ||
| 425 | int rv515_gpu_reset(struct radeon_device *rdev); | 424 | int rv515_gpu_reset(struct radeon_device *rdev); |
| 426 | int rv515_mc_init(struct radeon_device *rdev); | ||
| 427 | void rv515_mc_fini(struct radeon_device *rdev); | ||
| 428 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 425 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
| 429 | void rv515_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 426 | void rv515_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
| 430 | void rv515_ring_start(struct radeon_device *rdev); | 427 | void rv515_ring_start(struct radeon_device *rdev); |
| 431 | uint32_t rv515_pcie_rreg(struct radeon_device *rdev, uint32_t reg); | 428 | uint32_t rv515_pcie_rreg(struct radeon_device *rdev, uint32_t reg); |
| 432 | void rv515_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 429 | void rv515_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
| 433 | void rv515_bandwidth_update(struct radeon_device *rdev); | 430 | void rv515_bandwidth_update(struct radeon_device *rdev); |
| 431 | int rv515_resume(struct radeon_device *rdev); | ||
| 432 | int rv515_suspend(struct radeon_device *rdev); | ||
| 434 | static struct radeon_asic rv515_asic = { | 433 | static struct radeon_asic rv515_asic = { |
| 435 | .init = &rv515_init, | 434 | .init = &rv515_init, |
| 436 | .errata = &rv515_errata, | 435 | .fini = &rv515_fini, |
| 437 | .vram_info = &rv515_vram_info, | 436 | .suspend = &rv515_suspend, |
| 437 | .resume = &rv515_resume, | ||
| 438 | .errata = NULL, | ||
| 439 | .vram_info = NULL, | ||
| 438 | .vga_set_state = &r100_vga_set_state, | 440 | .vga_set_state = &r100_vga_set_state, |
| 439 | .gpu_reset = &rv515_gpu_reset, | 441 | .gpu_reset = &rv515_gpu_reset, |
| 440 | .mc_init = &rv515_mc_init, | 442 | .mc_init = NULL, |
| 441 | .mc_fini = &rv515_mc_fini, | 443 | .mc_fini = NULL, |
| 442 | .wb_init = &r100_wb_init, | 444 | .wb_init = NULL, |
| 443 | .wb_fini = &r100_wb_fini, | 445 | .wb_fini = NULL, |
| 444 | .gart_init = &rv370_pcie_gart_init, | 446 | .gart_init = &rv370_pcie_gart_init, |
| 445 | .gart_fini = &rv370_pcie_gart_fini, | 447 | .gart_fini = &rv370_pcie_gart_fini, |
| 446 | .gart_enable = &rv370_pcie_gart_enable, | 448 | .gart_enable = NULL, |
| 447 | .gart_disable = &rv370_pcie_gart_disable, | 449 | .gart_disable = NULL, |
| 448 | .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, | 450 | .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, |
| 449 | .gart_set_page = &rv370_pcie_gart_set_page, | 451 | .gart_set_page = &rv370_pcie_gart_set_page, |
| 450 | .cp_init = &r100_cp_init, | 452 | .cp_init = NULL, |
| 451 | .cp_fini = &r100_cp_fini, | 453 | .cp_fini = NULL, |
| 452 | .cp_disable = &r100_cp_disable, | 454 | .cp_disable = NULL, |
| 453 | .cp_commit = &r100_cp_commit, | 455 | .cp_commit = &r100_cp_commit, |
| 454 | .ring_start = &rv515_ring_start, | 456 | .ring_start = &rv515_ring_start, |
| 455 | .ring_test = &r100_ring_test, | 457 | .ring_test = &r100_ring_test, |
| 456 | .ring_ib_execute = &r100_ring_ib_execute, | 458 | .ring_ib_execute = &r100_ring_ib_execute, |
| 457 | .ib_test = &r100_ib_test, | 459 | .ib_test = NULL, |
| 458 | .irq_set = &rs600_irq_set, | 460 | .irq_set = &rs600_irq_set, |
| 459 | .irq_process = &rs600_irq_process, | 461 | .irq_process = &rs600_irq_process, |
| 460 | .get_vblank_counter = &rs600_get_vblank_counter, | 462 | .get_vblank_counter = &rs600_get_vblank_counter, |
| @@ -476,35 +478,35 @@ static struct radeon_asic rv515_asic = { | |||
| 476 | /* | 478 | /* |
| 477 | * r520,rv530,rv560,rv570,r580 | 479 | * r520,rv530,rv560,rv570,r580 |
| 478 | */ | 480 | */ |
| 479 | void r520_errata(struct radeon_device *rdev); | 481 | int r520_init(struct radeon_device *rdev); |
| 480 | void r520_vram_info(struct radeon_device *rdev); | 482 | int r520_resume(struct radeon_device *rdev); |
| 481 | int r520_mc_init(struct radeon_device *rdev); | ||
| 482 | void r520_mc_fini(struct radeon_device *rdev); | ||
| 483 | void r520_bandwidth_update(struct radeon_device *rdev); | ||
| 484 | static struct radeon_asic r520_asic = { | 483 | static struct radeon_asic r520_asic = { |
| 485 | .init = &rv515_init, | 484 | .init = &r520_init, |
| 486 | .errata = &r520_errata, | 485 | .fini = &rv515_fini, |
| 487 | .vram_info = &r520_vram_info, | 486 | .suspend = &rv515_suspend, |
| 487 | .resume = &r520_resume, | ||
| 488 | .errata = NULL, | ||
| 489 | .vram_info = NULL, | ||
| 488 | .vga_set_state = &r100_vga_set_state, | 490 | .vga_set_state = &r100_vga_set_state, |
| 489 | .gpu_reset = &rv515_gpu_reset, | 491 | .gpu_reset = &rv515_gpu_reset, |
| 490 | .mc_init = &r520_mc_init, | 492 | .mc_init = NULL, |
| 491 | .mc_fini = &r520_mc_fini, | 493 | .mc_fini = NULL, |
| 492 | .wb_init = &r100_wb_init, | 494 | .wb_init = NULL, |
| 493 | .wb_fini = &r100_wb_fini, | 495 | .wb_fini = NULL, |
| 494 | .gart_init = &rv370_pcie_gart_init, | 496 | .gart_init = NULL, |
| 495 | .gart_fini = &rv370_pcie_gart_fini, | 497 | .gart_fini = NULL, |
| 496 | .gart_enable = &rv370_pcie_gart_enable, | 498 | .gart_enable = NULL, |
| 497 | .gart_disable = &rv370_pcie_gart_disable, | 499 | .gart_disable = NULL, |
| 498 | .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, | 500 | .gart_tlb_flush = &rv370_pcie_gart_tlb_flush, |
| 499 | .gart_set_page = &rv370_pcie_gart_set_page, | 501 | .gart_set_page = &rv370_pcie_gart_set_page, |
| 500 | .cp_init = &r100_cp_init, | 502 | .cp_init = NULL, |
| 501 | .cp_fini = &r100_cp_fini, | 503 | .cp_fini = NULL, |
| 502 | .cp_disable = &r100_cp_disable, | 504 | .cp_disable = NULL, |
| 503 | .cp_commit = &r100_cp_commit, | 505 | .cp_commit = &r100_cp_commit, |
| 504 | .ring_start = &rv515_ring_start, | 506 | .ring_start = &rv515_ring_start, |
| 505 | .ring_test = &r100_ring_test, | 507 | .ring_test = &r100_ring_test, |
| 506 | .ring_ib_execute = &r100_ring_ib_execute, | 508 | .ring_ib_execute = &r100_ring_ib_execute, |
| 507 | .ib_test = &r100_ib_test, | 509 | .ib_test = NULL, |
| 508 | .irq_set = &rs600_irq_set, | 510 | .irq_set = &rs600_irq_set, |
| 509 | .irq_process = &rs600_irq_process, | 511 | .irq_process = &rs600_irq_process, |
| 510 | .get_vblank_counter = &rs600_get_vblank_counter, | 512 | .get_vblank_counter = &rs600_get_vblank_counter, |
| @@ -519,7 +521,7 @@ static struct radeon_asic r520_asic = { | |||
| 519 | .set_clock_gating = &radeon_atom_set_clock_gating, | 521 | .set_clock_gating = &radeon_atom_set_clock_gating, |
| 520 | .set_surface_reg = r100_set_surface_reg, | 522 | .set_surface_reg = r100_set_surface_reg, |
| 521 | .clear_surface_reg = r100_clear_surface_reg, | 523 | .clear_surface_reg = r100_clear_surface_reg, |
| 522 | .bandwidth_update = &r520_bandwidth_update, | 524 | .bandwidth_update = &rv515_bandwidth_update, |
| 523 | }; | 525 | }; |
| 524 | 526 | ||
| 525 | /* | 527 | /* |
| @@ -596,7 +598,7 @@ static struct radeon_asic r600_asic = { | |||
| 596 | .set_clock_gating = &radeon_atom_set_clock_gating, | 598 | .set_clock_gating = &radeon_atom_set_clock_gating, |
| 597 | .set_surface_reg = r600_set_surface_reg, | 599 | .set_surface_reg = r600_set_surface_reg, |
| 598 | .clear_surface_reg = r600_clear_surface_reg, | 600 | .clear_surface_reg = r600_clear_surface_reg, |
| 599 | .bandwidth_update = &r520_bandwidth_update, | 601 | .bandwidth_update = &rv515_bandwidth_update, |
| 600 | }; | 602 | }; |
| 601 | 603 | ||
| 602 | /* | 604 | /* |
| @@ -646,7 +648,7 @@ static struct radeon_asic rv770_asic = { | |||
| 646 | .set_clock_gating = &radeon_atom_set_clock_gating, | 648 | .set_clock_gating = &radeon_atom_set_clock_gating, |
| 647 | .set_surface_reg = r600_set_surface_reg, | 649 | .set_surface_reg = r600_set_surface_reg, |
| 648 | .clear_surface_reg = r600_clear_surface_reg, | 650 | .clear_surface_reg = r600_clear_surface_reg, |
| 649 | .bandwidth_update = &r520_bandwidth_update, | 651 | .bandwidth_update = &rv515_bandwidth_update, |
| 650 | }; | 652 | }; |
| 651 | 653 | ||
| 652 | #endif | 654 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 743742128307..5b6c08cee40e 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
| @@ -272,12 +272,9 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
| 272 | (le16_to_cpu(path->usConnObjectId) & | 272 | (le16_to_cpu(path->usConnObjectId) & |
| 273 | OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; | 273 | OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; |
| 274 | 274 | ||
| 275 | if ((le16_to_cpu(path->usDeviceTag) == | 275 | /* TODO CV support */ |
| 276 | ATOM_DEVICE_TV1_SUPPORT) | 276 | if (le16_to_cpu(path->usDeviceTag) == |
| 277 | || (le16_to_cpu(path->usDeviceTag) == | 277 | ATOM_DEVICE_CV_SUPPORT) |
| 278 | ATOM_DEVICE_TV2_SUPPORT) | ||
| 279 | || (le16_to_cpu(path->usDeviceTag) == | ||
| 280 | ATOM_DEVICE_CV_SUPPORT)) | ||
| 281 | continue; | 278 | continue; |
| 282 | 279 | ||
| 283 | if ((rdev->family == CHIP_RS780) && | 280 | if ((rdev->family == CHIP_RS780) && |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index af1d551f1a8f..e376be47a4a0 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include "drmP.h" | 26 | #include "drmP.h" |
| 27 | #include "drm_edid.h" | 27 | #include "drm_edid.h" |
| 28 | #include "drm_crtc_helper.h" | 28 | #include "drm_crtc_helper.h" |
| 29 | #include "drm_fb_helper.h" | ||
| 29 | #include "radeon_drm.h" | 30 | #include "radeon_drm.h" |
| 30 | #include "radeon.h" | 31 | #include "radeon.h" |
| 31 | #include "atom.h" | 32 | #include "atom.h" |
| @@ -245,7 +246,7 @@ static void radeon_add_common_modes(struct drm_encoder *encoder, struct drm_conn | |||
| 245 | if (common_modes[i].w < 320 || common_modes[i].h < 200) | 246 | if (common_modes[i].w < 320 || common_modes[i].h < 200) |
| 246 | continue; | 247 | continue; |
| 247 | 248 | ||
| 248 | mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false); | 249 | mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false); |
| 249 | drm_mode_probed_add(connector, mode); | 250 | drm_mode_probed_add(connector, mode); |
| 250 | } | 251 | } |
| 251 | } | 252 | } |
| @@ -559,7 +560,7 @@ static int radeon_tv_get_modes(struct drm_connector *connector) | |||
| 559 | radeon_add_common_modes(encoder, connector); | 560 | radeon_add_common_modes(encoder, connector); |
| 560 | else { | 561 | else { |
| 561 | /* only 800x600 is supported right now on pre-avivo chips */ | 562 | /* only 800x600 is supported right now on pre-avivo chips */ |
| 562 | tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false); | 563 | tv_mode = drm_cvt_mode(dev, 800, 600, 60, false, false, false); |
| 563 | tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; | 564 | tv_mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; |
| 564 | drm_mode_probed_add(connector, tv_mode); | 565 | drm_mode_probed_add(connector, tv_mode); |
| 565 | } | 566 | } |
| @@ -743,6 +744,15 @@ struct drm_encoder *radeon_dvi_encoder(struct drm_connector *connector) | |||
| 743 | return NULL; | 744 | return NULL; |
| 744 | } | 745 | } |
| 745 | 746 | ||
| 747 | static void radeon_dvi_force(struct drm_connector *connector) | ||
| 748 | { | ||
| 749 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
| 750 | if (connector->force == DRM_FORCE_ON) | ||
| 751 | radeon_connector->use_digital = false; | ||
| 752 | if (connector->force == DRM_FORCE_ON_DIGITAL) | ||
| 753 | radeon_connector->use_digital = true; | ||
| 754 | } | ||
| 755 | |||
| 746 | struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = { | 756 | struct drm_connector_helper_funcs radeon_dvi_connector_helper_funcs = { |
| 747 | .get_modes = radeon_dvi_get_modes, | 757 | .get_modes = radeon_dvi_get_modes, |
| 748 | .mode_valid = radeon_vga_mode_valid, | 758 | .mode_valid = radeon_vga_mode_valid, |
| @@ -755,6 +765,7 @@ struct drm_connector_funcs radeon_dvi_connector_funcs = { | |||
| 755 | .fill_modes = drm_helper_probe_single_connector_modes, | 765 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 756 | .set_property = radeon_connector_set_property, | 766 | .set_property = radeon_connector_set_property, |
| 757 | .destroy = radeon_connector_destroy, | 767 | .destroy = radeon_connector_destroy, |
| 768 | .force = radeon_dvi_force, | ||
| 758 | }; | 769 | }; |
| 759 | 770 | ||
| 760 | void | 771 | void |
| @@ -771,6 +782,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 771 | struct radeon_connector *radeon_connector; | 782 | struct radeon_connector *radeon_connector; |
| 772 | struct radeon_connector_atom_dig *radeon_dig_connector; | 783 | struct radeon_connector_atom_dig *radeon_dig_connector; |
| 773 | uint32_t subpixel_order = SubPixelNone; | 784 | uint32_t subpixel_order = SubPixelNone; |
| 785 | int ret; | ||
| 774 | 786 | ||
| 775 | /* fixme - tv/cv/din */ | 787 | /* fixme - tv/cv/din */ |
| 776 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) | 788 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) |
| @@ -796,24 +808,30 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 796 | switch (connector_type) { | 808 | switch (connector_type) { |
| 797 | case DRM_MODE_CONNECTOR_VGA: | 809 | case DRM_MODE_CONNECTOR_VGA: |
| 798 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); | 810 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
| 799 | drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); | 811 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); |
| 812 | if (ret) | ||
| 813 | goto failed; | ||
| 800 | if (i2c_bus->valid) { | 814 | if (i2c_bus->valid) { |
| 801 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA"); | 815 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA"); |
| 802 | if (!radeon_connector->ddc_bus) | 816 | if (!radeon_connector->ddc_bus) |
| 803 | goto failed; | 817 | goto failed; |
| 804 | } | 818 | } |
| 819 | radeon_connector->dac_load_detect = true; | ||
| 805 | drm_connector_attach_property(&radeon_connector->base, | 820 | drm_connector_attach_property(&radeon_connector->base, |
| 806 | rdev->mode_info.load_detect_property, | 821 | rdev->mode_info.load_detect_property, |
| 807 | 1); | 822 | 1); |
| 808 | break; | 823 | break; |
| 809 | case DRM_MODE_CONNECTOR_DVIA: | 824 | case DRM_MODE_CONNECTOR_DVIA: |
| 810 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); | 825 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
| 811 | drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); | 826 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); |
| 827 | if (ret) | ||
| 828 | goto failed; | ||
| 812 | if (i2c_bus->valid) { | 829 | if (i2c_bus->valid) { |
| 813 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); | 830 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); |
| 814 | if (!radeon_connector->ddc_bus) | 831 | if (!radeon_connector->ddc_bus) |
| 815 | goto failed; | 832 | goto failed; |
| 816 | } | 833 | } |
| 834 | radeon_connector->dac_load_detect = true; | ||
| 817 | drm_connector_attach_property(&radeon_connector->base, | 835 | drm_connector_attach_property(&radeon_connector->base, |
| 818 | rdev->mode_info.load_detect_property, | 836 | rdev->mode_info.load_detect_property, |
| 819 | 1); | 837 | 1); |
| @@ -827,7 +845,9 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 827 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 845 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
| 828 | radeon_connector->con_priv = radeon_dig_connector; | 846 | radeon_connector->con_priv = radeon_dig_connector; |
| 829 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); | 847 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
| 830 | drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); | 848 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); |
| 849 | if (ret) | ||
| 850 | goto failed; | ||
| 831 | if (i2c_bus->valid) { | 851 | if (i2c_bus->valid) { |
| 832 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); | 852 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); |
| 833 | if (!radeon_connector->ddc_bus) | 853 | if (!radeon_connector->ddc_bus) |
| @@ -837,6 +857,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 837 | drm_connector_attach_property(&radeon_connector->base, | 857 | drm_connector_attach_property(&radeon_connector->base, |
| 838 | rdev->mode_info.coherent_mode_property, | 858 | rdev->mode_info.coherent_mode_property, |
| 839 | 1); | 859 | 1); |
| 860 | radeon_connector->dac_load_detect = true; | ||
| 840 | drm_connector_attach_property(&radeon_connector->base, | 861 | drm_connector_attach_property(&radeon_connector->base, |
| 841 | rdev->mode_info.load_detect_property, | 862 | rdev->mode_info.load_detect_property, |
| 842 | 1); | 863 | 1); |
| @@ -850,7 +871,9 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 850 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 871 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
| 851 | radeon_connector->con_priv = radeon_dig_connector; | 872 | radeon_connector->con_priv = radeon_dig_connector; |
| 852 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); | 873 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
| 853 | drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); | 874 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); |
| 875 | if (ret) | ||
| 876 | goto failed; | ||
| 854 | if (i2c_bus->valid) { | 877 | if (i2c_bus->valid) { |
| 855 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "HDMI"); | 878 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "HDMI"); |
| 856 | if (!radeon_connector->ddc_bus) | 879 | if (!radeon_connector->ddc_bus) |
| @@ -869,7 +892,9 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 869 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 892 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
| 870 | radeon_connector->con_priv = radeon_dig_connector; | 893 | radeon_connector->con_priv = radeon_dig_connector; |
| 871 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); | 894 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
| 872 | drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); | 895 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); |
| 896 | if (ret) | ||
| 897 | goto failed; | ||
| 873 | if (i2c_bus->valid) { | 898 | if (i2c_bus->valid) { |
| 874 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP"); | 899 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DP"); |
| 875 | if (!radeon_connector->ddc_bus) | 900 | if (!radeon_connector->ddc_bus) |
| @@ -882,11 +907,14 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 882 | case DRM_MODE_CONNECTOR_9PinDIN: | 907 | case DRM_MODE_CONNECTOR_9PinDIN: |
| 883 | if (radeon_tv == 1) { | 908 | if (radeon_tv == 1) { |
| 884 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); | 909 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); |
| 885 | drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); | 910 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); |
| 911 | if (ret) | ||
| 912 | goto failed; | ||
| 913 | radeon_connector->dac_load_detect = true; | ||
| 914 | drm_connector_attach_property(&radeon_connector->base, | ||
| 915 | rdev->mode_info.load_detect_property, | ||
| 916 | 1); | ||
| 886 | } | 917 | } |
| 887 | drm_connector_attach_property(&radeon_connector->base, | ||
| 888 | rdev->mode_info.load_detect_property, | ||
| 889 | 1); | ||
| 890 | break; | 918 | break; |
| 891 | case DRM_MODE_CONNECTOR_LVDS: | 919 | case DRM_MODE_CONNECTOR_LVDS: |
| 892 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 920 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
| @@ -896,7 +924,9 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
| 896 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 924 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
| 897 | radeon_connector->con_priv = radeon_dig_connector; | 925 | radeon_connector->con_priv = radeon_dig_connector; |
| 898 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); | 926 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); |
| 899 | drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); | 927 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); |
| 928 | if (ret) | ||
| 929 | goto failed; | ||
| 900 | if (i2c_bus->valid) { | 930 | if (i2c_bus->valid) { |
| 901 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS"); | 931 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS"); |
| 902 | if (!radeon_connector->ddc_bus) | 932 | if (!radeon_connector->ddc_bus) |
| @@ -932,6 +962,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
| 932 | struct drm_connector *connector; | 962 | struct drm_connector *connector; |
| 933 | struct radeon_connector *radeon_connector; | 963 | struct radeon_connector *radeon_connector; |
| 934 | uint32_t subpixel_order = SubPixelNone; | 964 | uint32_t subpixel_order = SubPixelNone; |
| 965 | int ret; | ||
| 935 | 966 | ||
| 936 | /* fixme - tv/cv/din */ | 967 | /* fixme - tv/cv/din */ |
| 937 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) | 968 | if (connector_type == DRM_MODE_CONNECTOR_Unknown) |
| @@ -957,24 +988,30 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
| 957 | switch (connector_type) { | 988 | switch (connector_type) { |
| 958 | case DRM_MODE_CONNECTOR_VGA: | 989 | case DRM_MODE_CONNECTOR_VGA: |
| 959 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); | 990 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
| 960 | drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); | 991 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); |
| 992 | if (ret) | ||
| 993 | goto failed; | ||
| 961 | if (i2c_bus->valid) { | 994 | if (i2c_bus->valid) { |
| 962 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA"); | 995 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "VGA"); |
| 963 | if (!radeon_connector->ddc_bus) | 996 | if (!radeon_connector->ddc_bus) |
| 964 | goto failed; | 997 | goto failed; |
| 965 | } | 998 | } |
| 999 | radeon_connector->dac_load_detect = true; | ||
| 966 | drm_connector_attach_property(&radeon_connector->base, | 1000 | drm_connector_attach_property(&radeon_connector->base, |
| 967 | rdev->mode_info.load_detect_property, | 1001 | rdev->mode_info.load_detect_property, |
| 968 | 1); | 1002 | 1); |
| 969 | break; | 1003 | break; |
| 970 | case DRM_MODE_CONNECTOR_DVIA: | 1004 | case DRM_MODE_CONNECTOR_DVIA: |
| 971 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); | 1005 | drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); |
| 972 | drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); | 1006 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs); |
| 1007 | if (ret) | ||
| 1008 | goto failed; | ||
| 973 | if (i2c_bus->valid) { | 1009 | if (i2c_bus->valid) { |
| 974 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); | 1010 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); |
| 975 | if (!radeon_connector->ddc_bus) | 1011 | if (!radeon_connector->ddc_bus) |
| 976 | goto failed; | 1012 | goto failed; |
| 977 | } | 1013 | } |
| 1014 | radeon_connector->dac_load_detect = true; | ||
| 978 | drm_connector_attach_property(&radeon_connector->base, | 1015 | drm_connector_attach_property(&radeon_connector->base, |
| 979 | rdev->mode_info.load_detect_property, | 1016 | rdev->mode_info.load_detect_property, |
| 980 | 1); | 1017 | 1); |
| @@ -982,11 +1019,14 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
| 982 | case DRM_MODE_CONNECTOR_DVII: | 1019 | case DRM_MODE_CONNECTOR_DVII: |
| 983 | case DRM_MODE_CONNECTOR_DVID: | 1020 | case DRM_MODE_CONNECTOR_DVID: |
| 984 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); | 1021 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
| 985 | drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); | 1022 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs); |
| 1023 | if (ret) | ||
| 1024 | goto failed; | ||
| 986 | if (i2c_bus->valid) { | 1025 | if (i2c_bus->valid) { |
| 987 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); | 1026 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "DVI"); |
| 988 | if (!radeon_connector->ddc_bus) | 1027 | if (!radeon_connector->ddc_bus) |
| 989 | goto failed; | 1028 | goto failed; |
| 1029 | radeon_connector->dac_load_detect = true; | ||
| 990 | drm_connector_attach_property(&radeon_connector->base, | 1030 | drm_connector_attach_property(&radeon_connector->base, |
| 991 | rdev->mode_info.load_detect_property, | 1031 | rdev->mode_info.load_detect_property, |
| 992 | 1); | 1032 | 1); |
| @@ -998,7 +1038,10 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
| 998 | case DRM_MODE_CONNECTOR_9PinDIN: | 1038 | case DRM_MODE_CONNECTOR_9PinDIN: |
| 999 | if (radeon_tv == 1) { | 1039 | if (radeon_tv == 1) { |
| 1000 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); | 1040 | drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type); |
| 1001 | drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); | 1041 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs); |
| 1042 | if (ret) | ||
| 1043 | goto failed; | ||
| 1044 | radeon_connector->dac_load_detect = true; | ||
| 1002 | drm_connector_attach_property(&radeon_connector->base, | 1045 | drm_connector_attach_property(&radeon_connector->base, |
| 1003 | rdev->mode_info.load_detect_property, | 1046 | rdev->mode_info.load_detect_property, |
| 1004 | 1); | 1047 | 1); |
| @@ -1006,7 +1049,9 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
| 1006 | break; | 1049 | break; |
| 1007 | case DRM_MODE_CONNECTOR_LVDS: | 1050 | case DRM_MODE_CONNECTOR_LVDS: |
| 1008 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); | 1051 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); |
| 1009 | drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); | 1052 | ret = drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs); |
| 1053 | if (ret) | ||
| 1054 | goto failed; | ||
| 1010 | if (i2c_bus->valid) { | 1055 | if (i2c_bus->valid) { |
| 1011 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS"); | 1056 | radeon_connector->ddc_bus = radeon_i2c_create(dev, i2c_bus, "LVDS"); |
| 1012 | if (!radeon_connector->ddc_bus) | 1057 | if (!radeon_connector->ddc_bus) |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 12f5990c2d2a..5ab2cf96a264 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
| @@ -142,15 +142,31 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | p->chunks[i].length_dw = user_chunk.length_dw; | 144 | p->chunks[i].length_dw = user_chunk.length_dw; |
| 145 | cdata = (uint32_t *)(unsigned long)user_chunk.chunk_data; | 145 | p->chunks[i].user_ptr = (void __user *)(unsigned long)user_chunk.chunk_data; |
| 146 | 146 | ||
| 147 | size = p->chunks[i].length_dw * sizeof(uint32_t); | 147 | cdata = (uint32_t *)(unsigned long)user_chunk.chunk_data; |
| 148 | p->chunks[i].kdata = kmalloc(size, GFP_KERNEL); | 148 | if (p->chunks[i].chunk_id != RADEON_CHUNK_ID_IB) { |
| 149 | if (p->chunks[i].kdata == NULL) { | 149 | size = p->chunks[i].length_dw * sizeof(uint32_t); |
| 150 | return -ENOMEM; | 150 | p->chunks[i].kdata = kmalloc(size, GFP_KERNEL); |
| 151 | } | 151 | if (p->chunks[i].kdata == NULL) { |
| 152 | if (DRM_COPY_FROM_USER(p->chunks[i].kdata, cdata, size)) { | 152 | return -ENOMEM; |
| 153 | return -EFAULT; | 153 | } |
| 154 | if (DRM_COPY_FROM_USER(p->chunks[i].kdata, | ||
| 155 | p->chunks[i].user_ptr, size)) { | ||
| 156 | return -EFAULT; | ||
| 157 | } | ||
| 158 | } else { | ||
| 159 | p->chunks[i].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
| 160 | p->chunks[i].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
| 161 | if (p->chunks[i].kpage[0] == NULL || p->chunks[i].kpage[1] == NULL) { | ||
| 162 | kfree(p->chunks[i].kpage[0]); | ||
| 163 | kfree(p->chunks[i].kpage[1]); | ||
| 164 | return -ENOMEM; | ||
| 165 | } | ||
| 166 | p->chunks[i].kpage_idx[0] = -1; | ||
| 167 | p->chunks[i].kpage_idx[1] = -1; | ||
| 168 | p->chunks[i].last_copied_page = -1; | ||
| 169 | p->chunks[i].last_page_index = ((p->chunks[i].length_dw * 4) - 1) / PAGE_SIZE; | ||
| 154 | } | 170 | } |
| 155 | } | 171 | } |
| 156 | if (p->chunks[p->chunk_ib_idx].length_dw > (16 * 1024)) { | 172 | 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) | |||
| 190 | kfree(parser->relocs_ptr); | 206 | kfree(parser->relocs_ptr); |
| 191 | for (i = 0; i < parser->nchunks; i++) { | 207 | for (i = 0; i < parser->nchunks; i++) { |
| 192 | kfree(parser->chunks[i].kdata); | 208 | kfree(parser->chunks[i].kdata); |
| 209 | kfree(parser->chunks[i].kpage[0]); | ||
| 210 | kfree(parser->chunks[i].kpage[1]); | ||
| 193 | } | 211 | } |
| 194 | kfree(parser->chunks); | 212 | kfree(parser->chunks); |
| 195 | kfree(parser->chunks_array); | 213 | kfree(parser->chunks_array); |
| @@ -238,8 +256,14 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
| 238 | * uncached). */ | 256 | * uncached). */ |
| 239 | ib_chunk = &parser.chunks[parser.chunk_ib_idx]; | 257 | ib_chunk = &parser.chunks[parser.chunk_ib_idx]; |
| 240 | parser.ib->length_dw = ib_chunk->length_dw; | 258 | parser.ib->length_dw = ib_chunk->length_dw; |
| 241 | memcpy((void *)parser.ib->ptr, ib_chunk->kdata, ib_chunk->length_dw*4); | ||
| 242 | r = radeon_cs_parse(&parser); | 259 | r = radeon_cs_parse(&parser); |
| 260 | if (r || parser.parser_error) { | ||
| 261 | DRM_ERROR("Invalid command stream !\n"); | ||
| 262 | radeon_cs_parser_fini(&parser, r); | ||
| 263 | mutex_unlock(&rdev->cs_mutex); | ||
| 264 | return r; | ||
| 265 | } | ||
| 266 | r = radeon_cs_finish_pages(&parser); | ||
| 243 | if (r) { | 267 | if (r) { |
| 244 | DRM_ERROR("Invalid command stream !\n"); | 268 | DRM_ERROR("Invalid command stream !\n"); |
| 245 | radeon_cs_parser_fini(&parser, r); | 269 | radeon_cs_parser_fini(&parser, r); |
| @@ -254,3 +278,64 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
| 254 | mutex_unlock(&rdev->cs_mutex); | 278 | mutex_unlock(&rdev->cs_mutex); |
| 255 | return r; | 279 | return r; |
| 256 | } | 280 | } |
| 281 | |||
| 282 | int radeon_cs_finish_pages(struct radeon_cs_parser *p) | ||
| 283 | { | ||
| 284 | struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx]; | ||
| 285 | int i; | ||
| 286 | int size = PAGE_SIZE; | ||
| 287 | |||
| 288 | for (i = ibc->last_copied_page + 1; i <= ibc->last_page_index; i++) { | ||
| 289 | if (i == ibc->last_page_index) { | ||
| 290 | size = (ibc->length_dw * 4) % PAGE_SIZE; | ||
| 291 | if (size == 0) | ||
| 292 | size = PAGE_SIZE; | ||
| 293 | } | ||
| 294 | |||
| 295 | if (DRM_COPY_FROM_USER(p->ib->ptr + (i * (PAGE_SIZE/4)), | ||
| 296 | ibc->user_ptr + (i * PAGE_SIZE), | ||
| 297 | size)) | ||
| 298 | return -EFAULT; | ||
| 299 | } | ||
| 300 | return 0; | ||
| 301 | } | ||
| 302 | |||
| 303 | int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx) | ||
| 304 | { | ||
| 305 | int new_page; | ||
| 306 | struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx]; | ||
| 307 | int i; | ||
| 308 | int size = PAGE_SIZE; | ||
| 309 | |||
| 310 | for (i = ibc->last_copied_page + 1; i < pg_idx; i++) { | ||
| 311 | if (DRM_COPY_FROM_USER(p->ib->ptr + (i * (PAGE_SIZE/4)), | ||
| 312 | ibc->user_ptr + (i * PAGE_SIZE), | ||
| 313 | PAGE_SIZE)) { | ||
| 314 | p->parser_error = -EFAULT; | ||
| 315 | return 0; | ||
| 316 | } | ||
| 317 | } | ||
| 318 | |||
| 319 | new_page = ibc->kpage_idx[0] < ibc->kpage_idx[1] ? 0 : 1; | ||
| 320 | |||
| 321 | if (pg_idx == ibc->last_page_index) { | ||
| 322 | size = (ibc->length_dw * 4) % PAGE_SIZE; | ||
| 323 | if (size == 0) | ||
| 324 | size = PAGE_SIZE; | ||
| 325 | } | ||
| 326 | |||
| 327 | if (DRM_COPY_FROM_USER(ibc->kpage[new_page], | ||
| 328 | ibc->user_ptr + (pg_idx * PAGE_SIZE), | ||
| 329 | size)) { | ||
| 330 | p->parser_error = -EFAULT; | ||
| 331 | return 0; | ||
| 332 | } | ||
| 333 | |||
| 334 | /* copy to IB here */ | ||
| 335 | memcpy((void *)(p->ib->ptr+(pg_idx*(PAGE_SIZE/4))), ibc->kpage[new_page], size); | ||
| 336 | |||
| 337 | ibc->last_copied_page = pg_idx; | ||
| 338 | ibc->kpage_idx[new_page] = pg_idx; | ||
| 339 | |||
| 340 | return new_page; | ||
| 341 | } | ||
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index daf5db780956..ec835d56d30a 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -532,10 +532,13 @@ int radeon_device_init(struct radeon_device *rdev, | |||
| 532 | 532 | ||
| 533 | if (radeon_agpmode == -1) { | 533 | if (radeon_agpmode == -1) { |
| 534 | rdev->flags &= ~RADEON_IS_AGP; | 534 | rdev->flags &= ~RADEON_IS_AGP; |
| 535 | if (rdev->family >= CHIP_RV515 || | 535 | if (rdev->family >= CHIP_R600) { |
| 536 | rdev->family == CHIP_RV380 || | 536 | DRM_INFO("Forcing AGP to PCIE mode\n"); |
| 537 | rdev->family == CHIP_RV410 || | 537 | rdev->flags |= RADEON_IS_PCIE; |
| 538 | rdev->family == CHIP_R423) { | 538 | } else if (rdev->family >= CHIP_RV515 || |
| 539 | rdev->family == CHIP_RV380 || | ||
| 540 | rdev->family == CHIP_RV410 || | ||
| 541 | rdev->family == CHIP_R423) { | ||
| 539 | DRM_INFO("Forcing AGP to PCIE mode\n"); | 542 | DRM_INFO("Forcing AGP to PCIE mode\n"); |
| 540 | rdev->flags |= RADEON_IS_PCIE; | 543 | rdev->flags |= RADEON_IS_PCIE; |
| 541 | rdev->asic->gart_init = &rv370_pcie_gart_init; | 544 | rdev->asic->gart_init = &rv370_pcie_gart_init; |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 50fce498910c..7f50fb864af8 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
| @@ -62,9 +62,6 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev); | |||
| 62 | int radeon_driver_irq_postinstall_kms(struct drm_device *dev); | 62 | int radeon_driver_irq_postinstall_kms(struct drm_device *dev); |
| 63 | void radeon_driver_irq_uninstall_kms(struct drm_device *dev); | 63 | void radeon_driver_irq_uninstall_kms(struct drm_device *dev); |
| 64 | irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS); | 64 | irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS); |
| 65 | int radeon_master_create_kms(struct drm_device *dev, struct drm_master *master); | ||
| 66 | void radeon_master_destroy_kms(struct drm_device *dev, | ||
| 67 | struct drm_master *master); | ||
| 68 | int radeon_dma_ioctl_kms(struct drm_device *dev, void *data, | 65 | int radeon_dma_ioctl_kms(struct drm_device *dev, void *data, |
| 69 | struct drm_file *file_priv); | 66 | struct drm_file *file_priv); |
| 70 | int radeon_gem_object_init(struct drm_gem_object *obj); | 67 | int radeon_gem_object_init(struct drm_gem_object *obj); |
| @@ -260,8 +257,6 @@ static struct drm_driver kms_driver = { | |||
| 260 | .get_vblank_counter = radeon_get_vblank_counter_kms, | 257 | .get_vblank_counter = radeon_get_vblank_counter_kms, |
| 261 | .enable_vblank = radeon_enable_vblank_kms, | 258 | .enable_vblank = radeon_enable_vblank_kms, |
| 262 | .disable_vblank = radeon_disable_vblank_kms, | 259 | .disable_vblank = radeon_disable_vblank_kms, |
| 263 | .master_create = radeon_master_create_kms, | ||
| 264 | .master_destroy = radeon_master_destroy_kms, | ||
| 265 | #if defined(CONFIG_DEBUG_FS) | 260 | #if defined(CONFIG_DEBUG_FS) |
| 266 | .debugfs_init = radeon_debugfs_init, | 261 | .debugfs_init = radeon_debugfs_init, |
| 267 | .debugfs_cleanup = radeon_debugfs_cleanup, | 262 | .debugfs_cleanup = radeon_debugfs_cleanup, |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 944e4fa78db5..1ba704eedefb 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
| @@ -128,6 +128,7 @@ static struct drm_fb_helper_funcs radeon_fb_helper_funcs = { | |||
| 128 | int radeonfb_create(struct drm_device *dev, | 128 | int radeonfb_create(struct drm_device *dev, |
| 129 | uint32_t fb_width, uint32_t fb_height, | 129 | uint32_t fb_width, uint32_t fb_height, |
| 130 | uint32_t surface_width, uint32_t surface_height, | 130 | uint32_t surface_width, uint32_t surface_height, |
| 131 | uint32_t surface_depth, uint32_t surface_bpp, | ||
| 131 | struct drm_framebuffer **fb_p) | 132 | struct drm_framebuffer **fb_p) |
| 132 | { | 133 | { |
| 133 | struct radeon_device *rdev = dev->dev_private; | 134 | struct radeon_device *rdev = dev->dev_private; |
| @@ -148,10 +149,10 @@ int radeonfb_create(struct drm_device *dev, | |||
| 148 | 149 | ||
| 149 | mode_cmd.width = surface_width; | 150 | mode_cmd.width = surface_width; |
| 150 | mode_cmd.height = surface_height; | 151 | mode_cmd.height = surface_height; |
| 151 | mode_cmd.bpp = 32; | 152 | mode_cmd.bpp = surface_bpp; |
| 152 | /* need to align pitch with crtc limits */ | 153 | /* need to align pitch with crtc limits */ |
| 153 | mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp, fb_tiled) * ((mode_cmd.bpp + 1) / 8); | 154 | mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp, fb_tiled) * ((mode_cmd.bpp + 1) / 8); |
| 154 | mode_cmd.depth = 24; | 155 | mode_cmd.depth = surface_depth; |
| 155 | 156 | ||
| 156 | size = mode_cmd.pitch * mode_cmd.height; | 157 | size = mode_cmd.pitch * mode_cmd.height; |
| 157 | aligned_size = ALIGN(size, PAGE_SIZE); | 158 | aligned_size = ALIGN(size, PAGE_SIZE); |
| @@ -290,13 +291,26 @@ out: | |||
| 290 | return ret; | 291 | return ret; |
| 291 | } | 292 | } |
| 292 | 293 | ||
| 294 | static char *mode_option; | ||
| 295 | int radeon_parse_options(char *options) | ||
| 296 | { | ||
| 297 | char *this_opt; | ||
| 298 | |||
| 299 | if (!options || !*options) | ||
| 300 | return 0; | ||
| 301 | |||
| 302 | while ((this_opt = strsep(&options, ",")) != NULL) { | ||
| 303 | if (!*this_opt) | ||
| 304 | continue; | ||
| 305 | mode_option = this_opt; | ||
| 306 | } | ||
| 307 | return 0; | ||
| 308 | } | ||
| 309 | |||
| 293 | int radeonfb_probe(struct drm_device *dev) | 310 | int radeonfb_probe(struct drm_device *dev) |
| 294 | { | 311 | { |
| 295 | int ret; | 312 | return drm_fb_helper_single_fb_probe(dev, &radeonfb_create); |
| 296 | ret = drm_fb_helper_single_fb_probe(dev, &radeonfb_create); | ||
| 297 | return ret; | ||
| 298 | } | 313 | } |
| 299 | EXPORT_SYMBOL(radeonfb_probe); | ||
| 300 | 314 | ||
| 301 | int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) | 315 | int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) |
| 302 | { | 316 | { |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 709bd892b3a9..ba128621057a 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
| @@ -201,55 +201,6 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) | |||
| 201 | 201 | ||
| 202 | 202 | ||
| 203 | /* | 203 | /* |
| 204 | * For multiple master (like multiple X). | ||
| 205 | */ | ||
| 206 | struct drm_radeon_master_private { | ||
| 207 | drm_local_map_t *sarea; | ||
| 208 | drm_radeon_sarea_t *sarea_priv; | ||
| 209 | }; | ||
| 210 | |||
| 211 | int radeon_master_create_kms(struct drm_device *dev, struct drm_master *master) | ||
| 212 | { | ||
| 213 | struct drm_radeon_master_private *master_priv; | ||
| 214 | unsigned long sareapage; | ||
| 215 | int ret; | ||
| 216 | |||
| 217 | master_priv = kzalloc(sizeof(*master_priv), GFP_KERNEL); | ||
| 218 | if (master_priv == NULL) { | ||
| 219 | return -ENOMEM; | ||
| 220 | } | ||
| 221 | /* prebuild the SAREA */ | ||
| 222 | sareapage = max_t(unsigned long, SAREA_MAX, PAGE_SIZE); | ||
| 223 | ret = drm_addmap(dev, 0, sareapage, _DRM_SHM, | ||
| 224 | _DRM_CONTAINS_LOCK, | ||
| 225 | &master_priv->sarea); | ||
| 226 | if (ret) { | ||
| 227 | DRM_ERROR("SAREA setup failed\n"); | ||
| 228 | return ret; | ||
| 229 | } | ||
| 230 | master_priv->sarea_priv = master_priv->sarea->handle + sizeof(struct drm_sarea); | ||
| 231 | master_priv->sarea_priv->pfCurrentPage = 0; | ||
| 232 | master->driver_priv = master_priv; | ||
| 233 | return 0; | ||
| 234 | } | ||
| 235 | |||
| 236 | void radeon_master_destroy_kms(struct drm_device *dev, | ||
| 237 | struct drm_master *master) | ||
| 238 | { | ||
| 239 | struct drm_radeon_master_private *master_priv = master->driver_priv; | ||
| 240 | |||
| 241 | if (master_priv == NULL) { | ||
| 242 | return; | ||
| 243 | } | ||
| 244 | if (master_priv->sarea) { | ||
| 245 | drm_rmmap_locked(dev, master_priv->sarea); | ||
| 246 | } | ||
| 247 | kfree(master_priv); | ||
| 248 | master->driver_priv = NULL; | ||
| 249 | } | ||
| 250 | |||
| 251 | |||
| 252 | /* | ||
| 253 | * IOCTL. | 204 | * IOCTL. |
| 254 | */ | 205 | */ |
| 255 | int radeon_dma_ioctl_kms(struct drm_device *dev, void *data, | 206 | int radeon_dma_ioctl_kms(struct drm_device *dev, void *data, |
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index 21da871a793c..bfa1ab9c93e1 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h | |||
| @@ -3333,6 +3333,7 @@ | |||
| 3333 | # define RADEON_CP_PACKET_MAX_DWORDS (1 << 12) | 3333 | # define RADEON_CP_PACKET_MAX_DWORDS (1 << 12) |
| 3334 | # define RADEON_CP_PACKET0_REG_MASK 0x000007ff | 3334 | # define RADEON_CP_PACKET0_REG_MASK 0x000007ff |
| 3335 | # define R300_CP_PACKET0_REG_MASK 0x00001fff | 3335 | # define R300_CP_PACKET0_REG_MASK 0x00001fff |
| 3336 | # define R600_CP_PACKET0_REG_MASK 0x0000ffff | ||
| 3336 | # define RADEON_CP_PACKET1_REG0_MASK 0x000007ff | 3337 | # define RADEON_CP_PACKET1_REG0_MASK 0x000007ff |
| 3337 | # define RADEON_CP_PACKET1_REG1_MASK 0x003ff800 | 3338 | # define RADEON_CP_PACKET1_REG1_MASK 0x003ff800 |
| 3338 | 3339 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 5b1cf04a011a..765bd184b6fc 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
| @@ -689,9 +689,6 @@ struct ttm_backend *radeon_ttm_backend_create(struct radeon_device *rdev) | |||
| 689 | 689 | ||
| 690 | #define RADEON_DEBUGFS_MEM_TYPES 2 | 690 | #define RADEON_DEBUGFS_MEM_TYPES 2 |
| 691 | 691 | ||
| 692 | static struct drm_info_list radeon_mem_types_list[RADEON_DEBUGFS_MEM_TYPES]; | ||
| 693 | static char radeon_mem_types_names[RADEON_DEBUGFS_MEM_TYPES][32]; | ||
| 694 | |||
| 695 | #if defined(CONFIG_DEBUG_FS) | 692 | #if defined(CONFIG_DEBUG_FS) |
| 696 | static int radeon_mm_dump_table(struct seq_file *m, void *data) | 693 | static int radeon_mm_dump_table(struct seq_file *m, void *data) |
| 697 | { | 694 | { |
| @@ -711,9 +708,11 @@ static int radeon_mm_dump_table(struct seq_file *m, void *data) | |||
| 711 | 708 | ||
| 712 | static int radeon_ttm_debugfs_init(struct radeon_device *rdev) | 709 | static int radeon_ttm_debugfs_init(struct radeon_device *rdev) |
| 713 | { | 710 | { |
| 711 | #if defined(CONFIG_DEBUG_FS) | ||
| 712 | static struct drm_info_list radeon_mem_types_list[RADEON_DEBUGFS_MEM_TYPES]; | ||
| 713 | static char radeon_mem_types_names[RADEON_DEBUGFS_MEM_TYPES][32]; | ||
| 714 | unsigned i; | 714 | unsigned i; |
| 715 | 715 | ||
| 716 | #if defined(CONFIG_DEBUG_FS) | ||
| 717 | for (i = 0; i < RADEON_DEBUGFS_MEM_TYPES; i++) { | 716 | for (i = 0; i < RADEON_DEBUGFS_MEM_TYPES; i++) { |
| 718 | if (i == 0) | 717 | if (i == 0) |
| 719 | sprintf(radeon_mem_types_names[i], "radeon_vram_mm"); | 718 | sprintf(radeon_mem_types_names[i], "radeon_vram_mm"); |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 0e791e26def3..4a4fe1cb131c 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
| @@ -28,7 +28,6 @@ | |||
| 28 | #include "drmP.h" | 28 | #include "drmP.h" |
| 29 | #include "radeon_reg.h" | 29 | #include "radeon_reg.h" |
| 30 | #include "radeon.h" | 30 | #include "radeon.h" |
| 31 | #include "avivod.h" | ||
| 32 | 31 | ||
| 33 | #include "rs600_reg_safe.h" | 32 | #include "rs600_reg_safe.h" |
| 34 | 33 | ||
| @@ -45,7 +44,6 @@ void r420_pipes_init(struct radeon_device *rdev); | |||
| 45 | */ | 44 | */ |
| 46 | void rs600_gpu_init(struct radeon_device *rdev); | 45 | void rs600_gpu_init(struct radeon_device *rdev); |
| 47 | int rs600_mc_wait_for_idle(struct radeon_device *rdev); | 46 | int rs600_mc_wait_for_idle(struct radeon_device *rdev); |
| 48 | void rs600_disable_vga(struct radeon_device *rdev); | ||
| 49 | 47 | ||
| 50 | 48 | ||
| 51 | /* | 49 | /* |
| @@ -198,7 +196,7 @@ void rs600_mc_disable_clients(struct radeon_device *rdev) | |||
| 198 | "programming pipes. Bad things might happen.\n"); | 196 | "programming pipes. Bad things might happen.\n"); |
| 199 | } | 197 | } |
| 200 | 198 | ||
| 201 | radeon_avivo_vga_render_disable(rdev); | 199 | rv515_vga_render_disable(rdev); |
| 202 | 200 | ||
| 203 | tmp = RREG32(AVIVO_D1VGA_CONTROL); | 201 | tmp = RREG32(AVIVO_D1VGA_CONTROL); |
| 204 | WREG32(AVIVO_D1VGA_CONTROL, tmp & ~AVIVO_DVGA_CONTROL_MODE_ENABLE); | 202 | 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) | |||
| 346 | /* | 344 | /* |
| 347 | * Global GPU functions | 345 | * Global GPU functions |
| 348 | */ | 346 | */ |
| 349 | void rs600_disable_vga(struct radeon_device *rdev) | ||
| 350 | { | ||
| 351 | unsigned tmp; | ||
| 352 | |||
| 353 | WREG32(0x330, 0); | ||
| 354 | WREG32(0x338, 0); | ||
| 355 | tmp = RREG32(0x300); | ||
| 356 | tmp &= ~(3 << 16); | ||
| 357 | WREG32(0x300, tmp); | ||
| 358 | WREG32(0x308, (1 << 8)); | ||
| 359 | WREG32(0x310, rdev->mc.vram_location); | ||
| 360 | WREG32(0x594, 0); | ||
| 361 | } | ||
| 362 | |||
| 363 | int rs600_mc_wait_for_idle(struct radeon_device *rdev) | 347 | int rs600_mc_wait_for_idle(struct radeon_device *rdev) |
| 364 | { | 348 | { |
| 365 | unsigned i; | 349 | unsigned i; |
| @@ -385,7 +369,7 @@ void rs600_gpu_init(struct radeon_device *rdev) | |||
| 385 | { | 369 | { |
| 386 | /* FIXME: HDP same place on rs600 ? */ | 370 | /* FIXME: HDP same place on rs600 ? */ |
| 387 | r100_hdp_reset(rdev); | 371 | r100_hdp_reset(rdev); |
| 388 | rs600_disable_vga(rdev); | 372 | rv515_vga_render_disable(rdev); |
| 389 | /* FIXME: is this correct ? */ | 373 | /* FIXME: is this correct ? */ |
| 390 | r420_pipes_init(rdev); | 374 | r420_pipes_init(rdev); |
| 391 | if (rs600_mc_wait_for_idle(rdev)) { | 375 | if (rs600_mc_wait_for_idle(rdev)) { |
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 0f585ca8276d..7a0098ddf977 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c | |||
| @@ -40,7 +40,6 @@ void rs400_gart_disable(struct radeon_device *rdev); | |||
| 40 | int rs400_gart_enable(struct radeon_device *rdev); | 40 | int rs400_gart_enable(struct radeon_device *rdev); |
| 41 | void rs400_gart_adjust_size(struct radeon_device *rdev); | 41 | void rs400_gart_adjust_size(struct radeon_device *rdev); |
| 42 | void rs600_mc_disable_clients(struct radeon_device *rdev); | 42 | void rs600_mc_disable_clients(struct radeon_device *rdev); |
| 43 | void rs600_disable_vga(struct radeon_device *rdev); | ||
| 44 | 43 | ||
| 45 | /* This files gather functions specifics to : | 44 | /* This files gather functions specifics to : |
| 46 | * rs690,rs740 | 45 | * rs690,rs740 |
| @@ -125,7 +124,7 @@ void rs690_gpu_init(struct radeon_device *rdev) | |||
| 125 | { | 124 | { |
| 126 | /* FIXME: HDP same place on rs690 ? */ | 125 | /* FIXME: HDP same place on rs690 ? */ |
| 127 | r100_hdp_reset(rdev); | 126 | r100_hdp_reset(rdev); |
| 128 | rs600_disable_vga(rdev); | 127 | rv515_vga_render_disable(rdev); |
| 129 | /* FIXME: is this correct ? */ | 128 | /* FIXME: is this correct ? */ |
| 130 | r420_pipes_init(rdev); | 129 | r420_pipes_init(rdev); |
| 131 | if (rs690_mc_wait_for_idle(rdev)) { | 130 | if (rs690_mc_wait_for_idle(rdev)) { |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index fd799748e7d8..e53b5ca7a253 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
| @@ -29,37 +29,17 @@ | |||
| 29 | #include "drmP.h" | 29 | #include "drmP.h" |
| 30 | #include "rv515d.h" | 30 | #include "rv515d.h" |
| 31 | #include "radeon.h" | 31 | #include "radeon.h" |
| 32 | 32 | #include "atom.h" | |
| 33 | #include "rv515_reg_safe.h" | 33 | #include "rv515_reg_safe.h" |
| 34 | /* rv515 depends on : */ | 34 | |
| 35 | void r100_hdp_reset(struct radeon_device *rdev); | 35 | /* This files gather functions specifics to: rv515 */ |
| 36 | int r100_cp_reset(struct radeon_device *rdev); | ||
| 37 | int r100_rb2d_reset(struct radeon_device *rdev); | ||
| 38 | int r100_gui_wait_for_idle(struct radeon_device *rdev); | ||
| 39 | int r100_cp_init(struct radeon_device *rdev, unsigned ring_size); | ||
| 40 | void r420_pipes_init(struct radeon_device *rdev); | ||
| 41 | void rs600_mc_disable_clients(struct radeon_device *rdev); | ||
| 42 | void rs600_disable_vga(struct radeon_device *rdev); | ||
| 43 | |||
| 44 | /* This files gather functions specifics to: | ||
| 45 | * rv515 | ||
| 46 | * | ||
| 47 | * Some of these functions might be used by newer ASICs. | ||
| 48 | */ | ||
| 49 | int rv515_debugfs_pipes_info_init(struct radeon_device *rdev); | 36 | int rv515_debugfs_pipes_info_init(struct radeon_device *rdev); |
| 50 | int rv515_debugfs_ga_info_init(struct radeon_device *rdev); | 37 | int rv515_debugfs_ga_info_init(struct radeon_device *rdev); |
| 51 | void rv515_gpu_init(struct radeon_device *rdev); | 38 | void rv515_gpu_init(struct radeon_device *rdev); |
| 52 | int rv515_mc_wait_for_idle(struct radeon_device *rdev); | 39 | int rv515_mc_wait_for_idle(struct radeon_device *rdev); |
| 53 | 40 | ||
| 54 | 41 | void rv515_debugfs(struct radeon_device *rdev) | |
| 55 | /* | ||
| 56 | * MC | ||
| 57 | */ | ||
| 58 | int rv515_mc_init(struct radeon_device *rdev) | ||
| 59 | { | 42 | { |
| 60 | uint32_t tmp; | ||
| 61 | int r; | ||
| 62 | |||
| 63 | if (r100_debugfs_rbbm_init(rdev)) { | 43 | if (r100_debugfs_rbbm_init(rdev)) { |
| 64 | DRM_ERROR("Failed to register debugfs file for RBBM !\n"); | 44 | DRM_ERROR("Failed to register debugfs file for RBBM !\n"); |
| 65 | } | 45 | } |
| @@ -69,67 +49,8 @@ int rv515_mc_init(struct radeon_device *rdev) | |||
| 69 | if (rv515_debugfs_ga_info_init(rdev)) { | 49 | if (rv515_debugfs_ga_info_init(rdev)) { |
| 70 | DRM_ERROR("Failed to register debugfs file for pipes !\n"); | 50 | DRM_ERROR("Failed to register debugfs file for pipes !\n"); |
| 71 | } | 51 | } |
| 72 | |||
| 73 | rv515_gpu_init(rdev); | ||
| 74 | rv370_pcie_gart_disable(rdev); | ||
| 75 | |||
| 76 | /* Setup GPU memory space */ | ||
| 77 | rdev->mc.vram_location = 0xFFFFFFFFUL; | ||
| 78 | rdev->mc.gtt_location = 0xFFFFFFFFUL; | ||
| 79 | if (rdev->flags & RADEON_IS_AGP) { | ||
| 80 | r = radeon_agp_init(rdev); | ||
| 81 | if (r) { | ||
| 82 | printk(KERN_WARNING "[drm] Disabling AGP\n"); | ||
| 83 | rdev->flags &= ~RADEON_IS_AGP; | ||
| 84 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | ||
| 85 | } else { | ||
| 86 | rdev->mc.gtt_location = rdev->mc.agp_base; | ||
| 87 | } | ||
| 88 | } | ||
| 89 | r = radeon_mc_setup(rdev); | ||
| 90 | if (r) { | ||
| 91 | return r; | ||
| 92 | } | ||
| 93 | |||
| 94 | /* Program GPU memory space */ | ||
| 95 | rs600_mc_disable_clients(rdev); | ||
| 96 | if (rv515_mc_wait_for_idle(rdev)) { | ||
| 97 | printk(KERN_WARNING "Failed to wait MC idle while " | ||
| 98 | "programming pipes. Bad things might happen.\n"); | ||
| 99 | } | ||
| 100 | /* Write VRAM size in case we are limiting it */ | ||
| 101 | WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size); | ||
| 102 | tmp = REG_SET(MC_FB_START, rdev->mc.vram_location >> 16); | ||
| 103 | WREG32(0x134, tmp); | ||
| 104 | tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; | ||
| 105 | tmp = REG_SET(MC_FB_TOP, tmp >> 16); | ||
| 106 | tmp |= REG_SET(MC_FB_START, rdev->mc.vram_location >> 16); | ||
| 107 | WREG32_MC(MC_FB_LOCATION, tmp); | ||
| 108 | WREG32(HDP_FB_LOCATION, rdev->mc.vram_location >> 16); | ||
| 109 | WREG32(0x310, rdev->mc.vram_location); | ||
| 110 | if (rdev->flags & RADEON_IS_AGP) { | ||
| 111 | tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; | ||
| 112 | tmp = REG_SET(MC_AGP_TOP, tmp >> 16); | ||
| 113 | tmp |= REG_SET(MC_AGP_START, rdev->mc.gtt_location >> 16); | ||
| 114 | WREG32_MC(MC_AGP_LOCATION, tmp); | ||
| 115 | WREG32_MC(MC_AGP_BASE, rdev->mc.agp_base); | ||
| 116 | WREG32_MC(MC_AGP_BASE_2, 0); | ||
| 117 | } else { | ||
| 118 | WREG32_MC(MC_AGP_LOCATION, 0x0FFFFFFF); | ||
| 119 | WREG32_MC(MC_AGP_BASE, 0); | ||
| 120 | WREG32_MC(MC_AGP_BASE_2, 0); | ||
| 121 | } | ||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | |||
| 125 | void rv515_mc_fini(struct radeon_device *rdev) | ||
| 126 | { | ||
| 127 | } | 52 | } |
| 128 | 53 | ||
| 129 | |||
| 130 | /* | ||
| 131 | * Global GPU functions | ||
| 132 | */ | ||
| 133 | void rv515_ring_start(struct radeon_device *rdev) | 54 | void rv515_ring_start(struct radeon_device *rdev) |
| 134 | { | 55 | { |
| 135 | int r; | 56 | int r; |
| @@ -198,11 +119,6 @@ void rv515_ring_start(struct radeon_device *rdev) | |||
| 198 | radeon_ring_unlock_commit(rdev); | 119 | radeon_ring_unlock_commit(rdev); |
| 199 | } | 120 | } |
| 200 | 121 | ||
| 201 | void rv515_errata(struct radeon_device *rdev) | ||
| 202 | { | ||
| 203 | rdev->pll_errata = 0; | ||
| 204 | } | ||
| 205 | |||
| 206 | int rv515_mc_wait_for_idle(struct radeon_device *rdev) | 122 | int rv515_mc_wait_for_idle(struct radeon_device *rdev) |
| 207 | { | 123 | { |
| 208 | unsigned i; | 124 | unsigned i; |
| @@ -219,6 +135,12 @@ int rv515_mc_wait_for_idle(struct radeon_device *rdev) | |||
| 219 | return -1; | 135 | return -1; |
| 220 | } | 136 | } |
| 221 | 137 | ||
| 138 | void rv515_vga_render_disable(struct radeon_device *rdev) | ||
| 139 | { | ||
| 140 | WREG32(R_000300_VGA_RENDER_CONTROL, | ||
| 141 | RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL); | ||
| 142 | } | ||
| 143 | |||
| 222 | void rv515_gpu_init(struct radeon_device *rdev) | 144 | void rv515_gpu_init(struct radeon_device *rdev) |
| 223 | { | 145 | { |
| 224 | unsigned pipe_select_current, gb_pipe_select, tmp; | 146 | unsigned pipe_select_current, gb_pipe_select, tmp; |
| @@ -231,7 +153,7 @@ void rv515_gpu_init(struct radeon_device *rdev) | |||
| 231 | "reseting GPU. Bad things might happen.\n"); | 153 | "reseting GPU. Bad things might happen.\n"); |
| 232 | } | 154 | } |
| 233 | 155 | ||
| 234 | rs600_disable_vga(rdev); | 156 | rv515_vga_render_disable(rdev); |
| 235 | 157 | ||
| 236 | r420_pipes_init(rdev); | 158 | r420_pipes_init(rdev); |
| 237 | gb_pipe_select = RREG32(0x402C); | 159 | gb_pipe_select = RREG32(0x402C); |
| @@ -335,10 +257,6 @@ int rv515_gpu_reset(struct radeon_device *rdev) | |||
| 335 | return 0; | 257 | return 0; |
| 336 | } | 258 | } |
| 337 | 259 | ||
| 338 | |||
| 339 | /* | ||
| 340 | * VRAM info | ||
| 341 | */ | ||
| 342 | static void rv515_vram_get_type(struct radeon_device *rdev) | 260 | static void rv515_vram_get_type(struct radeon_device *rdev) |
| 343 | { | 261 | { |
| 344 | uint32_t tmp; | 262 | uint32_t tmp; |
| @@ -374,10 +292,6 @@ void rv515_vram_info(struct radeon_device *rdev) | |||
| 374 | rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); | 292 | rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); |
| 375 | } | 293 | } |
| 376 | 294 | ||
| 377 | |||
| 378 | /* | ||
| 379 | * Indirect registers accessor | ||
| 380 | */ | ||
| 381 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg) | 295 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg) |
| 382 | { | 296 | { |
| 383 | uint32_t r; | 297 | uint32_t r; |
| @@ -395,9 +309,6 @@ void rv515_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | |||
| 395 | WREG32(MC_IND_INDEX, 0); | 309 | WREG32(MC_IND_INDEX, 0); |
| 396 | } | 310 | } |
| 397 | 311 | ||
| 398 | /* | ||
| 399 | * Debugfs info | ||
| 400 | */ | ||
| 401 | #if defined(CONFIG_DEBUG_FS) | 312 | #if defined(CONFIG_DEBUG_FS) |
| 402 | static int rv515_debugfs_pipes_info(struct seq_file *m, void *data) | 313 | static int rv515_debugfs_pipes_info(struct seq_file *m, void *data) |
| 403 | { | 314 | { |
| @@ -459,13 +370,258 @@ int rv515_debugfs_ga_info_init(struct radeon_device *rdev) | |||
| 459 | #endif | 370 | #endif |
| 460 | } | 371 | } |
| 461 | 372 | ||
| 462 | /* | 373 | void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) |
| 463 | * Asic initialization | 374 | { |
| 464 | */ | 375 | save->d1vga_control = RREG32(R_000330_D1VGA_CONTROL); |
| 465 | int rv515_init(struct radeon_device *rdev) | 376 | save->d2vga_control = RREG32(R_000338_D2VGA_CONTROL); |
| 377 | save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); | ||
| 378 | save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); | ||
| 379 | save->d1crtc_control = RREG32(R_006080_D1CRTC_CONTROL); | ||
| 380 | save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL); | ||
| 381 | |||
| 382 | /* Stop all video */ | ||
| 383 | WREG32(R_000330_D1VGA_CONTROL, 0); | ||
| 384 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | ||
| 385 | WREG32(R_000300_VGA_RENDER_CONTROL, 0); | ||
| 386 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); | ||
| 387 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); | ||
| 388 | WREG32(R_006080_D1CRTC_CONTROL, 0); | ||
| 389 | WREG32(R_006880_D2CRTC_CONTROL, 0); | ||
| 390 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); | ||
| 391 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | ||
| 392 | } | ||
| 393 | |||
| 394 | void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) | ||
| 395 | { | ||
| 396 | WREG32(R_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS, rdev->mc.vram_start); | ||
| 397 | WREG32(R_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS, rdev->mc.vram_start); | ||
| 398 | WREG32(R_006910_D2GRPH_PRIMARY_SURFACE_ADDRESS, rdev->mc.vram_start); | ||
| 399 | WREG32(R_006918_D2GRPH_SECONDARY_SURFACE_ADDRESS, rdev->mc.vram_start); | ||
| 400 | WREG32(R_000310_VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start); | ||
| 401 | /* Unlock host access */ | ||
| 402 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); | ||
| 403 | mdelay(1); | ||
| 404 | /* Restore video state */ | ||
| 405 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); | ||
| 406 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); | ||
| 407 | WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control); | ||
| 408 | WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control); | ||
| 409 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); | ||
| 410 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | ||
| 411 | WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control); | ||
| 412 | WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control); | ||
| 413 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); | ||
| 414 | } | ||
| 415 | |||
| 416 | void rv515_mc_program(struct radeon_device *rdev) | ||
| 417 | { | ||
| 418 | struct rv515_mc_save save; | ||
| 419 | |||
| 420 | /* Stops all mc clients */ | ||
| 421 | rv515_mc_stop(rdev, &save); | ||
| 422 | |||
| 423 | /* Wait for mc idle */ | ||
| 424 | if (rv515_mc_wait_for_idle(rdev)) | ||
| 425 | dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); | ||
| 426 | /* Write VRAM size in case we are limiting it */ | ||
| 427 | WREG32(R_0000F8_CONFIG_MEMSIZE, rdev->mc.real_vram_size); | ||
| 428 | /* Program MC, should be a 32bits limited address space */ | ||
| 429 | WREG32_MC(R_000001_MC_FB_LOCATION, | ||
| 430 | S_000001_MC_FB_START(rdev->mc.vram_start >> 16) | | ||
| 431 | S_000001_MC_FB_TOP(rdev->mc.vram_end >> 16)); | ||
| 432 | WREG32(R_000134_HDP_FB_LOCATION, | ||
| 433 | S_000134_HDP_FB_START(rdev->mc.vram_start >> 16)); | ||
| 434 | if (rdev->flags & RADEON_IS_AGP) { | ||
| 435 | WREG32_MC(R_000002_MC_AGP_LOCATION, | ||
| 436 | S_000002_MC_AGP_START(rdev->mc.gtt_start >> 16) | | ||
| 437 | S_000002_MC_AGP_TOP(rdev->mc.gtt_end >> 16)); | ||
| 438 | WREG32_MC(R_000003_MC_AGP_BASE, lower_32_bits(rdev->mc.agp_base)); | ||
| 439 | WREG32_MC(R_000004_MC_AGP_BASE_2, | ||
| 440 | S_000004_AGP_BASE_ADDR_2(upper_32_bits(rdev->mc.agp_base))); | ||
| 441 | } else { | ||
| 442 | WREG32_MC(R_000002_MC_AGP_LOCATION, 0xFFFFFFFF); | ||
| 443 | WREG32_MC(R_000003_MC_AGP_BASE, 0); | ||
| 444 | WREG32_MC(R_000004_MC_AGP_BASE_2, 0); | ||
| 445 | } | ||
| 446 | |||
| 447 | rv515_mc_resume(rdev, &save); | ||
| 448 | } | ||
| 449 | |||
| 450 | void rv515_clock_startup(struct radeon_device *rdev) | ||
| 451 | { | ||
| 452 | if (radeon_dynclks != -1 && radeon_dynclks) | ||
| 453 | radeon_atom_set_clock_gating(rdev, 1); | ||
| 454 | /* We need to force on some of the block */ | ||
| 455 | WREG32_PLL(R_00000F_CP_DYN_CNTL, | ||
| 456 | RREG32_PLL(R_00000F_CP_DYN_CNTL) | S_00000F_CP_FORCEON(1)); | ||
| 457 | WREG32_PLL(R_000011_E2_DYN_CNTL, | ||
| 458 | RREG32_PLL(R_000011_E2_DYN_CNTL) | S_000011_E2_FORCEON(1)); | ||
| 459 | WREG32_PLL(R_000013_IDCT_DYN_CNTL, | ||
| 460 | RREG32_PLL(R_000013_IDCT_DYN_CNTL) | S_000013_IDCT_FORCEON(1)); | ||
| 461 | } | ||
| 462 | |||
| 463 | static int rv515_startup(struct radeon_device *rdev) | ||
| 464 | { | ||
| 465 | int r; | ||
| 466 | |||
| 467 | rv515_mc_program(rdev); | ||
| 468 | /* Resume clock */ | ||
| 469 | rv515_clock_startup(rdev); | ||
| 470 | /* Initialize GPU configuration (# pipes, ...) */ | ||
| 471 | rv515_gpu_init(rdev); | ||
| 472 | /* Initialize GART (initialize after TTM so we can allocate | ||
| 473 | * memory through TTM but finalize after TTM) */ | ||
| 474 | if (rdev->flags & RADEON_IS_PCIE) { | ||
| 475 | r = rv370_pcie_gart_enable(rdev); | ||
| 476 | if (r) | ||
| 477 | return r; | ||
| 478 | } | ||
| 479 | /* Enable IRQ */ | ||
| 480 | rdev->irq.sw_int = true; | ||
| 481 | r100_irq_set(rdev); | ||
| 482 | /* 1M ring buffer */ | ||
| 483 | r = r100_cp_init(rdev, 1024 * 1024); | ||
| 484 | if (r) { | ||
| 485 | dev_err(rdev->dev, "failled initializing CP (%d).\n", r); | ||
| 486 | return r; | ||
| 487 | } | ||
| 488 | r = r100_wb_init(rdev); | ||
| 489 | if (r) | ||
| 490 | dev_err(rdev->dev, "failled initializing WB (%d).\n", r); | ||
| 491 | r = r100_ib_init(rdev); | ||
| 492 | if (r) { | ||
| 493 | dev_err(rdev->dev, "failled initializing IB (%d).\n", r); | ||
| 494 | return r; | ||
| 495 | } | ||
| 496 | return 0; | ||
| 497 | } | ||
| 498 | |||
| 499 | int rv515_resume(struct radeon_device *rdev) | ||
| 500 | { | ||
| 501 | /* Make sur GART are not working */ | ||
| 502 | if (rdev->flags & RADEON_IS_PCIE) | ||
| 503 | rv370_pcie_gart_disable(rdev); | ||
| 504 | /* Resume clock before doing reset */ | ||
| 505 | rv515_clock_startup(rdev); | ||
| 506 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | ||
| 507 | if (radeon_gpu_reset(rdev)) { | ||
| 508 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | ||
| 509 | RREG32(R_000E40_RBBM_STATUS), | ||
| 510 | RREG32(R_0007C0_CP_STAT)); | ||
| 511 | } | ||
| 512 | /* post */ | ||
| 513 | atom_asic_init(rdev->mode_info.atom_context); | ||
| 514 | /* Resume clock after posting */ | ||
| 515 | rv515_clock_startup(rdev); | ||
| 516 | return rv515_startup(rdev); | ||
| 517 | } | ||
| 518 | |||
| 519 | int rv515_suspend(struct radeon_device *rdev) | ||
| 520 | { | ||
| 521 | r100_cp_disable(rdev); | ||
| 522 | r100_wb_disable(rdev); | ||
| 523 | r100_irq_disable(rdev); | ||
| 524 | if (rdev->flags & RADEON_IS_PCIE) | ||
| 525 | rv370_pcie_gart_disable(rdev); | ||
| 526 | return 0; | ||
| 527 | } | ||
| 528 | |||
| 529 | void rv515_set_safe_registers(struct radeon_device *rdev) | ||
| 466 | { | 530 | { |
| 467 | rdev->config.r300.reg_safe_bm = rv515_reg_safe_bm; | 531 | rdev->config.r300.reg_safe_bm = rv515_reg_safe_bm; |
| 468 | rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rv515_reg_safe_bm); | 532 | rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rv515_reg_safe_bm); |
| 533 | } | ||
| 534 | |||
| 535 | void rv515_fini(struct radeon_device *rdev) | ||
| 536 | { | ||
| 537 | rv515_suspend(rdev); | ||
| 538 | r100_cp_fini(rdev); | ||
| 539 | r100_wb_fini(rdev); | ||
| 540 | r100_ib_fini(rdev); | ||
| 541 | radeon_gem_fini(rdev); | ||
| 542 | rv370_pcie_gart_fini(rdev); | ||
| 543 | radeon_agp_fini(rdev); | ||
| 544 | radeon_irq_kms_fini(rdev); | ||
| 545 | radeon_fence_driver_fini(rdev); | ||
| 546 | radeon_object_fini(rdev); | ||
| 547 | radeon_atombios_fini(rdev); | ||
| 548 | kfree(rdev->bios); | ||
| 549 | rdev->bios = NULL; | ||
| 550 | } | ||
| 551 | |||
| 552 | int rv515_init(struct radeon_device *rdev) | ||
| 553 | { | ||
| 554 | int r; | ||
| 555 | |||
| 556 | rdev->new_init_path = true; | ||
| 557 | /* Initialize scratch registers */ | ||
| 558 | radeon_scratch_init(rdev); | ||
| 559 | /* Initialize surface registers */ | ||
| 560 | radeon_surface_init(rdev); | ||
| 561 | /* TODO: disable VGA need to use VGA request */ | ||
| 562 | /* BIOS*/ | ||
| 563 | if (!radeon_get_bios(rdev)) { | ||
| 564 | if (ASIC_IS_AVIVO(rdev)) | ||
| 565 | return -EINVAL; | ||
| 566 | } | ||
| 567 | if (rdev->is_atom_bios) { | ||
| 568 | r = radeon_atombios_init(rdev); | ||
| 569 | if (r) | ||
| 570 | return r; | ||
| 571 | } else { | ||
| 572 | dev_err(rdev->dev, "Expecting atombios for RV515 GPU\n"); | ||
| 573 | return -EINVAL; | ||
| 574 | } | ||
| 575 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | ||
| 576 | if (radeon_gpu_reset(rdev)) { | ||
| 577 | dev_warn(rdev->dev, | ||
| 578 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | ||
| 579 | RREG32(R_000E40_RBBM_STATUS), | ||
| 580 | RREG32(R_0007C0_CP_STAT)); | ||
| 581 | } | ||
| 582 | /* check if cards are posted or not */ | ||
| 583 | if (!radeon_card_posted(rdev) && rdev->bios) { | ||
| 584 | DRM_INFO("GPU not posted. posting now...\n"); | ||
| 585 | atom_asic_init(rdev->mode_info.atom_context); | ||
| 586 | } | ||
| 587 | /* Initialize clocks */ | ||
| 588 | radeon_get_clock_info(rdev->ddev); | ||
| 589 | /* Get vram informations */ | ||
| 590 | rv515_vram_info(rdev); | ||
| 591 | /* Initialize memory controller (also test AGP) */ | ||
| 592 | r = r420_mc_init(rdev); | ||
| 593 | if (r) | ||
| 594 | return r; | ||
| 595 | rv515_debugfs(rdev); | ||
| 596 | /* Fence driver */ | ||
| 597 | r = radeon_fence_driver_init(rdev); | ||
| 598 | if (r) | ||
| 599 | return r; | ||
| 600 | r = radeon_irq_kms_init(rdev); | ||
| 601 | if (r) | ||
| 602 | return r; | ||
| 603 | /* Memory manager */ | ||
| 604 | r = radeon_object_init(rdev); | ||
| 605 | if (r) | ||
| 606 | return r; | ||
| 607 | r = rv370_pcie_gart_init(rdev); | ||
| 608 | if (r) | ||
| 609 | return r; | ||
| 610 | rv515_set_safe_registers(rdev); | ||
| 611 | rdev->accel_working = true; | ||
| 612 | r = rv515_startup(rdev); | ||
| 613 | if (r) { | ||
| 614 | /* Somethings want wront with the accel init stop accel */ | ||
| 615 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | ||
| 616 | rv515_suspend(rdev); | ||
| 617 | r100_cp_fini(rdev); | ||
| 618 | r100_wb_fini(rdev); | ||
| 619 | r100_ib_fini(rdev); | ||
| 620 | rv370_pcie_gart_fini(rdev); | ||
| 621 | radeon_agp_fini(rdev); | ||
| 622 | radeon_irq_kms_fini(rdev); | ||
| 623 | rdev->accel_working = false; | ||
| 624 | } | ||
| 469 | return 0; | 625 | return 0; |
| 470 | } | 626 | } |
| 471 | 627 | ||
diff --git a/drivers/gpu/drm/radeon/rv515d.h b/drivers/gpu/drm/radeon/rv515d.h index a65e17ec1c08..fc216e49384d 100644 --- a/drivers/gpu/drm/radeon/rv515d.h +++ b/drivers/gpu/drm/radeon/rv515d.h | |||
| @@ -216,5 +216,388 @@ | |||
| 216 | #define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) | 216 | #define CP_PACKET0_GET_ONE_REG_WR(h) (((h) >> 15) & 1) |
| 217 | #define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) | 217 | #define CP_PACKET3_GET_OPCODE(h) (((h) >> 8) & 0xFF) |
| 218 | 218 | ||
| 219 | #endif | 219 | /* Registers */ |
| 220 | #define R_0000F8_CONFIG_MEMSIZE 0x0000F8 | ||
| 221 | #define S_0000F8_CONFIG_MEMSIZE(x) (((x) & 0xFFFFFFFF) << 0) | ||
| 222 | #define G_0000F8_CONFIG_MEMSIZE(x) (((x) >> 0) & 0xFFFFFFFF) | ||
| 223 | #define C_0000F8_CONFIG_MEMSIZE 0x00000000 | ||
| 224 | #define R_000134_HDP_FB_LOCATION 0x000134 | ||
| 225 | #define S_000134_HDP_FB_START(x) (((x) & 0xFFFF) << 0) | ||
| 226 | #define G_000134_HDP_FB_START(x) (((x) >> 0) & 0xFFFF) | ||
| 227 | #define C_000134_HDP_FB_START 0xFFFF0000 | ||
| 228 | #define R_000300_VGA_RENDER_CONTROL 0x000300 | ||
| 229 | #define S_000300_VGA_BLINK_RATE(x) (((x) & 0x1F) << 0) | ||
| 230 | #define G_000300_VGA_BLINK_RATE(x) (((x) >> 0) & 0x1F) | ||
| 231 | #define C_000300_VGA_BLINK_RATE 0xFFFFFFE0 | ||
| 232 | #define S_000300_VGA_BLINK_MODE(x) (((x) & 0x3) << 5) | ||
| 233 | #define G_000300_VGA_BLINK_MODE(x) (((x) >> 5) & 0x3) | ||
| 234 | #define C_000300_VGA_BLINK_MODE 0xFFFFFF9F | ||
| 235 | #define S_000300_VGA_CURSOR_BLINK_INVERT(x) (((x) & 0x1) << 7) | ||
| 236 | #define G_000300_VGA_CURSOR_BLINK_INVERT(x) (((x) >> 7) & 0x1) | ||
| 237 | #define C_000300_VGA_CURSOR_BLINK_INVERT 0xFFFFFF7F | ||
| 238 | #define S_000300_VGA_EXTD_ADDR_COUNT_ENABLE(x) (((x) & 0x1) << 8) | ||
| 239 | #define G_000300_VGA_EXTD_ADDR_COUNT_ENABLE(x) (((x) >> 8) & 0x1) | ||
| 240 | #define C_000300_VGA_EXTD_ADDR_COUNT_ENABLE 0xFFFFFEFF | ||
| 241 | #define S_000300_VGA_VSTATUS_CNTL(x) (((x) & 0x3) << 16) | ||
| 242 | #define G_000300_VGA_VSTATUS_CNTL(x) (((x) >> 16) & 0x3) | ||
| 243 | #define C_000300_VGA_VSTATUS_CNTL 0xFFFCFFFF | ||
| 244 | #define S_000300_VGA_LOCK_8DOT(x) (((x) & 0x1) << 24) | ||
| 245 | #define G_000300_VGA_LOCK_8DOT(x) (((x) >> 24) & 0x1) | ||
| 246 | #define C_000300_VGA_LOCK_8DOT 0xFEFFFFFF | ||
| 247 | #define S_000300_VGAREG_LINECMP_COMPATIBILITY_SEL(x) (((x) & 0x1) << 25) | ||
| 248 | #define G_000300_VGAREG_LINECMP_COMPATIBILITY_SEL(x) (((x) >> 25) & 0x1) | ||
| 249 | #define C_000300_VGAREG_LINECMP_COMPATIBILITY_SEL 0xFDFFFFFF | ||
| 250 | #define R_000310_VGA_MEMORY_BASE_ADDRESS 0x000310 | ||
| 251 | #define S_000310_VGA_MEMORY_BASE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) | ||
| 252 | #define G_000310_VGA_MEMORY_BASE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) | ||
| 253 | #define C_000310_VGA_MEMORY_BASE_ADDRESS 0x00000000 | ||
| 254 | #define R_000328_VGA_HDP_CONTROL 0x000328 | ||
| 255 | #define S_000328_VGA_MEM_PAGE_SELECT_EN(x) (((x) & 0x1) << 0) | ||
| 256 | #define G_000328_VGA_MEM_PAGE_SELECT_EN(x) (((x) >> 0) & 0x1) | ||
| 257 | #define C_000328_VGA_MEM_PAGE_SELECT_EN 0xFFFFFFFE | ||
| 258 | #define S_000328_VGA_RBBM_LOCK_DISABLE(x) (((x) & 0x1) << 8) | ||
| 259 | #define G_000328_VGA_RBBM_LOCK_DISABLE(x) (((x) >> 8) & 0x1) | ||
| 260 | #define C_000328_VGA_RBBM_LOCK_DISABLE 0xFFFFFEFF | ||
| 261 | #define S_000328_VGA_SOFT_RESET(x) (((x) & 0x1) << 16) | ||
| 262 | #define G_000328_VGA_SOFT_RESET(x) (((x) >> 16) & 0x1) | ||
| 263 | #define C_000328_VGA_SOFT_RESET 0xFFFEFFFF | ||
| 264 | #define S_000328_VGA_TEST_RESET_CONTROL(x) (((x) & 0x1) << 24) | ||
| 265 | #define G_000328_VGA_TEST_RESET_CONTROL(x) (((x) >> 24) & 0x1) | ||
| 266 | #define C_000328_VGA_TEST_RESET_CONTROL 0xFEFFFFFF | ||
| 267 | #define R_000330_D1VGA_CONTROL 0x000330 | ||
| 268 | #define S_000330_D1VGA_MODE_ENABLE(x) (((x) & 0x1) << 0) | ||
| 269 | #define G_000330_D1VGA_MODE_ENABLE(x) (((x) >> 0) & 0x1) | ||
| 270 | #define C_000330_D1VGA_MODE_ENABLE 0xFFFFFFFE | ||
| 271 | #define S_000330_D1VGA_TIMING_SELECT(x) (((x) & 0x1) << 8) | ||
| 272 | #define G_000330_D1VGA_TIMING_SELECT(x) (((x) >> 8) & 0x1) | ||
| 273 | #define C_000330_D1VGA_TIMING_SELECT 0xFFFFFEFF | ||
| 274 | #define S_000330_D1VGA_SYNC_POLARITY_SELECT(x) (((x) & 0x1) << 9) | ||
| 275 | #define G_000330_D1VGA_SYNC_POLARITY_SELECT(x) (((x) >> 9) & 0x1) | ||
| 276 | #define C_000330_D1VGA_SYNC_POLARITY_SELECT 0xFFFFFDFF | ||
| 277 | #define S_000330_D1VGA_OVERSCAN_TIMING_SELECT(x) (((x) & 0x1) << 10) | ||
| 278 | #define G_000330_D1VGA_OVERSCAN_TIMING_SELECT(x) (((x) >> 10) & 0x1) | ||
| 279 | #define C_000330_D1VGA_OVERSCAN_TIMING_SELECT 0xFFFFFBFF | ||
| 280 | #define S_000330_D1VGA_OVERSCAN_COLOR_EN(x) (((x) & 0x1) << 16) | ||
| 281 | #define G_000330_D1VGA_OVERSCAN_COLOR_EN(x) (((x) >> 16) & 0x1) | ||
| 282 | #define C_000330_D1VGA_OVERSCAN_COLOR_EN 0xFFFEFFFF | ||
| 283 | #define S_000330_D1VGA_ROTATE(x) (((x) & 0x3) << 24) | ||
| 284 | #define G_000330_D1VGA_ROTATE(x) (((x) >> 24) & 0x3) | ||
| 285 | #define C_000330_D1VGA_ROTATE 0xFCFFFFFF | ||
| 286 | #define R_000338_D2VGA_CONTROL 0x000338 | ||
| 287 | #define S_000338_D2VGA_MODE_ENABLE(x) (((x) & 0x1) << 0) | ||
| 288 | #define G_000338_D2VGA_MODE_ENABLE(x) (((x) >> 0) & 0x1) | ||
| 289 | #define C_000338_D2VGA_MODE_ENABLE 0xFFFFFFFE | ||
| 290 | #define S_000338_D2VGA_TIMING_SELECT(x) (((x) & 0x1) << 8) | ||
| 291 | #define G_000338_D2VGA_TIMING_SELECT(x) (((x) >> 8) & 0x1) | ||
| 292 | #define C_000338_D2VGA_TIMING_SELECT 0xFFFFFEFF | ||
| 293 | #define S_000338_D2VGA_SYNC_POLARITY_SELECT(x) (((x) & 0x1) << 9) | ||
| 294 | #define G_000338_D2VGA_SYNC_POLARITY_SELECT(x) (((x) >> 9) & 0x1) | ||
| 295 | #define C_000338_D2VGA_SYNC_POLARITY_SELECT 0xFFFFFDFF | ||
| 296 | #define S_000338_D2VGA_OVERSCAN_TIMING_SELECT(x) (((x) & 0x1) << 10) | ||
| 297 | #define G_000338_D2VGA_OVERSCAN_TIMING_SELECT(x) (((x) >> 10) & 0x1) | ||
| 298 | #define C_000338_D2VGA_OVERSCAN_TIMING_SELECT 0xFFFFFBFF | ||
| 299 | #define S_000338_D2VGA_OVERSCAN_COLOR_EN(x) (((x) & 0x1) << 16) | ||
| 300 | #define G_000338_D2VGA_OVERSCAN_COLOR_EN(x) (((x) >> 16) & 0x1) | ||
| 301 | #define C_000338_D2VGA_OVERSCAN_COLOR_EN 0xFFFEFFFF | ||
| 302 | #define S_000338_D2VGA_ROTATE(x) (((x) & 0x3) << 24) | ||
| 303 | #define G_000338_D2VGA_ROTATE(x) (((x) >> 24) & 0x3) | ||
| 304 | #define C_000338_D2VGA_ROTATE 0xFCFFFFFF | ||
| 305 | #define R_0007C0_CP_STAT 0x0007C0 | ||
| 306 | #define S_0007C0_MRU_BUSY(x) (((x) & 0x1) << 0) | ||
| 307 | #define G_0007C0_MRU_BUSY(x) (((x) >> 0) & 0x1) | ||
| 308 | #define C_0007C0_MRU_BUSY 0xFFFFFFFE | ||
| 309 | #define S_0007C0_MWU_BUSY(x) (((x) & 0x1) << 1) | ||
| 310 | #define G_0007C0_MWU_BUSY(x) (((x) >> 1) & 0x1) | ||
| 311 | #define C_0007C0_MWU_BUSY 0xFFFFFFFD | ||
| 312 | #define S_0007C0_RSIU_BUSY(x) (((x) & 0x1) << 2) | ||
| 313 | #define G_0007C0_RSIU_BUSY(x) (((x) >> 2) & 0x1) | ||
| 314 | #define C_0007C0_RSIU_BUSY 0xFFFFFFFB | ||
| 315 | #define S_0007C0_RCIU_BUSY(x) (((x) & 0x1) << 3) | ||
| 316 | #define G_0007C0_RCIU_BUSY(x) (((x) >> 3) & 0x1) | ||
| 317 | #define C_0007C0_RCIU_BUSY 0xFFFFFFF7 | ||
| 318 | #define S_0007C0_CSF_PRIMARY_BUSY(x) (((x) & 0x1) << 9) | ||
| 319 | #define G_0007C0_CSF_PRIMARY_BUSY(x) (((x) >> 9) & 0x1) | ||
| 320 | #define C_0007C0_CSF_PRIMARY_BUSY 0xFFFFFDFF | ||
| 321 | #define S_0007C0_CSF_INDIRECT_BUSY(x) (((x) & 0x1) << 10) | ||
| 322 | #define G_0007C0_CSF_INDIRECT_BUSY(x) (((x) >> 10) & 0x1) | ||
| 323 | #define C_0007C0_CSF_INDIRECT_BUSY 0xFFFFFBFF | ||
| 324 | #define S_0007C0_CSQ_PRIMARY_BUSY(x) (((x) & 0x1) << 11) | ||
| 325 | #define G_0007C0_CSQ_PRIMARY_BUSY(x) (((x) >> 11) & 0x1) | ||
| 326 | #define C_0007C0_CSQ_PRIMARY_BUSY 0xFFFFF7FF | ||
| 327 | #define S_0007C0_CSQ_INDIRECT_BUSY(x) (((x) & 0x1) << 12) | ||
| 328 | #define G_0007C0_CSQ_INDIRECT_BUSY(x) (((x) >> 12) & 0x1) | ||
| 329 | #define C_0007C0_CSQ_INDIRECT_BUSY 0xFFFFEFFF | ||
| 330 | #define S_0007C0_CSI_BUSY(x) (((x) & 0x1) << 13) | ||
| 331 | #define G_0007C0_CSI_BUSY(x) (((x) >> 13) & 0x1) | ||
| 332 | #define C_0007C0_CSI_BUSY 0xFFFFDFFF | ||
| 333 | #define S_0007C0_CSF_INDIRECT2_BUSY(x) (((x) & 0x1) << 14) | ||
| 334 | #define G_0007C0_CSF_INDIRECT2_BUSY(x) (((x) >> 14) & 0x1) | ||
| 335 | #define C_0007C0_CSF_INDIRECT2_BUSY 0xFFFFBFFF | ||
| 336 | #define S_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) & 0x1) << 15) | ||
| 337 | #define G_0007C0_CSQ_INDIRECT2_BUSY(x) (((x) >> 15) & 0x1) | ||
| 338 | #define C_0007C0_CSQ_INDIRECT2_BUSY 0xFFFF7FFF | ||
| 339 | #define S_0007C0_GUIDMA_BUSY(x) (((x) & 0x1) << 28) | ||
| 340 | #define G_0007C0_GUIDMA_BUSY(x) (((x) >> 28) & 0x1) | ||
| 341 | #define C_0007C0_GUIDMA_BUSY 0xEFFFFFFF | ||
| 342 | #define S_0007C0_VIDDMA_BUSY(x) (((x) & 0x1) << 29) | ||
| 343 | #define G_0007C0_VIDDMA_BUSY(x) (((x) >> 29) & 0x1) | ||
| 344 | #define C_0007C0_VIDDMA_BUSY 0xDFFFFFFF | ||
| 345 | #define S_0007C0_CMDSTRM_BUSY(x) (((x) & 0x1) << 30) | ||
| 346 | #define G_0007C0_CMDSTRM_BUSY(x) (((x) >> 30) & 0x1) | ||
| 347 | #define C_0007C0_CMDSTRM_BUSY 0xBFFFFFFF | ||
| 348 | #define S_0007C0_CP_BUSY(x) (((x) & 0x1) << 31) | ||
| 349 | #define G_0007C0_CP_BUSY(x) (((x) >> 31) & 0x1) | ||
| 350 | #define C_0007C0_CP_BUSY 0x7FFFFFFF | ||
| 351 | #define R_000E40_RBBM_STATUS 0x000E40 | ||
| 352 | #define S_000E40_CMDFIFO_AVAIL(x) (((x) & 0x7F) << 0) | ||
| 353 | #define G_000E40_CMDFIFO_AVAIL(x) (((x) >> 0) & 0x7F) | ||
| 354 | #define C_000E40_CMDFIFO_AVAIL 0xFFFFFF80 | ||
| 355 | #define S_000E40_HIRQ_ON_RBB(x) (((x) & 0x1) << 8) | ||
| 356 | #define G_000E40_HIRQ_ON_RBB(x) (((x) >> 8) & 0x1) | ||
| 357 | #define C_000E40_HIRQ_ON_RBB 0xFFFFFEFF | ||
| 358 | #define S_000E40_CPRQ_ON_RBB(x) (((x) & 0x1) << 9) | ||
| 359 | #define G_000E40_CPRQ_ON_RBB(x) (((x) >> 9) & 0x1) | ||
| 360 | #define C_000E40_CPRQ_ON_RBB 0xFFFFFDFF | ||
| 361 | #define S_000E40_CFRQ_ON_RBB(x) (((x) & 0x1) << 10) | ||
| 362 | #define G_000E40_CFRQ_ON_RBB(x) (((x) >> 10) & 0x1) | ||
| 363 | #define C_000E40_CFRQ_ON_RBB 0xFFFFFBFF | ||
| 364 | #define S_000E40_HIRQ_IN_RTBUF(x) (((x) & 0x1) << 11) | ||
| 365 | #define G_000E40_HIRQ_IN_RTBUF(x) (((x) >> 11) & 0x1) | ||
| 366 | #define C_000E40_HIRQ_IN_RTBUF 0xFFFFF7FF | ||
| 367 | #define S_000E40_CPRQ_IN_RTBUF(x) (((x) & 0x1) << 12) | ||
| 368 | #define G_000E40_CPRQ_IN_RTBUF(x) (((x) >> 12) & 0x1) | ||
| 369 | #define C_000E40_CPRQ_IN_RTBUF 0xFFFFEFFF | ||
| 370 | #define S_000E40_CFRQ_IN_RTBUF(x) (((x) & 0x1) << 13) | ||
| 371 | #define G_000E40_CFRQ_IN_RTBUF(x) (((x) >> 13) & 0x1) | ||
| 372 | #define C_000E40_CFRQ_IN_RTBUF 0xFFFFDFFF | ||
| 373 | #define S_000E40_CF_PIPE_BUSY(x) (((x) & 0x1) << 14) | ||
| 374 | #define G_000E40_CF_PIPE_BUSY(x) (((x) >> 14) & 0x1) | ||
| 375 | #define C_000E40_CF_PIPE_BUSY 0xFFFFBFFF | ||
| 376 | #define S_000E40_ENG_EV_BUSY(x) (((x) & 0x1) << 15) | ||
| 377 | #define G_000E40_ENG_EV_BUSY(x) (((x) >> 15) & 0x1) | ||
| 378 | #define C_000E40_ENG_EV_BUSY 0xFFFF7FFF | ||
| 379 | #define S_000E40_CP_CMDSTRM_BUSY(x) (((x) & 0x1) << 16) | ||
| 380 | #define G_000E40_CP_CMDSTRM_BUSY(x) (((x) >> 16) & 0x1) | ||
| 381 | #define C_000E40_CP_CMDSTRM_BUSY 0xFFFEFFFF | ||
| 382 | #define S_000E40_E2_BUSY(x) (((x) & 0x1) << 17) | ||
| 383 | #define G_000E40_E2_BUSY(x) (((x) >> 17) & 0x1) | ||
| 384 | #define C_000E40_E2_BUSY 0xFFFDFFFF | ||
| 385 | #define S_000E40_RB2D_BUSY(x) (((x) & 0x1) << 18) | ||
| 386 | #define G_000E40_RB2D_BUSY(x) (((x) >> 18) & 0x1) | ||
| 387 | #define C_000E40_RB2D_BUSY 0xFFFBFFFF | ||
| 388 | #define S_000E40_RB3D_BUSY(x) (((x) & 0x1) << 19) | ||
| 389 | #define G_000E40_RB3D_BUSY(x) (((x) >> 19) & 0x1) | ||
| 390 | #define C_000E40_RB3D_BUSY 0xFFF7FFFF | ||
| 391 | #define S_000E40_VAP_BUSY(x) (((x) & 0x1) << 20) | ||
| 392 | #define G_000E40_VAP_BUSY(x) (((x) >> 20) & 0x1) | ||
| 393 | #define C_000E40_VAP_BUSY 0xFFEFFFFF | ||
| 394 | #define S_000E40_RE_BUSY(x) (((x) & 0x1) << 21) | ||
| 395 | #define G_000E40_RE_BUSY(x) (((x) >> 21) & 0x1) | ||
| 396 | #define C_000E40_RE_BUSY 0xFFDFFFFF | ||
| 397 | #define S_000E40_TAM_BUSY(x) (((x) & 0x1) << 22) | ||
| 398 | #define G_000E40_TAM_BUSY(x) (((x) >> 22) & 0x1) | ||
| 399 | #define C_000E40_TAM_BUSY 0xFFBFFFFF | ||
| 400 | #define S_000E40_TDM_BUSY(x) (((x) & 0x1) << 23) | ||
| 401 | #define G_000E40_TDM_BUSY(x) (((x) >> 23) & 0x1) | ||
| 402 | #define C_000E40_TDM_BUSY 0xFF7FFFFF | ||
| 403 | #define S_000E40_PB_BUSY(x) (((x) & 0x1) << 24) | ||
| 404 | #define G_000E40_PB_BUSY(x) (((x) >> 24) & 0x1) | ||
| 405 | #define C_000E40_PB_BUSY 0xFEFFFFFF | ||
| 406 | #define S_000E40_TIM_BUSY(x) (((x) & 0x1) << 25) | ||
| 407 | #define G_000E40_TIM_BUSY(x) (((x) >> 25) & 0x1) | ||
| 408 | #define C_000E40_TIM_BUSY 0xFDFFFFFF | ||
| 409 | #define S_000E40_GA_BUSY(x) (((x) & 0x1) << 26) | ||
| 410 | #define G_000E40_GA_BUSY(x) (((x) >> 26) & 0x1) | ||
| 411 | #define C_000E40_GA_BUSY 0xFBFFFFFF | ||
| 412 | #define S_000E40_CBA2D_BUSY(x) (((x) & 0x1) << 27) | ||
| 413 | #define G_000E40_CBA2D_BUSY(x) (((x) >> 27) & 0x1) | ||
| 414 | #define C_000E40_CBA2D_BUSY 0xF7FFFFFF | ||
| 415 | #define S_000E40_RBBM_HIBUSY(x) (((x) & 0x1) << 28) | ||
| 416 | #define G_000E40_RBBM_HIBUSY(x) (((x) >> 28) & 0x1) | ||
| 417 | #define C_000E40_RBBM_HIBUSY 0xEFFFFFFF | ||
| 418 | #define S_000E40_SKID_CFBUSY(x) (((x) & 0x1) << 29) | ||
| 419 | #define G_000E40_SKID_CFBUSY(x) (((x) >> 29) & 0x1) | ||
| 420 | #define C_000E40_SKID_CFBUSY 0xDFFFFFFF | ||
| 421 | #define S_000E40_VAP_VF_BUSY(x) (((x) & 0x1) << 30) | ||
| 422 | #define G_000E40_VAP_VF_BUSY(x) (((x) >> 30) & 0x1) | ||
| 423 | #define C_000E40_VAP_VF_BUSY 0xBFFFFFFF | ||
| 424 | #define S_000E40_GUI_ACTIVE(x) (((x) & 0x1) << 31) | ||
| 425 | #define G_000E40_GUI_ACTIVE(x) (((x) >> 31) & 0x1) | ||
| 426 | #define C_000E40_GUI_ACTIVE 0x7FFFFFFF | ||
| 427 | #define R_006080_D1CRTC_CONTROL 0x006080 | ||
| 428 | #define S_006080_D1CRTC_MASTER_EN(x) (((x) & 0x1) << 0) | ||
| 429 | #define G_006080_D1CRTC_MASTER_EN(x) (((x) >> 0) & 0x1) | ||
| 430 | #define C_006080_D1CRTC_MASTER_EN 0xFFFFFFFE | ||
| 431 | #define S_006080_D1CRTC_SYNC_RESET_SEL(x) (((x) & 0x1) << 4) | ||
| 432 | #define G_006080_D1CRTC_SYNC_RESET_SEL(x) (((x) >> 4) & 0x1) | ||
| 433 | #define C_006080_D1CRTC_SYNC_RESET_SEL 0xFFFFFFEF | ||
| 434 | #define S_006080_D1CRTC_DISABLE_POINT_CNTL(x) (((x) & 0x3) << 8) | ||
| 435 | #define G_006080_D1CRTC_DISABLE_POINT_CNTL(x) (((x) >> 8) & 0x3) | ||
| 436 | #define C_006080_D1CRTC_DISABLE_POINT_CNTL 0xFFFFFCFF | ||
| 437 | #define S_006080_D1CRTC_CURRENT_MASTER_EN_STATE(x) (((x) & 0x1) << 16) | ||
| 438 | #define G_006080_D1CRTC_CURRENT_MASTER_EN_STATE(x) (((x) >> 16) & 0x1) | ||
| 439 | #define C_006080_D1CRTC_CURRENT_MASTER_EN_STATE 0xFFFEFFFF | ||
| 440 | #define S_006080_D1CRTC_DISP_READ_REQUEST_DISABLE(x) (((x) & 0x1) << 24) | ||
| 441 | #define G_006080_D1CRTC_DISP_READ_REQUEST_DISABLE(x) (((x) >> 24) & 0x1) | ||
| 442 | #define C_006080_D1CRTC_DISP_READ_REQUEST_DISABLE 0xFEFFFFFF | ||
| 443 | #define R_0060E8_D1CRTC_UPDATE_LOCK 0x0060E8 | ||
| 444 | #define S_0060E8_D1CRTC_UPDATE_LOCK(x) (((x) & 0x1) << 0) | ||
| 445 | #define G_0060E8_D1CRTC_UPDATE_LOCK(x) (((x) >> 0) & 0x1) | ||
| 446 | #define C_0060E8_D1CRTC_UPDATE_LOCK 0xFFFFFFFE | ||
| 447 | #define R_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x006110 | ||
| 448 | #define S_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) | ||
| 449 | #define G_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) | ||
| 450 | #define C_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS 0x00000000 | ||
| 451 | #define R_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS 0x006118 | ||
| 452 | #define S_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) | ||
| 453 | #define G_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) | ||
| 454 | #define C_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS 0x00000000 | ||
| 455 | #define R_006880_D2CRTC_CONTROL 0x006880 | ||
| 456 | #define S_006880_D2CRTC_MASTER_EN(x) (((x) & 0x1) << 0) | ||
| 457 | #define G_006880_D2CRTC_MASTER_EN(x) (((x) >> 0) & 0x1) | ||
| 458 | #define C_006880_D2CRTC_MASTER_EN 0xFFFFFFFE | ||
| 459 | #define S_006880_D2CRTC_SYNC_RESET_SEL(x) (((x) & 0x1) << 4) | ||
| 460 | #define G_006880_D2CRTC_SYNC_RESET_SEL(x) (((x) >> 4) & 0x1) | ||
| 461 | #define C_006880_D2CRTC_SYNC_RESET_SEL 0xFFFFFFEF | ||
| 462 | #define S_006880_D2CRTC_DISABLE_POINT_CNTL(x) (((x) & 0x3) << 8) | ||
| 463 | #define G_006880_D2CRTC_DISABLE_POINT_CNTL(x) (((x) >> 8) & 0x3) | ||
| 464 | #define C_006880_D2CRTC_DISABLE_POINT_CNTL 0xFFFFFCFF | ||
| 465 | #define S_006880_D2CRTC_CURRENT_MASTER_EN_STATE(x) (((x) & 0x1) << 16) | ||
| 466 | #define G_006880_D2CRTC_CURRENT_MASTER_EN_STATE(x) (((x) >> 16) & 0x1) | ||
| 467 | #define C_006880_D2CRTC_CURRENT_MASTER_EN_STATE 0xFFFEFFFF | ||
| 468 | #define S_006880_D2CRTC_DISP_READ_REQUEST_DISABLE(x) (((x) & 0x1) << 24) | ||
| 469 | #define G_006880_D2CRTC_DISP_READ_REQUEST_DISABLE(x) (((x) >> 24) & 0x1) | ||
| 470 | #define C_006880_D2CRTC_DISP_READ_REQUEST_DISABLE 0xFEFFFFFF | ||
| 471 | #define R_0068E8_D2CRTC_UPDATE_LOCK 0x0068E8 | ||
| 472 | #define S_0068E8_D2CRTC_UPDATE_LOCK(x) (((x) & 0x1) << 0) | ||
| 473 | #define G_0068E8_D2CRTC_UPDATE_LOCK(x) (((x) >> 0) & 0x1) | ||
| 474 | #define C_0068E8_D2CRTC_UPDATE_LOCK 0xFFFFFFFE | ||
| 475 | #define R_006910_D2GRPH_PRIMARY_SURFACE_ADDRESS 0x006910 | ||
| 476 | #define S_006910_D2GRPH_PRIMARY_SURFACE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) | ||
| 477 | #define G_006910_D2GRPH_PRIMARY_SURFACE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) | ||
| 478 | #define C_006910_D2GRPH_PRIMARY_SURFACE_ADDRESS 0x00000000 | ||
| 479 | #define R_006918_D2GRPH_SECONDARY_SURFACE_ADDRESS 0x006918 | ||
| 480 | #define S_006918_D2GRPH_SECONDARY_SURFACE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) | ||
| 481 | #define G_006918_D2GRPH_SECONDARY_SURFACE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) | ||
| 482 | #define C_006918_D2GRPH_SECONDARY_SURFACE_ADDRESS 0x00000000 | ||
| 483 | |||
| 484 | |||
| 485 | #define R_000001_MC_FB_LOCATION 0x000001 | ||
| 486 | #define S_000001_MC_FB_START(x) (((x) & 0xFFFF) << 0) | ||
| 487 | #define G_000001_MC_FB_START(x) (((x) >> 0) & 0xFFFF) | ||
| 488 | #define C_000001_MC_FB_START 0xFFFF0000 | ||
| 489 | #define S_000001_MC_FB_TOP(x) (((x) & 0xFFFF) << 16) | ||
| 490 | #define G_000001_MC_FB_TOP(x) (((x) >> 16) & 0xFFFF) | ||
| 491 | #define C_000001_MC_FB_TOP 0x0000FFFF | ||
| 492 | #define R_000002_MC_AGP_LOCATION 0x000002 | ||
| 493 | #define S_000002_MC_AGP_START(x) (((x) & 0xFFFF) << 0) | ||
| 494 | #define G_000002_MC_AGP_START(x) (((x) >> 0) & 0xFFFF) | ||
| 495 | #define C_000002_MC_AGP_START 0xFFFF0000 | ||
| 496 | #define S_000002_MC_AGP_TOP(x) (((x) & 0xFFFF) << 16) | ||
| 497 | #define G_000002_MC_AGP_TOP(x) (((x) >> 16) & 0xFFFF) | ||
| 498 | #define C_000002_MC_AGP_TOP 0x0000FFFF | ||
| 499 | #define R_000003_MC_AGP_BASE 0x000003 | ||
| 500 | #define S_000003_AGP_BASE_ADDR(x) (((x) & 0xFFFFFFFF) << 0) | ||
| 501 | #define G_000003_AGP_BASE_ADDR(x) (((x) >> 0) & 0xFFFFFFFF) | ||
| 502 | #define C_000003_AGP_BASE_ADDR 0x00000000 | ||
| 503 | #define R_000004_MC_AGP_BASE_2 0x000004 | ||
| 504 | #define S_000004_AGP_BASE_ADDR_2(x) (((x) & 0xF) << 0) | ||
| 505 | #define G_000004_AGP_BASE_ADDR_2(x) (((x) >> 0) & 0xF) | ||
| 506 | #define C_000004_AGP_BASE_ADDR_2 0xFFFFFFF0 | ||
| 220 | 507 | ||
| 508 | |||
| 509 | #define R_00000F_CP_DYN_CNTL 0x00000F | ||
| 510 | #define S_00000F_CP_FORCEON(x) (((x) & 0x1) << 0) | ||
| 511 | #define G_00000F_CP_FORCEON(x) (((x) >> 0) & 0x1) | ||
| 512 | #define C_00000F_CP_FORCEON 0xFFFFFFFE | ||
| 513 | #define S_00000F_CP_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 1) | ||
| 514 | #define G_00000F_CP_MAX_DYN_STOP_LAT(x) (((x) >> 1) & 0x1) | ||
| 515 | #define C_00000F_CP_MAX_DYN_STOP_LAT 0xFFFFFFFD | ||
| 516 | #define S_00000F_CP_CLOCK_STATUS(x) (((x) & 0x1) << 2) | ||
| 517 | #define G_00000F_CP_CLOCK_STATUS(x) (((x) >> 2) & 0x1) | ||
| 518 | #define C_00000F_CP_CLOCK_STATUS 0xFFFFFFFB | ||
| 519 | #define S_00000F_CP_PROG_SHUTOFF(x) (((x) & 0x1) << 3) | ||
| 520 | #define G_00000F_CP_PROG_SHUTOFF(x) (((x) >> 3) & 0x1) | ||
| 521 | #define C_00000F_CP_PROG_SHUTOFF 0xFFFFFFF7 | ||
| 522 | #define S_00000F_CP_PROG_DELAY_VALUE(x) (((x) & 0xFF) << 4) | ||
| 523 | #define G_00000F_CP_PROG_DELAY_VALUE(x) (((x) >> 4) & 0xFF) | ||
| 524 | #define C_00000F_CP_PROG_DELAY_VALUE 0xFFFFF00F | ||
| 525 | #define S_00000F_CP_LOWER_POWER_IDLE(x) (((x) & 0xFF) << 12) | ||
| 526 | #define G_00000F_CP_LOWER_POWER_IDLE(x) (((x) >> 12) & 0xFF) | ||
| 527 | #define C_00000F_CP_LOWER_POWER_IDLE 0xFFF00FFF | ||
| 528 | #define S_00000F_CP_LOWER_POWER_IGNORE(x) (((x) & 0x1) << 20) | ||
| 529 | #define G_00000F_CP_LOWER_POWER_IGNORE(x) (((x) >> 20) & 0x1) | ||
| 530 | #define C_00000F_CP_LOWER_POWER_IGNORE 0xFFEFFFFF | ||
| 531 | #define S_00000F_CP_NORMAL_POWER_IGNORE(x) (((x) & 0x1) << 21) | ||
| 532 | #define G_00000F_CP_NORMAL_POWER_IGNORE(x) (((x) >> 21) & 0x1) | ||
| 533 | #define C_00000F_CP_NORMAL_POWER_IGNORE 0xFFDFFFFF | ||
| 534 | #define S_00000F_SPARE(x) (((x) & 0x3) << 22) | ||
| 535 | #define G_00000F_SPARE(x) (((x) >> 22) & 0x3) | ||
| 536 | #define C_00000F_SPARE 0xFF3FFFFF | ||
| 537 | #define S_00000F_CP_NORMAL_POWER_BUSY(x) (((x) & 0xFF) << 24) | ||
| 538 | #define G_00000F_CP_NORMAL_POWER_BUSY(x) (((x) >> 24) & 0xFF) | ||
| 539 | #define C_00000F_CP_NORMAL_POWER_BUSY 0x00FFFFFF | ||
| 540 | #define R_000011_E2_DYN_CNTL 0x000011 | ||
| 541 | #define S_000011_E2_FORCEON(x) (((x) & 0x1) << 0) | ||
| 542 | #define G_000011_E2_FORCEON(x) (((x) >> 0) & 0x1) | ||
| 543 | #define C_000011_E2_FORCEON 0xFFFFFFFE | ||
| 544 | #define S_000011_E2_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 1) | ||
| 545 | #define G_000011_E2_MAX_DYN_STOP_LAT(x) (((x) >> 1) & 0x1) | ||
| 546 | #define C_000011_E2_MAX_DYN_STOP_LAT 0xFFFFFFFD | ||
| 547 | #define S_000011_E2_CLOCK_STATUS(x) (((x) & 0x1) << 2) | ||
| 548 | #define G_000011_E2_CLOCK_STATUS(x) (((x) >> 2) & 0x1) | ||
| 549 | #define C_000011_E2_CLOCK_STATUS 0xFFFFFFFB | ||
| 550 | #define S_000011_E2_PROG_SHUTOFF(x) (((x) & 0x1) << 3) | ||
| 551 | #define G_000011_E2_PROG_SHUTOFF(x) (((x) >> 3) & 0x1) | ||
| 552 | #define C_000011_E2_PROG_SHUTOFF 0xFFFFFFF7 | ||
| 553 | #define S_000011_E2_PROG_DELAY_VALUE(x) (((x) & 0xFF) << 4) | ||
| 554 | #define G_000011_E2_PROG_DELAY_VALUE(x) (((x) >> 4) & 0xFF) | ||
| 555 | #define C_000011_E2_PROG_DELAY_VALUE 0xFFFFF00F | ||
| 556 | #define S_000011_E2_LOWER_POWER_IDLE(x) (((x) & 0xFF) << 12) | ||
| 557 | #define G_000011_E2_LOWER_POWER_IDLE(x) (((x) >> 12) & 0xFF) | ||
| 558 | #define C_000011_E2_LOWER_POWER_IDLE 0xFFF00FFF | ||
| 559 | #define S_000011_E2_LOWER_POWER_IGNORE(x) (((x) & 0x1) << 20) | ||
| 560 | #define G_000011_E2_LOWER_POWER_IGNORE(x) (((x) >> 20) & 0x1) | ||
| 561 | #define C_000011_E2_LOWER_POWER_IGNORE 0xFFEFFFFF | ||
| 562 | #define S_000011_E2_NORMAL_POWER_IGNORE(x) (((x) & 0x1) << 21) | ||
| 563 | #define G_000011_E2_NORMAL_POWER_IGNORE(x) (((x) >> 21) & 0x1) | ||
| 564 | #define C_000011_E2_NORMAL_POWER_IGNORE 0xFFDFFFFF | ||
| 565 | #define S_000011_SPARE(x) (((x) & 0x3) << 22) | ||
| 566 | #define G_000011_SPARE(x) (((x) >> 22) & 0x3) | ||
| 567 | #define C_000011_SPARE 0xFF3FFFFF | ||
| 568 | #define S_000011_E2_NORMAL_POWER_BUSY(x) (((x) & 0xFF) << 24) | ||
| 569 | #define G_000011_E2_NORMAL_POWER_BUSY(x) (((x) >> 24) & 0xFF) | ||
| 570 | #define C_000011_E2_NORMAL_POWER_BUSY 0x00FFFFFF | ||
| 571 | #define R_000013_IDCT_DYN_CNTL 0x000013 | ||
| 572 | #define S_000013_IDCT_FORCEON(x) (((x) & 0x1) << 0) | ||
| 573 | #define G_000013_IDCT_FORCEON(x) (((x) >> 0) & 0x1) | ||
| 574 | #define C_000013_IDCT_FORCEON 0xFFFFFFFE | ||
| 575 | #define S_000013_IDCT_MAX_DYN_STOP_LAT(x) (((x) & 0x1) << 1) | ||
| 576 | #define G_000013_IDCT_MAX_DYN_STOP_LAT(x) (((x) >> 1) & 0x1) | ||
| 577 | #define C_000013_IDCT_MAX_DYN_STOP_LAT 0xFFFFFFFD | ||
| 578 | #define S_000013_IDCT_CLOCK_STATUS(x) (((x) & 0x1) << 2) | ||
| 579 | #define G_000013_IDCT_CLOCK_STATUS(x) (((x) >> 2) & 0x1) | ||
| 580 | #define C_000013_IDCT_CLOCK_STATUS 0xFFFFFFFB | ||
| 581 | #define S_000013_IDCT_PROG_SHUTOFF(x) (((x) & 0x1) << 3) | ||
| 582 | #define G_000013_IDCT_PROG_SHUTOFF(x) (((x) >> 3) & 0x1) | ||
| 583 | #define C_000013_IDCT_PROG_SHUTOFF 0xFFFFFFF7 | ||
| 584 | #define S_000013_IDCT_PROG_DELAY_VALUE(x) (((x) & 0xFF) << 4) | ||
| 585 | #define G_000013_IDCT_PROG_DELAY_VALUE(x) (((x) >> 4) & 0xFF) | ||
| 586 | #define C_000013_IDCT_PROG_DELAY_VALUE 0xFFFFF00F | ||
| 587 | #define S_000013_IDCT_LOWER_POWER_IDLE(x) (((x) & 0xFF) << 12) | ||
| 588 | #define G_000013_IDCT_LOWER_POWER_IDLE(x) (((x) >> 12) & 0xFF) | ||
| 589 | #define C_000013_IDCT_LOWER_POWER_IDLE 0xFFF00FFF | ||
| 590 | #define S_000013_IDCT_LOWER_POWER_IGNORE(x) (((x) & 0x1) << 20) | ||
| 591 | #define G_000013_IDCT_LOWER_POWER_IGNORE(x) (((x) >> 20) & 0x1) | ||
| 592 | #define C_000013_IDCT_LOWER_POWER_IGNORE 0xFFEFFFFF | ||
| 593 | #define S_000013_IDCT_NORMAL_POWER_IGNORE(x) (((x) & 0x1) << 21) | ||
| 594 | #define G_000013_IDCT_NORMAL_POWER_IGNORE(x) (((x) >> 21) & 0x1) | ||
| 595 | #define C_000013_IDCT_NORMAL_POWER_IGNORE 0xFFDFFFFF | ||
| 596 | #define S_000013_SPARE(x) (((x) & 0x3) << 22) | ||
| 597 | #define G_000013_SPARE(x) (((x) >> 22) & 0x3) | ||
| 598 | #define C_000013_SPARE 0xFF3FFFFF | ||
| 599 | #define S_000013_IDCT_NORMAL_POWER_BUSY(x) (((x) & 0xFF) << 24) | ||
| 600 | #define G_000013_IDCT_NORMAL_POWER_BUSY(x) (((x) >> 24) & 0xFF) | ||
| 601 | #define C_000013_IDCT_NORMAL_POWER_BUSY 0x00FFFFFF | ||
| 602 | |||
| 603 | #endif | ||
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index b574c73a5109..e0b97d161397 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
| @@ -31,8 +31,8 @@ | |||
| 31 | #include "radeon.h" | 31 | #include "radeon.h" |
| 32 | #include "radeon_drm.h" | 32 | #include "radeon_drm.h" |
| 33 | #include "rv770d.h" | 33 | #include "rv770d.h" |
| 34 | #include "avivod.h" | ||
| 35 | #include "atom.h" | 34 | #include "atom.h" |
| 35 | #include "avivod.h" | ||
| 36 | 36 | ||
| 37 | #define R700_PFP_UCODE_SIZE 848 | 37 | #define R700_PFP_UCODE_SIZE 848 |
| 38 | #define R700_PM4_UCODE_SIZE 1360 | 38 | #define R700_PM4_UCODE_SIZE 1360 |
| @@ -231,7 +231,7 @@ static void rv770_mc_resume(struct radeon_device *rdev) | |||
| 231 | 231 | ||
| 232 | /* we need to own VRAM, so turn off the VGA renderer here | 232 | /* we need to own VRAM, so turn off the VGA renderer here |
| 233 | * to stop it overwriting our objects */ | 233 | * to stop it overwriting our objects */ |
| 234 | radeon_avivo_vga_render_disable(rdev); | 234 | rv515_vga_render_disable(rdev); |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | 237 | ||
| @@ -801,6 +801,13 @@ int rv770_mc_init(struct radeon_device *rdev) | |||
| 801 | /* Setup GPU memory space */ | 801 | /* Setup GPU memory space */ |
| 802 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); | 802 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); |
| 803 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | 803 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); |
| 804 | |||
| 805 | if (rdev->mc.mc_vram_size > rdev->mc.aper_size) | ||
| 806 | rdev->mc.mc_vram_size = rdev->mc.aper_size; | ||
| 807 | |||
| 808 | if (rdev->mc.real_vram_size > rdev->mc.aper_size) | ||
| 809 | rdev->mc.real_vram_size = rdev->mc.aper_size; | ||
| 810 | |||
| 804 | if (rdev->flags & RADEON_IS_AGP) { | 811 | if (rdev->flags & RADEON_IS_AGP) { |
| 805 | r = radeon_agp_init(rdev); | 812 | r = radeon_agp_init(rdev); |
| 806 | if (r) | 813 | if (r) |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index a1f2e7ce730b..99bbd282ce63 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
| @@ -1800,7 +1800,7 @@ static int __init video_setup(char *options) | |||
| 1800 | global = 1; | 1800 | global = 1; |
| 1801 | } | 1801 | } |
| 1802 | 1802 | ||
| 1803 | if (!global && !strstr(options, "fb:")) { | 1803 | if (!global && !strchr(options, ':')) { |
| 1804 | fb_mode_option = options; | 1804 | fb_mode_option = options; |
| 1805 | global = 1; | 1805 | global = 1; |
| 1806 | } | 1806 | } |
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index ae1e9e166959..b69347b8904f 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
| @@ -387,6 +387,7 @@ struct drm_crtc { | |||
| 387 | * @get_modes: get mode list for this connector | 387 | * @get_modes: get mode list for this connector |
| 388 | * @set_property: property for this connector may need update | 388 | * @set_property: property for this connector may need update |
| 389 | * @destroy: make object go away | 389 | * @destroy: make object go away |
| 390 | * @force: notify the driver the connector is forced on | ||
| 390 | * | 391 | * |
| 391 | * Each CRTC may have one or more connectors attached to it. The functions | 392 | * Each CRTC may have one or more connectors attached to it. The functions |
| 392 | * below allow the core DRM code to control connectors, enumerate available modes, | 393 | * below allow the core DRM code to control connectors, enumerate available modes, |
| @@ -401,6 +402,7 @@ struct drm_connector_funcs { | |||
| 401 | int (*set_property)(struct drm_connector *connector, struct drm_property *property, | 402 | int (*set_property)(struct drm_connector *connector, struct drm_property *property, |
| 402 | uint64_t val); | 403 | uint64_t val); |
| 403 | void (*destroy)(struct drm_connector *connector); | 404 | void (*destroy)(struct drm_connector *connector); |
| 405 | void (*force)(struct drm_connector *connector); | ||
| 404 | }; | 406 | }; |
| 405 | 407 | ||
| 406 | struct drm_encoder_funcs { | 408 | struct drm_encoder_funcs { |
| @@ -429,6 +431,13 @@ struct drm_encoder { | |||
| 429 | void *helper_private; | 431 | void *helper_private; |
| 430 | }; | 432 | }; |
| 431 | 433 | ||
| 434 | enum drm_connector_force { | ||
| 435 | DRM_FORCE_UNSPECIFIED, | ||
| 436 | DRM_FORCE_OFF, | ||
| 437 | DRM_FORCE_ON, /* force on analog part normally */ | ||
| 438 | DRM_FORCE_ON_DIGITAL, /* for DVI-I use digital connector */ | ||
| 439 | }; | ||
| 440 | |||
| 432 | /** | 441 | /** |
| 433 | * drm_connector - central DRM connector control structure | 442 | * drm_connector - central DRM connector control structure |
| 434 | * @crtc: CRTC this connector is currently connected to, NULL if none | 443 | * @crtc: CRTC this connector is currently connected to, NULL if none |
| @@ -478,9 +487,12 @@ struct drm_connector { | |||
| 478 | 487 | ||
| 479 | void *helper_private; | 488 | void *helper_private; |
| 480 | 489 | ||
| 490 | /* forced on connector */ | ||
| 491 | enum drm_connector_force force; | ||
| 481 | uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER]; | 492 | uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER]; |
| 482 | uint32_t force_encoder_id; | 493 | uint32_t force_encoder_id; |
| 483 | struct drm_encoder *encoder; /* currently active encoder */ | 494 | struct drm_encoder *encoder; /* currently active encoder */ |
| 495 | void *fb_helper_private; | ||
| 484 | }; | 496 | }; |
| 485 | 497 | ||
| 486 | /** | 498 | /** |
| @@ -746,7 +758,7 @@ extern int drm_mode_gamma_set_ioctl(struct drm_device *dev, | |||
| 746 | extern bool drm_detect_hdmi_monitor(struct edid *edid); | 758 | extern bool drm_detect_hdmi_monitor(struct edid *edid); |
| 747 | extern struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, | 759 | extern struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, |
| 748 | int hdisplay, int vdisplay, int vrefresh, | 760 | int hdisplay, int vdisplay, int vrefresh, |
| 749 | bool reduced, bool interlaced); | 761 | bool reduced, bool interlaced, bool margins); |
| 750 | extern struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, | 762 | extern struct drm_display_mode *drm_gtf_mode(struct drm_device *dev, |
| 751 | int hdisplay, int vdisplay, int vrefresh, | 763 | int hdisplay, int vdisplay, int vrefresh, |
| 752 | bool interlaced, int margins); | 764 | bool interlaced, int margins); |
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index 4c8dacaf4f58..ef47dfd8e5e9 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | 39 | ||
| 40 | #include <linux/fb.h> | 40 | #include <linux/fb.h> |
| 41 | 41 | ||
| 42 | #include "drm_fb_helper.h" | ||
| 42 | struct drm_crtc_helper_funcs { | 43 | struct drm_crtc_helper_funcs { |
| 43 | /* | 44 | /* |
| 44 | * Control power levels on the CRTC. If the mode passed in is | 45 | * 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, | |||
| 119 | encoder->helper_private = (void *)funcs; | 120 | encoder->helper_private = (void *)funcs; |
| 120 | } | 121 | } |
| 121 | 122 | ||
| 122 | static inline void drm_connector_helper_add(struct drm_connector *connector, | 123 | static inline int drm_connector_helper_add(struct drm_connector *connector, |
| 123 | const struct drm_connector_helper_funcs *funcs) | 124 | const struct drm_connector_helper_funcs *funcs) |
| 124 | { | 125 | { |
| 125 | connector->helper_private = (void *)funcs; | 126 | connector->helper_private = (void *)funcs; |
| 127 | return drm_fb_helper_add_connector(connector); | ||
| 126 | } | 128 | } |
| 127 | 129 | ||
| 128 | extern int drm_helper_resume_force_mode(struct drm_device *dev); | 130 | extern int drm_helper_resume_force_mode(struct drm_device *dev); |
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 88fffbdfa26f..4aa5740ce59f 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h | |||
| @@ -35,11 +35,30 @@ struct drm_fb_helper_crtc { | |||
| 35 | struct drm_mode_set mode_set; | 35 | struct drm_mode_set mode_set; |
| 36 | }; | 36 | }; |
| 37 | 37 | ||
| 38 | |||
| 38 | struct drm_fb_helper_funcs { | 39 | struct drm_fb_helper_funcs { |
| 39 | void (*gamma_set)(struct drm_crtc *crtc, u16 red, u16 green, | 40 | void (*gamma_set)(struct drm_crtc *crtc, u16 red, u16 green, |
| 40 | u16 blue, int regno); | 41 | u16 blue, int regno); |
| 41 | }; | 42 | }; |
| 42 | 43 | ||
| 44 | /* mode specified on the command line */ | ||
| 45 | struct drm_fb_helper_cmdline_mode { | ||
| 46 | bool specified; | ||
| 47 | bool refresh_specified; | ||
| 48 | bool bpp_specified; | ||
| 49 | int xres, yres; | ||
| 50 | int bpp; | ||
| 51 | int refresh; | ||
| 52 | bool rb; | ||
| 53 | bool interlace; | ||
| 54 | bool cvt; | ||
| 55 | bool margins; | ||
| 56 | }; | ||
| 57 | |||
| 58 | struct drm_fb_helper_connector { | ||
| 59 | struct drm_fb_helper_cmdline_mode cmdline_mode; | ||
| 60 | }; | ||
| 61 | |||
| 43 | struct drm_fb_helper { | 62 | struct drm_fb_helper { |
| 44 | struct drm_framebuffer *fb; | 63 | struct drm_framebuffer *fb; |
| 45 | struct drm_device *dev; | 64 | struct drm_device *dev; |
| @@ -57,6 +76,8 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev, | |||
| 57 | uint32_t fb_height, | 76 | uint32_t fb_height, |
| 58 | uint32_t surface_width, | 77 | uint32_t surface_width, |
| 59 | uint32_t surface_height, | 78 | uint32_t surface_height, |
| 79 | uint32_t surface_depth, | ||
| 80 | uint32_t surface_bpp, | ||
| 60 | struct drm_framebuffer **fb_ptr)); | 81 | struct drm_framebuffer **fb_ptr)); |
| 61 | int drm_fb_helper_init_crtc_count(struct drm_fb_helper *helper, int crtc_count, | 82 | int drm_fb_helper_init_crtc_count(struct drm_fb_helper *helper, int crtc_count, |
| 62 | int max_conn); | 83 | int max_conn); |
| @@ -79,4 +100,7 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb, | |||
| 79 | uint32_t fb_width, uint32_t fb_height); | 100 | uint32_t fb_width, uint32_t fb_height); |
| 80 | void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch); | 101 | void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch); |
| 81 | 102 | ||
| 103 | int drm_fb_helper_add_connector(struct drm_connector *connector); | ||
| 104 | int drm_fb_helper_parse_command_line(struct drm_device *dev); | ||
| 105 | |||
| 82 | #endif | 106 | #endif |
