Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
gpu
drm
mga
mga_warp.c
Go to the documentation of this file.
1
/* mga_warp.c -- Matrox G200/G400 WARP engine management -*- linux-c -*-
2
* Created: Thu Jan 11 21:29:32 2001 by
[email protected]
3
*
4
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
5
* All Rights Reserved.
6
*
7
* Permission is hereby granted, free of charge, to any person obtaining a
8
* copy of this software and associated documentation files (the "Software"),
9
* to deal in the Software without restriction, including without limitation
10
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
* and/or sell copies of the Software, and to permit persons to whom the
12
* Software is furnished to do so, subject to the following conditions:
13
*
14
* The above copyright notice and this permission notice (including the next
15
* paragraph) shall be included in all copies or substantial portions of the
16
* Software.
17
*
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
* OTHER DEALINGS IN THE SOFTWARE.
25
*
26
* Authors:
27
* Gareth Hughes <
[email protected]
>
28
*/
29
30
#include <
linux/firmware.h
>
31
#include <
linux/ihex.h
>
32
#include <
linux/platform_device.h
>
33
#include <linux/module.h>
34
35
#include <
drm/drmP.h
>
36
#include <
drm/mga_drm.h
>
37
#include "
mga_drv.h
"
38
39
#define FIRMWARE_G200 "matrox/g200_warp.fw"
40
#define FIRMWARE_G400 "matrox/g400_warp.fw"
41
42
MODULE_FIRMWARE
(
FIRMWARE_G200
);
43
MODULE_FIRMWARE
(
FIRMWARE_G400
);
44
45
#define MGA_WARP_CODE_ALIGN 256
/* in bytes */
46
47
#define WARP_UCODE_SIZE(size) ALIGN(size, MGA_WARP_CODE_ALIGN)
48
49
int
mga_warp_install_microcode
(
drm_mga_private_t
*
dev_priv
)
50
{
51
unsigned
char
*vcbase = dev_priv->
warp
->handle;
52
unsigned
long
pcbase = dev_priv->
warp
->offset;
53
const
char
*firmware_name;
54
struct
platform_device
*
pdev
;
55
const
struct
firmware
*
fw
=
NULL
;
56
const
struct
ihex_binrec
*rec;
57
unsigned
int
size
;
58
int
n_pipes, where;
59
int
rc
= 0;
60
61
switch
(dev_priv->
chipset
) {
62
case
MGA_CARD_TYPE_G400
:
63
case
MGA_CARD_TYPE_G550
:
64
firmware_name =
FIRMWARE_G400
;
65
n_pipes =
MGA_MAX_G400_PIPES
;
66
break
;
67
case
MGA_CARD_TYPE_G200
:
68
firmware_name =
FIRMWARE_G200
;
69
n_pipes =
MGA_MAX_G200_PIPES
;
70
break
;
71
default
:
72
return
-
EINVAL
;
73
}
74
75
pdev = platform_device_register_simple(
"mga_warp"
, 0,
NULL
, 0);
76
if
(IS_ERR(pdev)) {
77
DRM_ERROR(
"mga: Failed to register microcode\n"
);
78
return
PTR_ERR(pdev);
79
}
80
rc = request_ihex_firmware(&fw, firmware_name, &pdev->
dev
);
81
platform_device_unregister
(pdev);
82
if
(rc) {
83
DRM_ERROR(
"mga: Failed to load microcode \"%s\"\n"
,
84
firmware_name);
85
return
rc
;
86
}
87
88
size = 0;
89
where = 0;
90
for
(rec = (
const
struct
ihex_binrec
*)fw->
data
;
91
rec;
92
rec = ihex_next_binrec(rec)) {
93
size +=
WARP_UCODE_SIZE
(
be16_to_cpu
(rec->
len
));
94
where++;
95
}
96
97
if
(where != n_pipes) {
98
DRM_ERROR(
"mga: Invalid microcode \"%s\"\n"
, firmware_name);
99
rc = -
EINVAL
;
100
goto
out
;
101
}
102
size =
PAGE_ALIGN
(size);
103
DRM_DEBUG(
"MGA ucode size = %d bytes\n"
, size);
104
if
(size > dev_priv->
warp
->size) {
105
DRM_ERROR(
"microcode too large! (%u > %lu)\n"
,
106
size, dev_priv->
warp
->size);
107
rc = -
ENOMEM
;
108
goto
out
;
109
}
110
111
memset
(dev_priv->
warp_pipe_phys
, 0,
sizeof
(dev_priv->
warp_pipe_phys
));
112
113
where = 0;
114
for
(rec = (
const
struct
ihex_binrec
*)fw->
data
;
115
rec;
116
rec = ihex_next_binrec(rec)) {
117
unsigned
int
src_size,
dst_size
;
118
119
DRM_DEBUG(
" pcbase = 0x%08lx vcbase = %p\n"
, pcbase, vcbase);
120
dev_priv->
warp_pipe_phys
[where] = pcbase;
121
src_size =
be16_to_cpu
(rec->
len
);
122
dst_size =
WARP_UCODE_SIZE
(src_size);
123
memcpy
(vcbase, rec->
data
, src_size);
124
pcbase +=
dst_size
;
125
vcbase +=
dst_size
;
126
where++;
127
}
128
129
out
:
130
release_firmware
(fw);
131
return
rc
;
132
}
133
134
#define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE)
135
136
int
mga_warp_init
(
drm_mga_private_t
*
dev_priv
)
137
{
138
u32
wmisc;
139
140
/* FIXME: Get rid of these damned magic numbers...
141
*/
142
switch
(dev_priv->
chipset
) {
143
case
MGA_CARD_TYPE_G400
:
144
case
MGA_CARD_TYPE_G550
:
145
MGA_WRITE
(
MGA_WIADDR2
,
MGA_WMODE_SUSPEND
);
146
MGA_WRITE
(
MGA_WGETMSB
, 0x00000E00);
147
MGA_WRITE
(
MGA_WVRTXSZ
, 0x00001807);
148
MGA_WRITE
(
MGA_WACCEPTSEQ
, 0x18000000);
149
break
;
150
case
MGA_CARD_TYPE_G200
:
151
MGA_WRITE
(
MGA_WIADDR
,
MGA_WMODE_SUSPEND
);
152
MGA_WRITE
(
MGA_WGETMSB
, 0x1606);
153
MGA_WRITE
(
MGA_WVRTXSZ
, 7);
154
break
;
155
default
:
156
return
-
EINVAL
;
157
}
158
159
MGA_WRITE
(
MGA_WMISC
, (
MGA_WUCODECACHE_ENABLE
|
160
MGA_WMASTER_ENABLE
|
MGA_WCACHEFLUSH_ENABLE
));
161
wmisc =
MGA_READ
(
MGA_WMISC
);
162
if
(wmisc !=
WMISC_EXPECTED
) {
163
DRM_ERROR(
"WARP engine config failed! 0x%x != 0x%x\n"
,
164
wmisc,
WMISC_EXPECTED
);
165
return
-
EINVAL
;
166
}
167
168
return
0;
169
}
Generated on Thu Jan 10 2013 13:32:03 for Linux Kernel by
1.8.2