aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/ast/ast_main.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-05-18 21:15:08 -0400
committerDave Airlie <airlied@redhat.com>2014-05-18 21:15:08 -0400
commit263432b021cd252570001c10404367e948ac10f0 (patch)
treec8ac4662ece75eab1554de8d180e430f55b18d97 /drivers/gpu/drm/ast/ast_main.c
parente5daa1ddc1b01587cba2915390e52c0dd0190e1e (diff)
parent83c6620bae3f14adb2430fdcc367980fe3b7bee2 (diff)
Merge branch 'ast-updates' of ssh://people.freedesktop.org/~/linux into drm-next
Pull in latest updates to AST driver. * 'ast-updates' of ssh://people.freedesktop.org/~/linux: drm/ast: initial DP501 support (v0.2) drm/ast: rename the mindwm/moutdwm and deinline them drm/ast: resync the dram post code with upstream drm/ast: add AST 2400 support. drm/ast: add widescreen + rb modes from X.org driver (v2)
Diffstat (limited to 'drivers/gpu/drm/ast/ast_main.c')
-rw-r--r--drivers/gpu/drm/ast/ast_main.c90
1 files changed, 82 insertions, 8 deletions
diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
index 01bf9e730acf..a2cc6be97983 100644
--- a/drivers/gpu/drm/ast/ast_main.c
+++ b/drivers/gpu/drm/ast/ast_main.c
@@ -66,12 +66,16 @@ uint8_t ast_get_index_reg_mask(struct ast_private *ast,
66static int ast_detect_chip(struct drm_device *dev) 66static int ast_detect_chip(struct drm_device *dev)
67{ 67{
68 struct ast_private *ast = dev->dev_private; 68 struct ast_private *ast = dev->dev_private;
69 uint32_t data, jreg;
69 70
70 if (dev->pdev->device == PCI_CHIP_AST1180) { 71 if (dev->pdev->device == PCI_CHIP_AST1180) {
71 ast->chip = AST1100; 72 ast->chip = AST1100;
72 DRM_INFO("AST 1180 detected\n"); 73 DRM_INFO("AST 1180 detected\n");
73 } else { 74 } else {
74 if (dev->pdev->revision >= 0x20) { 75 if (dev->pdev->revision >= 0x30) {
76 ast->chip = AST2400;
77 DRM_INFO("AST 2400 detected\n");
78 } else if (dev->pdev->revision >= 0x20) {
75 ast->chip = AST2300; 79 ast->chip = AST2300;
76 DRM_INFO("AST 2300 detected\n"); 80 DRM_INFO("AST 2300 detected\n");
77 } else if (dev->pdev->revision >= 0x10) { 81 } else if (dev->pdev->revision >= 0x10) {
@@ -104,6 +108,59 @@ static int ast_detect_chip(struct drm_device *dev)
104 DRM_INFO("AST 2000 detected\n"); 108 DRM_INFO("AST 2000 detected\n");
105 } 109 }
106 } 110 }
111
112 switch (ast->chip) {
113 case AST1180:
114 ast->support_wide_screen = true;
115 break;
116 case AST2000:
117 ast->support_wide_screen = false;
118 break;
119 default:
120 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff);
121 if (!(jreg & 0x80))
122 ast->support_wide_screen = true;
123 else if (jreg & 0x01)
124 ast->support_wide_screen = true;
125 else {
126 ast->support_wide_screen = false;
127 ast_write32(ast, 0xf004, 0x1e6e0000);
128 ast_write32(ast, 0xf000, 0x1);
129 data = ast_read32(ast, 0x1207c);
130 data &= 0x300;
131 if (ast->chip == AST2300 && data == 0x0) /* ast1300 */
132 ast->support_wide_screen = true;
133 if (ast->chip == AST2400 && data == 0x100) /* ast1400 */
134 ast->support_wide_screen = true;
135 }
136 break;
137 }
138
139 ast->tx_chip_type = AST_TX_NONE;
140 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff);
141 if (jreg & 0x80)
142 ast->tx_chip_type = AST_TX_SIL164;
143 if ((ast->chip == AST2300) || (ast->chip == AST2400)) {
144 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff);
145 switch (jreg) {
146 case 0x04:
147 ast->tx_chip_type = AST_TX_SIL164;
148 break;
149 case 0x08:
150 ast->dp501_fw_addr = kzalloc(32*1024, GFP_KERNEL);
151 if (ast->dp501_fw_addr) {
152 /* backup firmware */
153 if (ast_backup_fw(dev, ast->dp501_fw_addr, 32*1024)) {
154 kfree(ast->dp501_fw_addr);
155 ast->dp501_fw_addr = NULL;
156 }
157 }
158 /* fallthrough */
159 case 0x0c:
160 ast->tx_chip_type = AST_TX_DP501;
161 }
162 }
163
107 return 0; 164 return 0;
108} 165}
109 166
@@ -129,7 +186,7 @@ static int ast_get_dram_info(struct drm_device *dev)
129 else 186 else
130 ast->dram_bus_width = 32; 187 ast->dram_bus_width = 32;
131 188
132 if (ast->chip == AST2300) { 189 if (ast->chip == AST2300 || ast->chip == AST2400) {
133 switch (data & 0x03) { 190 switch (data & 0x03) {
134 case 0: 191 case 0:
135 ast->dram_type = AST_DRAM_512Mx16; 192 ast->dram_type = AST_DRAM_512Mx16;
@@ -257,17 +314,32 @@ static u32 ast_get_vram_info(struct drm_device *dev)
257{ 314{
258 struct ast_private *ast = dev->dev_private; 315 struct ast_private *ast = dev->dev_private;
259 u8 jreg; 316 u8 jreg;
260 317 u32 vram_size;
261 ast_open_key(ast); 318 ast_open_key(ast);
262 319
320 vram_size = AST_VIDMEM_DEFAULT_SIZE;
263 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff); 321 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff);
264 switch (jreg & 3) { 322 switch (jreg & 3) {
265 case 0: return AST_VIDMEM_SIZE_8M; 323 case 0: vram_size = AST_VIDMEM_SIZE_8M; break;
266 case 1: return AST_VIDMEM_SIZE_16M; 324 case 1: vram_size = AST_VIDMEM_SIZE_16M; break;
267 case 2: return AST_VIDMEM_SIZE_32M; 325 case 2: vram_size = AST_VIDMEM_SIZE_32M; break;
268 case 3: return AST_VIDMEM_SIZE_64M; 326 case 3: vram_size = AST_VIDMEM_SIZE_64M; break;
269 } 327 }
270 return AST_VIDMEM_DEFAULT_SIZE; 328
329 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xff);
330 switch (jreg & 0x03) {
331 case 1:
332 vram_size -= 0x100000;
333 break;
334 case 2:
335 vram_size -= 0x200000;
336 break;
337 case 3:
338 vram_size -= 0x400000;
339 break;
340 }
341
342 return vram_size;
271} 343}
272 344
273int ast_driver_load(struct drm_device *dev, unsigned long flags) 345int ast_driver_load(struct drm_device *dev, unsigned long flags)
@@ -316,6 +388,7 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags)
316 if (ast->chip == AST2100 || 388 if (ast->chip == AST2100 ||
317 ast->chip == AST2200 || 389 ast->chip == AST2200 ||
318 ast->chip == AST2300 || 390 ast->chip == AST2300 ||
391 ast->chip == AST2400 ||
319 ast->chip == AST1180) { 392 ast->chip == AST1180) {
320 dev->mode_config.max_width = 1920; 393 dev->mode_config.max_width = 1920;
321 dev->mode_config.max_height = 2048; 394 dev->mode_config.max_height = 2048;
@@ -343,6 +416,7 @@ int ast_driver_unload(struct drm_device *dev)
343{ 416{
344 struct ast_private *ast = dev->dev_private; 417 struct ast_private *ast = dev->dev_private;
345 418
419 kfree(ast->dp501_fw_addr);
346 ast_mode_fini(dev); 420 ast_mode_fini(dev);
347 ast_fbdev_fini(dev); 421 ast_fbdev_fini(dev);
348 drm_mode_config_cleanup(dev); 422 drm_mode_config_cleanup(dev);