1 | /* |
2 | * Copyright 2012 Red Hat Inc. |
3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the |
6 | * "Software"), to deal in the Software without restriction, including |
7 | * without limitation the rights to use, copy, modify, merge, publish, |
8 | * distribute, sub license, and/or sell copies of the Software, and to |
9 | * permit persons to whom the Software is furnished to do so, subject to |
10 | * the following conditions: |
11 | * |
12 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
13 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
14 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL |
15 | * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, |
16 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
17 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
18 | * USE OR OTHER DEALINGS IN THE SOFTWARE. |
19 | * |
20 | * The above copyright notice and this permission notice (including the |
21 | * next paragraph) shall be included in all copies or substantial portions |
22 | * of the Software. |
23 | * |
24 | */ |
25 | /* |
26 | * Authors: Dave Airlie <airlied@redhat.com> |
27 | */ |
28 | |
29 | #include <linux/pci.h> |
30 | |
31 | #include <drm/drm_managed.h> |
32 | #include <drm/drm_print.h> |
33 | |
34 | #include "ast_drv.h" |
35 | |
36 | static u32 ast_get_vram_size(struct ast_device *ast) |
37 | { |
38 | u8 jreg; |
39 | u32 vram_size; |
40 | |
41 | vram_size = AST_VIDMEM_DEFAULT_SIZE; |
42 | jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, index: 0xaa, preserve_mask: 0xff); |
43 | switch (jreg & 3) { |
44 | case 0: |
45 | vram_size = AST_VIDMEM_SIZE_8M; |
46 | break; |
47 | case 1: |
48 | vram_size = AST_VIDMEM_SIZE_16M; |
49 | break; |
50 | case 2: |
51 | vram_size = AST_VIDMEM_SIZE_32M; |
52 | break; |
53 | case 3: |
54 | vram_size = AST_VIDMEM_SIZE_64M; |
55 | break; |
56 | } |
57 | |
58 | jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, index: 0x99, preserve_mask: 0xff); |
59 | switch (jreg & 0x03) { |
60 | case 1: |
61 | vram_size -= 0x100000; |
62 | break; |
63 | case 2: |
64 | vram_size -= 0x200000; |
65 | break; |
66 | case 3: |
67 | vram_size -= 0x400000; |
68 | break; |
69 | } |
70 | |
71 | return vram_size; |
72 | } |
73 | |
74 | int ast_mm_init(struct ast_device *ast) |
75 | { |
76 | struct drm_device *dev = &ast->base; |
77 | struct pci_dev *pdev = to_pci_dev(dev->dev); |
78 | resource_size_t base, size; |
79 | u32 vram_size; |
80 | |
81 | base = pci_resource_start(pdev, 0); |
82 | size = pci_resource_len(pdev, 0); |
83 | |
84 | /* Don't fail on errors, but performance might be reduced. */ |
85 | devm_arch_io_reserve_memtype_wc(dev: dev->dev, start: base, size); |
86 | devm_arch_phys_wc_add(dev: dev->dev, base, size); |
87 | |
88 | vram_size = ast_get_vram_size(ast); |
89 | |
90 | ast->vram = devm_ioremap_wc(dev: dev->dev, offset: base, size: vram_size); |
91 | if (!ast->vram) |
92 | return -ENOMEM; |
93 | |
94 | ast->vram_base = base; |
95 | ast->vram_size = vram_size; |
96 | ast->vram_fb_available = vram_size; |
97 | |
98 | return 0; |
99 | } |
100 | |