1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#include <linux/pci.h>
30
31#include <drm/drm_gem_vram_helper.h>
32#include <drm/drm_managed.h>
33#include <drm/drm_print.h>
34
35#include "ast_drv.h"
36
37static u32 ast_get_vram_size(struct ast_private *ast)
38{
39 u8 jreg;
40 u32 vram_size;
41
42 ast_open_key(ast);
43
44 vram_size = AST_VIDMEM_DEFAULT_SIZE;
45 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff);
46 switch (jreg & 3) {
47 case 0:
48 vram_size = AST_VIDMEM_SIZE_8M;
49 break;
50 case 1:
51 vram_size = AST_VIDMEM_SIZE_16M;
52 break;
53 case 2:
54 vram_size = AST_VIDMEM_SIZE_32M;
55 break;
56 case 3:
57 vram_size = AST_VIDMEM_SIZE_64M;
58 break;
59 }
60
61 jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xff);
62 switch (jreg & 0x03) {
63 case 1:
64 vram_size -= 0x100000;
65 break;
66 case 2:
67 vram_size -= 0x200000;
68 break;
69 case 3:
70 vram_size -= 0x400000;
71 break;
72 }
73
74 return vram_size;
75}
76
77static void ast_mm_release(struct drm_device *dev, void *ptr)
78{
79 struct ast_private *ast = to_ast_private(dev);
80 struct pci_dev *pdev = to_pci_dev(dev->dev);
81
82 arch_phys_wc_del(ast->fb_mtrr);
83 arch_io_free_memtype_wc(pci_resource_start(pdev, 0),
84 pci_resource_len(pdev, 0));
85}
86
87int ast_mm_init(struct ast_private *ast)
88{
89 struct drm_device *dev = &ast->base;
90 struct pci_dev *pdev = to_pci_dev(dev->dev);
91 u32 vram_size;
92 int ret;
93
94 vram_size = ast_get_vram_size(ast);
95
96 ret = drmm_vram_helper_init(dev, pci_resource_start(pdev, 0), vram_size);
97 if (ret) {
98 drm_err(dev, "Error initializing VRAM MM; %d\n", ret);
99 return ret;
100 }
101
102 arch_io_reserve_memtype_wc(pci_resource_start(pdev, 0),
103 pci_resource_len(pdev, 0));
104 ast->fb_mtrr = arch_phys_wc_add(pci_resource_start(pdev, 0),
105 pci_resource_len(pdev, 0));
106
107 return drmm_add_action_or_reset(dev, ast_mm_release, NULL);
108}
109