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 |