Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/gpu/drm/ast/ast_main.c
29281 views
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 <[email protected]>
27
*/
28
29
#include <linux/of.h>
30
#include <linux/pci.h>
31
32
#include <drm/drm_atomic_helper.h>
33
#include <drm/drm_drv.h>
34
#include <drm/drm_gem.h>
35
#include <drm/drm_managed.h>
36
37
#include "ast_drv.h"
38
39
/* Try to detect WSXGA+ on Gen2+ */
40
static bool __ast_2100_detect_wsxga_p(struct ast_device *ast)
41
{
42
u8 vgacrd0 = ast_get_index_reg(ast, AST_IO_VGACRI, 0xd0);
43
44
if (!(vgacrd0 & AST_IO_VGACRD0_VRAM_INIT_BY_BMC))
45
return true;
46
if (vgacrd0 & AST_IO_VGACRD0_IKVM_WIDESCREEN)
47
return true;
48
49
return false;
50
}
51
52
/* Try to detect WUXGA on Gen2+ */
53
static bool __ast_2100_detect_wuxga(struct ast_device *ast)
54
{
55
u8 vgacrd1;
56
57
if (ast->support_fullhd) {
58
vgacrd1 = ast_get_index_reg(ast, AST_IO_VGACRI, 0xd1);
59
if (!(vgacrd1 & AST_IO_VGACRD1_SUPPORTS_WUXGA))
60
return true;
61
}
62
63
return false;
64
}
65
66
static void ast_detect_widescreen(struct ast_device *ast)
67
{
68
ast->support_wsxga_p = false;
69
ast->support_fullhd = false;
70
ast->support_wuxga = false;
71
72
if (AST_GEN(ast) >= 7) {
73
ast->support_wsxga_p = true;
74
ast->support_fullhd = true;
75
if (__ast_2100_detect_wuxga(ast))
76
ast->support_wuxga = true;
77
} else if (AST_GEN(ast) >= 6) {
78
if (__ast_2100_detect_wsxga_p(ast))
79
ast->support_wsxga_p = true;
80
else if (ast->chip == AST2510)
81
ast->support_wsxga_p = true;
82
if (ast->support_wsxga_p)
83
ast->support_fullhd = true;
84
if (__ast_2100_detect_wuxga(ast))
85
ast->support_wuxga = true;
86
} else if (AST_GEN(ast) >= 5) {
87
if (__ast_2100_detect_wsxga_p(ast))
88
ast->support_wsxga_p = true;
89
else if (ast->chip == AST1400)
90
ast->support_wsxga_p = true;
91
if (ast->support_wsxga_p)
92
ast->support_fullhd = true;
93
if (__ast_2100_detect_wuxga(ast))
94
ast->support_wuxga = true;
95
} else if (AST_GEN(ast) >= 4) {
96
if (__ast_2100_detect_wsxga_p(ast))
97
ast->support_wsxga_p = true;
98
else if (ast->chip == AST1300)
99
ast->support_wsxga_p = true;
100
if (ast->support_wsxga_p)
101
ast->support_fullhd = true;
102
if (__ast_2100_detect_wuxga(ast))
103
ast->support_wuxga = true;
104
} else if (AST_GEN(ast) >= 3) {
105
if (__ast_2100_detect_wsxga_p(ast))
106
ast->support_wsxga_p = true;
107
if (ast->support_wsxga_p) {
108
if (ast->chip == AST2200)
109
ast->support_fullhd = true;
110
}
111
if (__ast_2100_detect_wuxga(ast))
112
ast->support_wuxga = true;
113
} else if (AST_GEN(ast) >= 2) {
114
if (__ast_2100_detect_wsxga_p(ast))
115
ast->support_wsxga_p = true;
116
if (ast->support_wsxga_p) {
117
if (ast->chip == AST2100)
118
ast->support_fullhd = true;
119
}
120
if (__ast_2100_detect_wuxga(ast))
121
ast->support_wuxga = true;
122
}
123
}
124
125
static void ast_detect_tx_chip(struct ast_device *ast, bool need_post)
126
{
127
static const char * const info_str[] = {
128
"analog VGA",
129
"Sil164 TMDS transmitter",
130
"DP501 DisplayPort transmitter",
131
"ASPEED DisplayPort transmitter",
132
};
133
134
struct drm_device *dev = &ast->base;
135
u8 vgacra3, vgacrd1;
136
137
/* Check 3rd Tx option (digital output afaik) */
138
ast->tx_chip = AST_TX_NONE;
139
140
if (AST_GEN(ast) <= 3) {
141
/*
142
* VGACRA3 Enhanced Color Mode Register, check if DVO is already
143
* enabled, in that case, assume we have a SIL164 TMDS transmitter
144
*
145
* Don't make that assumption if we the chip wasn't enabled and
146
* is at power-on reset, otherwise we'll incorrectly "detect" a
147
* SIL164 when there is none.
148
*/
149
if (!need_post) {
150
vgacra3 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xff);
151
if (vgacra3 & AST_IO_VGACRA3_DVO_ENABLED)
152
ast->tx_chip = AST_TX_SIL164;
153
}
154
} else {
155
/*
156
* On AST GEN4+, look at the configuration set by the SoC in
157
* the SOC scratch register #1 bits 11:8 (interestingly marked
158
* as "reserved" in the spec)
159
*/
160
vgacrd1 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1,
161
AST_IO_VGACRD1_TX_TYPE_MASK);
162
switch (vgacrd1) {
163
/*
164
* GEN4 to GEN6
165
*/
166
case AST_IO_VGACRD1_TX_SIL164_VBIOS:
167
ast->tx_chip = AST_TX_SIL164;
168
break;
169
case AST_IO_VGACRD1_TX_DP501_VBIOS:
170
ast->dp501_fw_addr = drmm_kzalloc(dev, 32*1024, GFP_KERNEL);
171
if (ast->dp501_fw_addr) {
172
/* backup firmware */
173
if (ast_backup_fw(ast, ast->dp501_fw_addr, 32*1024)) {
174
drmm_kfree(dev, ast->dp501_fw_addr);
175
ast->dp501_fw_addr = NULL;
176
}
177
}
178
fallthrough;
179
case AST_IO_VGACRD1_TX_FW_EMBEDDED_FW:
180
ast->tx_chip = AST_TX_DP501;
181
break;
182
/*
183
* GEN7+
184
*/
185
case AST_IO_VGACRD1_TX_ASTDP:
186
ast->tx_chip = AST_TX_ASTDP;
187
break;
188
/*
189
* Several of the listed TX chips are not explicitly supported
190
* by the ast driver. If these exist in real-world devices, they
191
* are most likely reported as VGA or SIL164 outputs. We warn here
192
* to get bug reports for these devices. If none come in for some
193
* time, we can begin to fail device probing on these values.
194
*/
195
case AST_IO_VGACRD1_TX_ITE66121_VBIOS:
196
drm_warn(dev, "ITE IT66121 detected, 0x%x, Gen%lu\n",
197
vgacrd1, AST_GEN(ast));
198
break;
199
case AST_IO_VGACRD1_TX_CH7003_VBIOS:
200
drm_warn(dev, "Chrontel CH7003 detected, 0x%x, Gen%lu\n",
201
vgacrd1, AST_GEN(ast));
202
break;
203
case AST_IO_VGACRD1_TX_ANX9807_VBIOS:
204
drm_warn(dev, "Analogix ANX9807 detected, 0x%x, Gen%lu\n",
205
vgacrd1, AST_GEN(ast));
206
break;
207
}
208
}
209
210
drm_info(dev, "Using %s\n", info_str[ast->tx_chip]);
211
}
212
213
struct drm_device *ast_device_create(struct pci_dev *pdev,
214
const struct drm_driver *drv,
215
enum ast_chip chip,
216
enum ast_config_mode config_mode,
217
void __iomem *regs,
218
void __iomem *ioregs,
219
bool need_post)
220
{
221
struct drm_device *dev;
222
struct ast_device *ast;
223
int ret;
224
225
ast = devm_drm_dev_alloc(&pdev->dev, drv, struct ast_device, base);
226
if (IS_ERR(ast))
227
return ERR_CAST(ast);
228
dev = &ast->base;
229
230
ast->chip = chip;
231
ast->config_mode = config_mode;
232
ast->regs = regs;
233
ast->ioregs = ioregs;
234
235
ast_detect_tx_chip(ast, need_post);
236
switch (ast->tx_chip) {
237
case AST_TX_ASTDP:
238
ret = ast_post_gpu(ast);
239
break;
240
default:
241
ret = 0;
242
if (need_post)
243
ret = ast_post_gpu(ast);
244
break;
245
}
246
if (ret)
247
return ERR_PTR(ret);
248
249
ret = ast_mm_init(ast);
250
if (ret)
251
return ERR_PTR(ret);
252
253
/* map reserved buffer */
254
ast->dp501_fw_buf = NULL;
255
if (ast->vram_size < pci_resource_len(pdev, 0)) {
256
ast->dp501_fw_buf = pci_iomap_range(pdev, 0, ast->vram_size, 0);
257
if (!ast->dp501_fw_buf)
258
drm_info(dev, "failed to map reserved buffer!\n");
259
}
260
261
ast_detect_widescreen(ast);
262
263
ret = ast_mode_config_init(ast);
264
if (ret)
265
return ERR_PTR(ret);
266
267
return dev;
268
}
269
270