2 * Copyright 2012 Red Hat Inc.
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:
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.
20 * The above copyright notice and this permission notice (including the
21 * next paragraph) shall be included in all copies or substantial portions
26 * Authors: Dave Airlie <airlied@redhat.com>
29 #include <linux/pci.h>
31 #include <drm/drm_managed.h>
33 #include "mgag200_drv.h"
35 static size_t mgag200_probe_vram(struct mga_device
*mdev
, void __iomem
*mem
,
50 if ((mdev
->type
== G200_EW3
) && (vram_size
>= 0x1000000))
51 vram_size
= vram_size
- 0x400000;
53 for (offset
= 0x100000; offset
< vram_size
; offset
+= 0x4000) {
54 orig1
= ioread8(mem
+ offset
);
55 orig2
= ioread8(mem
+ offset
+ 0x100);
57 iowrite16(0xaa55, mem
+ offset
);
58 iowrite16(0xaa55, mem
+ offset
+ 0x100);
60 test1
= ioread16(mem
+ offset
);
61 test2
= ioread16(mem
);
63 iowrite16(orig1
, mem
+ offset
);
64 iowrite16(orig2
, mem
+ offset
+ 0x100);
75 return offset
- 65536;
78 static void mgag200_mm_release(struct drm_device
*dev
, void *ptr
)
80 struct mga_device
*mdev
= to_mga_device(dev
);
82 mdev
->vram_fb_available
= 0;
84 arch_io_free_memtype_wc(pci_resource_start(dev
->pdev
, 0),
85 pci_resource_len(dev
->pdev
, 0));
86 arch_phys_wc_del(mdev
->fb_mtrr
);
90 int mgag200_mm_init(struct mga_device
*mdev
)
92 struct drm_device
*dev
= &mdev
->base
;
94 resource_size_t start
, len
;
97 WREG_ECRT(0x04, 0x00);
99 misc
= RREG8(MGA_MISC_IN
);
100 misc
|= MGAREG_MISC_RAMMAPEN
|
101 MGAREG_MISC_HIGH_PG_SEL
;
102 WREG8(MGA_MISC_OUT
, misc
);
105 start
= pci_resource_start(dev
->pdev
, 0);
106 len
= pci_resource_len(dev
->pdev
, 0);
108 if (!devm_request_mem_region(dev
->dev
, start
, len
, "mgadrmfb_vram")) {
109 drm_err(dev
, "can't reserve VRAM\n");
113 arch_io_reserve_memtype_wc(start
, len
);
115 mdev
->fb_mtrr
= arch_phys_wc_add(start
, len
);
117 mdev
->vram
= ioremap(start
, len
);
120 goto err_arch_phys_wc_del
;
123 mdev
->mc
.vram_size
= mgag200_probe_vram(mdev
, mdev
->vram
, len
);
124 mdev
->mc
.vram_base
= start
;
125 mdev
->mc
.vram_window
= len
;
127 mdev
->vram_fb_available
= mdev
->mc
.vram_size
;
129 return drmm_add_action_or_reset(dev
, mgag200_mm_release
, NULL
);
131 err_arch_phys_wc_del
:
132 arch_phys_wc_del(mdev
->fb_mtrr
);
133 arch_io_free_memtype_wc(start
, len
);