aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/ast/ast_main.c
diff options
context:
space:
mode:
authorRussell Currey <ruscur@russell.cc>2017-02-16 22:33:01 -0500
committerDave Airlie <airlied@redhat.com>2017-02-27 22:09:50 -0500
commit71f677a91046599ece96ebab21df956ce909c456 (patch)
tree4974601a564581b08cd16bb8e34fdeda5d1ffa49 /drivers/gpu/drm/ast/ast_main.c
parent3856081eede297b617560b85e948cfb00bb395ec (diff)
drm/ast: Handle configuration without P2A bridge
The ast driver configures a window to enable access into BMC memory space in order to read some configuration registers. If this window is disabled, which it can be from the BMC side, the ast driver can't function. Closing this window is a necessity for security if a machine's host side and BMC side are controlled by different parties; i.e. a cloud provider offering machines "bare metal". A recent patch went in to try to check if that window is open but it does so by trying to access the registers in question and testing if the result is 0xffffffff. This method will trigger a PCIe error when the window is closed which on some systems will be fatal (it will trigger an EEH for example on POWER which will take out the device). This patch improves this in two ways: - First, if the firmware has put properties in the device-tree containing the relevant configuration information, we use these. - Otherwise, a bit in one of the SCU scratch registers (which are readable via the VGA register space and writeable by the BMC) will indicate if the BMC has closed the window. This bit has been defined by Y.C Chen from Aspeed. If the window is closed and the configuration isn't available from the device-tree, some sane defaults are used. Those defaults are hopefully sufficient for standard video modes used on a server. Signed-off-by: Russell Currey <ruscur@russell.cc> Acked-by: Joel Stanley <joel@jms.id.au> Cc: <stable@vger.kernel.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/ast/ast_main.c')
-rw-r--r--drivers/gpu/drm/ast/ast_main.c264
1 files changed, 161 insertions, 103 deletions
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index 993909430736..1f9fa69d4504 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -62,13 +62,84 @@ uint8_t ast_get_index_reg_mask(struct ast_private *ast,
62 return ret; 62 return ret;
63} 63}
64 64
65static void ast_detect_config_mode(struct drm_device *dev, u32 *scu_rev)
66{
67 struct device_node *np = dev->pdev->dev.of_node;
68 struct ast_private *ast = dev->dev_private;
69 uint32_t data, jregd0, jregd1;
70
71 /* Defaults */
72 ast->config_mode = ast_use_defaults;
73 *scu_rev = 0xffffffff;
74
75 /* Check if we have device-tree properties */
76 if (np && !of_property_read_u32(np, "aspeed,scu-revision-id",
77 scu_rev)) {
78 /* We do, disable P2A access */
79 ast->config_mode = ast_use_dt;
80 DRM_INFO("Using device-tree for configuration\n");
81 return;
82 }
83
84 /* Not all families have a P2A bridge */
85 if (dev->pdev->device != PCI_CHIP_AST2000)
86 return;
87
88 /*
89 * The BMC will set SCU 0x40 D[12] to 1 if the P2 bridge
90 * is disabled. We force using P2A if VGA only mode bit
91 * is set D[7]
92 */
93 jregd0 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
94 jregd1 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
95 if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) {
96 /* Double check it's actually working */
97 data = ast_read32(ast, 0xf004);
98 if (data != 0xFFFFFFFF) {
99 /* P2A works, grab silicon revision */
100 ast->config_mode = ast_use_p2a;
101
102 DRM_INFO("Using P2A bridge for configuration\n");
103
104 /* Read SCU7c (silicon revision register) */
105 ast_write32(ast, 0xf004, 0x1e6e0000);
106 ast_write32(ast, 0xf000, 0x1);
107 *scu_rev = ast_read32(ast, 0x1207c);
108 return;
109 }
110 }
111
112 /* We have a P2A bridge but it's disabled */
113 DRM_INFO("P2A bridge disabled, using default configuration\n");
114}
65 115
66static int ast_detect_chip(struct drm_device *dev, bool *need_post) 116static int ast_detect_chip(struct drm_device *dev, bool *need_post)
67{ 117{
68 struct ast_private *ast = dev->dev_private; 118 struct ast_private *ast = dev->dev_private;
69 uint32_t data, jreg; 119 uint32_t jreg, scu_rev;
120
121 /*
122 * If VGA isn't enabled, we need to enable now or subsequent
123 * access to the scratch registers will fail. We also inform
124 * our caller that it needs to POST the chip
125 * (Assumption: VGA not enabled -> need to POST)
126 */
127 if (!ast_is_vga_enabled(dev)) {
128 ast_enable_vga(dev);
129 DRM_INFO("VGA not enabled on entry, requesting chip POST\n");
130 *need_post = true;
131 } else
132 *need_post = false;
133
134
135 /* Enable extended register access */
136 ast_enable_mmio(dev);
70 ast_open_key(ast); 137 ast_open_key(ast);
71 138
139 /* Find out whether P2A works or whether to use device-tree */
140 ast_detect_config_mode(dev, &scu_rev);
141
142 /* Identify chipset */
72 if (dev->pdev->device == PCI_CHIP_AST1180) { 143 if (dev->pdev->device == PCI_CHIP_AST1180) {
73 ast->chip = AST1100; 144 ast->chip = AST1100;
74 DRM_INFO("AST 1180 detected\n"); 145 DRM_INFO("AST 1180 detected\n");
@@ -80,12 +151,7 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
80 ast->chip = AST2300; 151 ast->chip = AST2300;
81 DRM_INFO("AST 2300 detected\n"); 152 DRM_INFO("AST 2300 detected\n");
82 } else if (dev->pdev->revision >= 0x10) { 153 } else if (dev->pdev->revision >= 0x10) {
83 uint32_t data; 154 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: 155 case 0x0200:
90 ast->chip = AST1100; 156 ast->chip = AST1100;
91 DRM_INFO("AST 1100 detected\n"); 157 DRM_INFO("AST 1100 detected\n");
@@ -110,26 +176,6 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
110 } 176 }
111 } 177 }
112 178
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 */ 179 /* Check if we support wide screen */
134 switch (ast->chip) { 180 switch (ast->chip) {
135 case AST1180: 181 case AST1180:
@@ -146,17 +192,12 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
146 ast->support_wide_screen = true; 192 ast->support_wide_screen = true;
147 else { 193 else {
148 ast->support_wide_screen = false; 194 ast->support_wide_screen = false;
149 if (ast->DisableP2A == false) { 195 if (ast->chip == AST2300 &&
150 /* Read SCU7c (silicon revision register) */ 196 (scu_rev & 0x300) == 0x0) /* ast1300 */
151 ast_write32(ast, 0xf004, 0x1e6e0000); 197 ast->support_wide_screen = true;
152 ast_write32(ast, 0xf000, 0x1); 198 if (ast->chip == AST2400 &&
153 data = ast_read32(ast, 0x1207c); 199 (scu_rev & 0x300) == 0x100) /* ast1400 */
154 data &= 0x300; 200 ast->support_wide_screen = true;
155 if (ast->chip == AST2300 && data == 0x0) /* ast1300 */
156 ast->support_wide_screen = true;
157 if (ast->chip == AST2400 && data == 0x100) /* ast1400 */
158 ast->support_wide_screen = true;
159 }
160 } 201 }
161 break; 202 break;
162 } 203 }
@@ -220,85 +261,102 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post)
220 261
221static int ast_get_dram_info(struct drm_device *dev) 262static int ast_get_dram_info(struct drm_device *dev)
222{ 263{
264 struct device_node *np = dev->pdev->dev.of_node;
223 struct ast_private *ast = dev->dev_private; 265 struct ast_private *ast = dev->dev_private;
224 uint32_t data, data2; 266 uint32_t mcr_cfg, mcr_scu_mpll, mcr_scu_strap;
225 uint32_t denum, num, div, ref_pll; 267 uint32_t denum, num, div, ref_pll, dsel;
226 268
227 if (ast->DisableP2A) 269 switch (ast->config_mode) {
228 { 270 case ast_use_dt:
271 /*
272 * If some properties are missing, use reasonable
273 * defaults for AST2400
274 */
275 if (of_property_read_u32(np, "aspeed,mcr-configuration",
276 &mcr_cfg))
277 mcr_cfg = 0x00000577;
278 if (of_property_read_u32(np, "aspeed,mcr-scu-mpll",
279 &mcr_scu_mpll))
280 mcr_scu_mpll = 0x000050C0;
281 if (of_property_read_u32(np, "aspeed,mcr-scu-strap",
282 &mcr_scu_strap))
283 mcr_scu_strap = 0;
284 break;
285 case ast_use_p2a:
286 ast_write32(ast, 0xf004, 0x1e6e0000);
287 ast_write32(ast, 0xf000, 0x1);
288 mcr_cfg = ast_read32(ast, 0x10004);
289 mcr_scu_mpll = ast_read32(ast, 0x10120);
290 mcr_scu_strap = ast_read32(ast, 0x10170);
291 break;
292 case ast_use_defaults:
293 default:
229 ast->dram_bus_width = 16; 294 ast->dram_bus_width = 16;
230 ast->dram_type = AST_DRAM_1Gx16; 295 ast->dram_type = AST_DRAM_1Gx16;
231 ast->mclk = 396; 296 ast->mclk = 396;
297 return 0;
232 } 298 }
233 else
234 {
235 ast_write32(ast, 0xf004, 0x1e6e0000);
236 ast_write32(ast, 0xf000, 0x1);
237 data = ast_read32(ast, 0x10004);
238
239 if (data & 0x40)
240 ast->dram_bus_width = 16;
241 else
242 ast->dram_bus_width = 32;
243 299
244 if (ast->chip == AST2300 || ast->chip == AST2400) { 300 if (mcr_cfg & 0x40)
245 switch (data & 0x03) { 301 ast->dram_bus_width = 16;
246 case 0: 302 else
247 ast->dram_type = AST_DRAM_512Mx16; 303 ast->dram_bus_width = 32;
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 304
278 data = ast_read32(ast, 0x10120); 305 if (ast->chip == AST2300 || ast->chip == AST2400) {
279 data2 = ast_read32(ast, 0x10170); 306 switch (mcr_cfg & 0x03) {
280 if (data2 & 0x2000) 307 case 0:
281 ref_pll = 14318; 308 ast->dram_type = AST_DRAM_512Mx16;
282 else
283 ref_pll = 12000;
284
285 denum = data & 0x1f;
286 num = (data & 0x3fe0) >> 5;
287 data = (data & 0xc000) >> 14;
288 switch (data) {
289 case 3:
290 div = 0x4;
291 break; 309 break;
292 case 2: 310 default:
293 case 1: 311 case 1:
294 div = 0x2; 312 ast->dram_type = AST_DRAM_1Gx16;
295 break; 313 break;
296 default: 314 case 2:
297 div = 0x1; 315 ast->dram_type = AST_DRAM_2Gx16;
316 break;
317 case 3:
318 ast->dram_type = AST_DRAM_4Gx16;
319 break;
320 }
321 } else {
322 switch (mcr_cfg & 0x0c) {
323 case 0:
324 case 4:
325 ast->dram_type = AST_DRAM_512Mx16;
326 break;
327 case 8:
328 if (mcr_cfg & 0x40)
329 ast->dram_type = AST_DRAM_1Gx16;
330 else
331 ast->dram_type = AST_DRAM_512Mx32;
332 break;
333 case 0xc:
334 ast->dram_type = AST_DRAM_1Gx32;
298 break; 335 break;
299 } 336 }
300 ast->mclk = ref_pll * (num + 2) / (denum + 2) * (div * 1000);
301 } 337 }
338
339 if (mcr_scu_strap & 0x2000)
340 ref_pll = 14318;
341 else
342 ref_pll = 12000;
343
344 denum = mcr_scu_mpll & 0x1f;
345 num = (mcr_scu_mpll & 0x3fe0) >> 5;
346 dsel = (mcr_scu_mpll & 0xc000) >> 14;
347 switch (dsel) {
348 case 3:
349 div = 0x4;
350 break;
351 case 2:
352 case 1:
353 div = 0x2;
354 break;
355 default:
356 div = 0x1;
357 break;
358 }
359 ast->mclk = ref_pll * (num + 2) / (denum + 2) * (div * 1000);
302 return 0; 360 return 0;
303} 361}
304 362