diff options
Diffstat (limited to 'drivers/gpu/drm/ast/ast_main.c')
-rw-r--r-- | drivers/gpu/drm/ast/ast_main.c | 304 |
1 files changed, 194 insertions, 110 deletions
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 993909430736..262c2c0e43b4 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c | |||
@@ -32,8 +32,6 @@ | |||
32 | #include <drm/drm_fb_helper.h> | 32 | #include <drm/drm_fb_helper.h> |
33 | #include <drm/drm_crtc_helper.h> | 33 | #include <drm/drm_crtc_helper.h> |
34 | 34 | ||
35 | #include "ast_dram_tables.h" | ||
36 | |||
37 | void ast_set_index_reg_mask(struct ast_private *ast, | 35 | void ast_set_index_reg_mask(struct ast_private *ast, |
38 | uint32_t base, uint8_t index, | 36 | uint32_t base, uint8_t index, |
39 | uint8_t mask, uint8_t val) | 37 | uint8_t mask, uint8_t val) |
@@ -62,30 +60,99 @@ uint8_t ast_get_index_reg_mask(struct ast_private *ast, | |||
62 | return ret; | 60 | return ret; |
63 | } | 61 | } |
64 | 62 | ||
63 | static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev) | ||
64 | { | ||
65 | struct device_node *np = dev->pdev->dev.of_node; | ||
66 | struct ast_private *ast = dev->dev_private; | ||
67 | uint32_t data, jregd0, jregd1; | ||
68 | |||
69 | /* Defaults */ | ||
70 | ast->config_mode = ast_use_defaults; | ||
71 | *scu_rev = 0xffffffff; | ||
72 | |||
73 | /* Check if we have device-tree properties */ | ||
74 | if (np && !of_property_read_u32(np, "aspeed,scu-revision-id", | ||
75 | scu_rev)) { | ||
76 | /* We do, disable P2A access */ | ||
77 | ast->config_mode = ast_use_dt; | ||
78 | DRM_INFO("Using device-tree for configuration\n"); | ||
79 | return; | ||
80 | } | ||
81 | |||
82 | /* Not all families have a P2A bridge */ | ||
83 | if (dev->pdev->device != PCI_CHIP_AST2000) | ||
84 | return; | ||
85 | |||
86 | /* | ||
87 | * The BMC will set SCU 0x40 D[12] to 1 if the P2 bridge | ||
88 | * is disabled. We force using P2A if VGA only mode bit | ||
89 | * is set D[7] | ||
90 | */ | ||
91 | jregd0 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); | ||
92 | jregd1 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); | ||
93 | if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) { | ||
94 | /* Double check it's actually working */ | ||
95 | data = ast_read32(ast, 0xf004); | ||
96 | if (data != 0xFFFFFFFF) { | ||
97 | /* P2A works, grab silicon revision */ | ||
98 | ast->config_mode = ast_use_p2a; | ||
99 | |||
100 | DRM_INFO("Using P2A bridge for configuration\n"); | ||
101 | |||
102 | /* Read SCU7c (silicon revision register) */ | ||
103 | ast_write32(ast, 0xf004, 0x1e6e0000); | ||
104 | ast_write32(ast, 0xf000, 0x1); | ||
105 | *scu_rev = ast_read32(ast, 0x1207c); | ||
106 | return; | ||
107 | } | ||
108 | } | ||
109 | |||
110 | /* We have a P2A bridge but it's disabled */ | ||
111 | DRM_INFO("P2A bridge disabled, using default configuration\n"); | ||
112 | } | ||
65 | 113 | ||
66 | static int ast_detect_chip(struct drm_device *dev, bool *need_post) | 114 | static int ast_detect_chip(struct drm_device *dev, bool *need_post) |
67 | { | 115 | { |
68 | struct ast_private *ast = dev->dev_private; | 116 | struct ast_private *ast = dev->dev_private; |
69 | uint32_t data, jreg; | 117 | uint32_t jreg, scu_rev; |
118 | |||
119 | /* | ||
120 | * If VGA isn't enabled, we need to enable now or subsequent | ||
121 | * access to the scratch registers will fail. We also inform | ||
122 | * our caller that it needs to POST the chip | ||
123 | * (Assumption: VGA not enabled -> need to POST) | ||
124 | */ | ||
125 | if (!ast_is_vga_enabled(dev)) { | ||
126 | ast_enable_vga(dev); | ||
127 | DRM_INFO("VGA not enabled on entry, requesting chip POST\n"); | ||
128 | *need_post = true; | ||
129 | } else | ||
130 | *need_post = false; | ||
131 | |||
132 | |||
133 | /* Enable extended register access */ | ||
134 | ast_enable_mmio(dev); | ||
70 | ast_open_key(ast); | 135 | ast_open_key(ast); |
71 | 136 | ||
137 | /* Find out whether P2A works or whether to use device-tree */ | ||
138 | ast_detect_config_mode(dev, &scu_rev); | ||
139 | |||
140 | /* Identify chipset */ | ||
72 | if (dev->pdev->device == PCI_CHIP_AST1180) { | 141 | if (dev->pdev->device == PCI_CHIP_AST1180) { |
73 | ast->chip = AST1100; | 142 | ast->chip = AST1100; |
74 | DRM_INFO("AST 1180 detected\n"); | 143 | DRM_INFO("AST 1180 detected\n"); |
75 | } else { | 144 | } else { |
76 | if (dev->pdev->revision >= 0x30) { | 145 | if (dev->pdev->revision >= 0x40) { |
146 | ast->chip = AST2500; | ||
147 | DRM_INFO("AST 2500 detected\n"); | ||
148 | } else if (dev->pdev->revision >= 0x30) { | ||
77 | ast->chip = AST2400; | 149 | ast->chip = AST2400; |
78 | DRM_INFO("AST 2400 detected\n"); | 150 | DRM_INFO("AST 2400 detected\n"); |
79 | } else if (dev->pdev->revision >= 0x20) { | 151 | } else if (dev->pdev->revision >= 0x20) { |
80 | ast->chip = AST2300; | 152 | ast->chip = AST2300; |
81 | DRM_INFO("AST 2300 detected\n"); | 153 | DRM_INFO("AST 2300 detected\n"); |
82 | } else if (dev->pdev->revision >= 0x10) { | 154 | } else if (dev->pdev->revision >= 0x10) { |
83 | uint32_t data; | 155 | switch (scu_rev & 0x0300) { |
84 | ast_write32(ast, 0xf004, 0x1e6e0000); | ||
85 | ast_write32(ast, 0xf000, 0x1); | ||
86 | |||
87 | data = ast_read32(ast, 0x1207c); | ||
88 | switch (data & 0x0300) { | ||
89 | case 0x0200: | 156 | case 0x0200: |
90 | ast->chip = AST1100; | 157 | ast->chip = AST1100; |
91 | DRM_INFO("AST 1100 detected\n"); | 158 | DRM_INFO("AST 1100 detected\n"); |
@@ -110,26 +177,6 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) | |||
110 | } | 177 | } |
111 | } | 178 | } |
112 | 179 | ||
113 | /* | ||
114 | * If VGA isn't enabled, we need to enable now or subsequent | ||
115 | * access to the scratch registers will fail. We also inform | ||
116 | * our caller that it needs to POST the chip | ||
117 | * (Assumption: VGA not enabled -> need to POST) | ||
118 | */ | ||
119 | if (!ast_is_vga_enabled(dev)) { | ||
120 | ast_enable_vga(dev); | ||
121 | ast_enable_mmio(dev); | ||
122 | DRM_INFO("VGA not enabled on entry, requesting chip POST\n"); | ||
123 | *need_post = true; | ||
124 | } else | ||
125 | *need_post = false; | ||
126 | |||
127 | /* Check P2A Access */ | ||
128 | ast->DisableP2A = true; | ||
129 | data = ast_read32(ast, 0xf004); | ||
130 | if (data != 0xFFFFFFFF) | ||
131 | ast->DisableP2A = false; | ||
132 | |||
133 | /* Check if we support wide screen */ | 180 | /* Check if we support wide screen */ |
134 | switch (ast->chip) { | 181 | switch (ast->chip) { |
135 | case AST1180: | 182 | case AST1180: |
@@ -146,17 +193,15 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) | |||
146 | ast->support_wide_screen = true; | 193 | ast->support_wide_screen = true; |
147 | else { | 194 | else { |
148 | ast->support_wide_screen = false; | 195 | ast->support_wide_screen = false; |
149 | if (ast->DisableP2A == false) { | 196 | if (ast->chip == AST2300 && |
150 | /* Read SCU7c (silicon revision register) */ | 197 | (scu_rev & 0x300) == 0x0) /* ast1300 */ |
151 | ast_write32(ast, 0xf004, 0x1e6e0000); | 198 | ast->support_wide_screen = true; |
152 | ast_write32(ast, 0xf000, 0x1); | 199 | if (ast->chip == AST2400 && |
153 | data = ast_read32(ast, 0x1207c); | 200 | (scu_rev & 0x300) == 0x100) /* ast1400 */ |
154 | data &= 0x300; | 201 | ast->support_wide_screen = true; |
155 | if (ast->chip == AST2300 && data == 0x0) /* ast1300 */ | 202 | if (ast->chip == AST2500 && |
156 | ast->support_wide_screen = true; | 203 | scu_rev == 0x100) /* ast2510 */ |
157 | if (ast->chip == AST2400 && data == 0x100) /* ast1400 */ | 204 | ast->support_wide_screen = true; |
158 | ast->support_wide_screen = true; | ||
159 | } | ||
160 | } | 205 | } |
161 | break; | 206 | break; |
162 | } | 207 | } |
@@ -220,85 +265,121 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) | |||
220 | 265 | ||
221 | static int ast_get_dram_info(struct drm_device *dev) | 266 | static int ast_get_dram_info(struct drm_device *dev) |
222 | { | 267 | { |
268 | struct device_node *np = dev->pdev->dev.of_node; | ||
223 | struct ast_private *ast = dev->dev_private; | 269 | struct ast_private *ast = dev->dev_private; |
224 | uint32_t data, data2; | 270 | uint32_t mcr_cfg, mcr_scu_mpll, mcr_scu_strap; |
225 | uint32_t denum, num, div, ref_pll; | 271 | uint32_t denum, num, div, ref_pll, dsel; |
226 | 272 | ||
227 | if (ast->DisableP2A) | 273 | switch (ast->config_mode) { |
228 | { | 274 | case ast_use_dt: |
229 | ast->dram_bus_width = 16; | 275 | /* |
230 | ast->dram_type = AST_DRAM_1Gx16; | 276 | * If some properties are missing, use reasonable |
231 | ast->mclk = 396; | 277 | * defaults for AST2400 |
232 | } | 278 | */ |
233 | else | 279 | if (of_property_read_u32(np, "aspeed,mcr-configuration", |
234 | { | 280 | &mcr_cfg)) |
281 | mcr_cfg = 0x00000577; | ||
282 | if (of_property_read_u32(np, "aspeed,mcr-scu-mpll", | ||
283 | &mcr_scu_mpll)) | ||
284 | mcr_scu_mpll = 0x000050C0; | ||
285 | if (of_property_read_u32(np, "aspeed,mcr-scu-strap", | ||
286 | &mcr_scu_strap)) | ||
287 | mcr_scu_strap = 0; | ||
288 | break; | ||
289 | case ast_use_p2a: | ||
235 | ast_write32(ast, 0xf004, 0x1e6e0000); | 290 | ast_write32(ast, 0xf004, 0x1e6e0000); |
236 | ast_write32(ast, 0xf000, 0x1); | 291 | ast_write32(ast, 0xf000, 0x1); |
237 | data = ast_read32(ast, 0x10004); | 292 | mcr_cfg = ast_read32(ast, 0x10004); |
238 | 293 | mcr_scu_mpll = ast_read32(ast, 0x10120); | |
239 | if (data & 0x40) | 294 | mcr_scu_strap = ast_read32(ast, 0x10170); |
240 | ast->dram_bus_width = 16; | 295 | break; |
296 | case ast_use_defaults: | ||
297 | default: | ||
298 | ast->dram_bus_width = 16; | ||
299 | ast->dram_type = AST_DRAM_1Gx16; | ||
300 | if (ast->chip == AST2500) | ||
301 | ast->mclk = 800; | ||
241 | else | 302 | else |
242 | ast->dram_bus_width = 32; | 303 | ast->mclk = 396; |
243 | 304 | return 0; | |
244 | if (ast->chip == AST2300 || ast->chip == AST2400) { | 305 | } |
245 | switch (data & 0x03) { | ||
246 | case 0: | ||
247 | ast->dram_type = AST_DRAM_512Mx16; | ||
248 | break; | ||
249 | default: | ||
250 | case 1: | ||
251 | ast->dram_type = AST_DRAM_1Gx16; | ||
252 | break; | ||
253 | case 2: | ||
254 | ast->dram_type = AST_DRAM_2Gx16; | ||
255 | break; | ||
256 | case 3: | ||
257 | ast->dram_type = AST_DRAM_4Gx16; | ||
258 | break; | ||
259 | } | ||
260 | } else { | ||
261 | switch (data & 0x0c) { | ||
262 | case 0: | ||
263 | case 4: | ||
264 | ast->dram_type = AST_DRAM_512Mx16; | ||
265 | break; | ||
266 | case 8: | ||
267 | if (data & 0x40) | ||
268 | ast->dram_type = AST_DRAM_1Gx16; | ||
269 | else | ||
270 | ast->dram_type = AST_DRAM_512Mx32; | ||
271 | break; | ||
272 | case 0xc: | ||
273 | ast->dram_type = AST_DRAM_1Gx32; | ||
274 | break; | ||
275 | } | ||
276 | } | ||
277 | 306 | ||
278 | data = ast_read32(ast, 0x10120); | 307 | if (mcr_cfg & 0x40) |
279 | data2 = ast_read32(ast, 0x10170); | 308 | ast->dram_bus_width = 16; |
280 | if (data2 & 0x2000) | 309 | else |
281 | ref_pll = 14318; | 310 | ast->dram_bus_width = 32; |
282 | else | ||
283 | ref_pll = 12000; | ||
284 | 311 | ||
285 | denum = data & 0x1f; | 312 | if (ast->chip == AST2500) { |
286 | num = (data & 0x3fe0) >> 5; | 313 | switch (mcr_cfg & 0x03) { |
287 | data = (data & 0xc000) >> 14; | 314 | case 0: |
288 | switch (data) { | 315 | ast->dram_type = AST_DRAM_1Gx16; |
289 | case 3: | ||
290 | div = 0x4; | ||
291 | break; | 316 | break; |
292 | case 2: | 317 | default: |
293 | case 1: | 318 | case 1: |
294 | div = 0x2; | 319 | ast->dram_type = AST_DRAM_2Gx16; |
320 | break; | ||
321 | case 2: | ||
322 | ast->dram_type = AST_DRAM_4Gx16; | ||
323 | break; | ||
324 | case 3: | ||
325 | ast->dram_type = AST_DRAM_8Gx16; | ||
326 | break; | ||
327 | } | ||
328 | } else if (ast->chip == AST2300 || ast->chip == AST2400) { | ||
329 | switch (mcr_cfg & 0x03) { | ||
330 | case 0: | ||
331 | ast->dram_type = AST_DRAM_512Mx16; | ||
295 | break; | 332 | break; |
296 | default: | 333 | default: |
297 | div = 0x1; | 334 | case 1: |
335 | ast->dram_type = AST_DRAM_1Gx16; | ||
336 | break; | ||
337 | case 2: | ||
338 | ast->dram_type = AST_DRAM_2Gx16; | ||
339 | break; | ||
340 | case 3: | ||
341 | ast->dram_type = AST_DRAM_4Gx16; | ||
342 | break; | ||
343 | } | ||
344 | } else { | ||
345 | switch (mcr_cfg & 0x0c) { | ||
346 | case 0: | ||
347 | case 4: | ||
348 | ast->dram_type = AST_DRAM_512Mx16; | ||
349 | break; | ||
350 | case 8: | ||
351 | if (mcr_cfg & 0x40) | ||
352 | ast->dram_type = AST_DRAM_1Gx16; | ||
353 | else | ||
354 | ast->dram_type = AST_DRAM_512Mx32; | ||
355 | break; | ||
356 | case 0xc: | ||
357 | ast->dram_type = AST_DRAM_1Gx32; | ||
298 | break; | 358 | break; |
299 | } | 359 | } |
300 | ast->mclk = ref_pll * (num + 2) / (denum + 2) * (div * 1000); | ||
301 | } | 360 | } |
361 | |||
362 | if (mcr_scu_strap & 0x2000) | ||
363 | ref_pll = 14318; | ||
364 | else | ||
365 | ref_pll = 12000; | ||
366 | |||
367 | denum = mcr_scu_mpll & 0x1f; | ||
368 | num = (mcr_scu_mpll & 0x3fe0) >> 5; | ||
369 | dsel = (mcr_scu_mpll & 0xc000) >> 14; | ||
370 | switch (dsel) { | ||
371 | case 3: | ||
372 | div = 0x4; | ||
373 | break; | ||
374 | case 2: | ||
375 | case 1: | ||
376 | div = 0x2; | ||
377 | break; | ||
378 | default: | ||
379 | div = 0x1; | ||
380 | break; | ||
381 | } | ||
382 | ast->mclk = ref_pll * (num + 2) / ((denum + 2) * (div * 1000)); | ||
302 | return 0; | 383 | return 0; |
303 | } | 384 | } |
304 | 385 | ||
@@ -437,17 +518,19 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags) | |||
437 | 518 | ||
438 | ast_detect_chip(dev, &need_post); | 519 | ast_detect_chip(dev, &need_post); |
439 | 520 | ||
521 | if (need_post) | ||
522 | ast_post_gpu(dev); | ||
523 | |||
440 | if (ast->chip != AST1180) { | 524 | if (ast->chip != AST1180) { |
441 | ret = ast_get_dram_info(dev); | 525 | ret = ast_get_dram_info(dev); |
442 | if (ret) | 526 | if (ret) |
443 | goto out_free; | 527 | goto out_free; |
444 | ast->vram_size = ast_get_vram_info(dev); | 528 | ast->vram_size = ast_get_vram_info(dev); |
445 | DRM_INFO("dram %d %d %d %08x\n", ast->mclk, ast->dram_type, ast->dram_bus_width, ast->vram_size); | 529 | DRM_INFO("dram MCLK=%u Mhz type=%d bus_width=%d size=%08x\n", |
530 | ast->mclk, ast->dram_type, | ||
531 | ast->dram_bus_width, ast->vram_size); | ||
446 | } | 532 | } |
447 | 533 | ||
448 | if (need_post) | ||
449 | ast_post_gpu(dev); | ||
450 | |||
451 | ret = ast_mm_init(ast); | 534 | ret = ast_mm_init(ast); |
452 | if (ret) | 535 | if (ret) |
453 | goto out_free; | 536 | goto out_free; |
@@ -465,6 +548,7 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags) | |||
465 | ast->chip == AST2200 || | 548 | ast->chip == AST2200 || |
466 | ast->chip == AST2300 || | 549 | ast->chip == AST2300 || |
467 | ast->chip == AST2400 || | 550 | ast->chip == AST2400 || |
551 | ast->chip == AST2500 || | ||
468 | ast->chip == AST1180) { | 552 | ast->chip == AST1180) { |
469 | dev->mode_config.max_width = 1920; | 553 | dev->mode_config.max_width = 1920; |
470 | dev->mode_config.max_height = 2048; | 554 | dev->mode_config.max_height = 2048; |