xref: /OK3568_Linux_fs/kernel/drivers/gpu/drm/ast/ast_mm.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright 2012 Red Hat Inc.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Permission is hereby granted, free of charge, to any person obtaining a
5*4882a593Smuzhiyun  * copy of this software and associated documentation files (the
6*4882a593Smuzhiyun  * "Software"), to deal in the Software without restriction, including
7*4882a593Smuzhiyun  * without limitation the rights to use, copy, modify, merge, publish,
8*4882a593Smuzhiyun  * distribute, sub license, and/or sell copies of the Software, and to
9*4882a593Smuzhiyun  * permit persons to whom the Software is furnished to do so, subject to
10*4882a593Smuzhiyun  * the following conditions:
11*4882a593Smuzhiyun  *
12*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13*4882a593Smuzhiyun  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14*4882a593Smuzhiyun  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
15*4882a593Smuzhiyun  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
16*4882a593Smuzhiyun  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
17*4882a593Smuzhiyun  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
18*4882a593Smuzhiyun  * USE OR OTHER DEALINGS IN THE SOFTWARE.
19*4882a593Smuzhiyun  *
20*4882a593Smuzhiyun  * The above copyright notice and this permission notice (including the
21*4882a593Smuzhiyun  * next paragraph) shall be included in all copies or substantial portions
22*4882a593Smuzhiyun  * of the Software.
23*4882a593Smuzhiyun  *
24*4882a593Smuzhiyun  */
25*4882a593Smuzhiyun /*
26*4882a593Smuzhiyun  * Authors: Dave Airlie <airlied@redhat.com>
27*4882a593Smuzhiyun  */
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun #include <linux/pci.h>
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #include <drm/drm_gem_vram_helper.h>
32*4882a593Smuzhiyun #include <drm/drm_managed.h>
33*4882a593Smuzhiyun #include <drm/drm_print.h>
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #include "ast_drv.h"
36*4882a593Smuzhiyun 
ast_get_vram_size(struct ast_private * ast)37*4882a593Smuzhiyun static u32 ast_get_vram_size(struct ast_private *ast)
38*4882a593Smuzhiyun {
39*4882a593Smuzhiyun 	u8 jreg;
40*4882a593Smuzhiyun 	u32 vram_size;
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun 	ast_open_key(ast);
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun 	vram_size = AST_VIDMEM_DEFAULT_SIZE;
45*4882a593Smuzhiyun 	jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff);
46*4882a593Smuzhiyun 	switch (jreg & 3) {
47*4882a593Smuzhiyun 	case 0:
48*4882a593Smuzhiyun 		vram_size = AST_VIDMEM_SIZE_8M;
49*4882a593Smuzhiyun 		break;
50*4882a593Smuzhiyun 	case 1:
51*4882a593Smuzhiyun 		vram_size = AST_VIDMEM_SIZE_16M;
52*4882a593Smuzhiyun 		break;
53*4882a593Smuzhiyun 	case 2:
54*4882a593Smuzhiyun 		vram_size = AST_VIDMEM_SIZE_32M;
55*4882a593Smuzhiyun 		break;
56*4882a593Smuzhiyun 	case 3:
57*4882a593Smuzhiyun 		vram_size = AST_VIDMEM_SIZE_64M;
58*4882a593Smuzhiyun 		break;
59*4882a593Smuzhiyun 	}
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xff);
62*4882a593Smuzhiyun 	switch (jreg & 0x03) {
63*4882a593Smuzhiyun 	case 1:
64*4882a593Smuzhiyun 		vram_size -= 0x100000;
65*4882a593Smuzhiyun 		break;
66*4882a593Smuzhiyun 	case 2:
67*4882a593Smuzhiyun 		vram_size -= 0x200000;
68*4882a593Smuzhiyun 		break;
69*4882a593Smuzhiyun 	case 3:
70*4882a593Smuzhiyun 		vram_size -= 0x400000;
71*4882a593Smuzhiyun 		break;
72*4882a593Smuzhiyun 	}
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	return vram_size;
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun 
ast_mm_release(struct drm_device * dev,void * ptr)77*4882a593Smuzhiyun static void ast_mm_release(struct drm_device *dev, void *ptr)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun 	struct ast_private *ast = to_ast_private(dev);
80*4882a593Smuzhiyun 
81*4882a593Smuzhiyun 	arch_phys_wc_del(ast->fb_mtrr);
82*4882a593Smuzhiyun 	arch_io_free_memtype_wc(pci_resource_start(dev->pdev, 0),
83*4882a593Smuzhiyun 				pci_resource_len(dev->pdev, 0));
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun 
ast_mm_init(struct ast_private * ast)86*4882a593Smuzhiyun int ast_mm_init(struct ast_private *ast)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun 	struct drm_device *dev = &ast->base;
89*4882a593Smuzhiyun 	u32 vram_size;
90*4882a593Smuzhiyun 	int ret;
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 	vram_size = ast_get_vram_size(ast);
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	ret = drmm_vram_helper_init(dev, pci_resource_start(dev->pdev, 0),
95*4882a593Smuzhiyun 				    vram_size);
96*4882a593Smuzhiyun 	if (ret) {
97*4882a593Smuzhiyun 		drm_err(dev, "Error initializing VRAM MM; %d\n", ret);
98*4882a593Smuzhiyun 		return ret;
99*4882a593Smuzhiyun 	}
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	arch_io_reserve_memtype_wc(pci_resource_start(dev->pdev, 0),
102*4882a593Smuzhiyun 				   pci_resource_len(dev->pdev, 0));
103*4882a593Smuzhiyun 	ast->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0),
104*4882a593Smuzhiyun 					pci_resource_len(dev->pdev, 0));
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	return drmm_add_action_or_reset(dev, ast_mm_release, NULL);
107*4882a593Smuzhiyun }
108