hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/gpu/drm/ast/ast_dp501.c
....@@ -1,15 +1,31 @@
11 // SPDX-License-Identifier: GPL-2.0
22
3
+#include <linux/delay.h>
34 #include <linux/firmware.h>
4
-#include <drm/drmP.h>
5
+#include <linux/module.h>
6
+
57 #include "ast_drv.h"
8
+
69 MODULE_FIRMWARE("ast_dp501_fw.bin");
10
+
11
+static void ast_release_firmware(void *data)
12
+{
13
+ struct ast_private *ast = data;
14
+
15
+ release_firmware(ast->dp501_fw);
16
+ ast->dp501_fw = NULL;
17
+}
718
819 static int ast_load_dp501_microcode(struct drm_device *dev)
920 {
10
- struct ast_private *ast = dev->dev_private;
21
+ struct ast_private *ast = to_ast_private(dev);
22
+ int ret;
1123
12
- return request_firmware(&ast->dp501_fw, "ast_dp501_fw.bin", dev->dev);
24
+ ret = request_firmware(&ast->dp501_fw, "ast_dp501_fw.bin", dev->dev);
25
+ if (ret)
26
+ return ret;
27
+
28
+ return devm_add_action_or_reset(dev->dev, ast_release_firmware, ast);
1329 }
1430
1531 static void send_ack(struct ast_private *ast)
....@@ -90,7 +106,7 @@
90106
91107 static bool ast_write_cmd(struct drm_device *dev, u8 data)
92108 {
93
- struct ast_private *ast = dev->dev_private;
109
+ struct ast_private *ast = to_ast_private(dev);
94110 int retry = 0;
95111 if (wait_nack(ast)) {
96112 send_nack(ast);
....@@ -112,7 +128,7 @@
112128
113129 static bool ast_write_data(struct drm_device *dev, u8 data)
114130 {
115
- struct ast_private *ast = dev->dev_private;
131
+ struct ast_private *ast = to_ast_private(dev);
116132
117133 if (wait_nack(ast)) {
118134 send_nack(ast);
....@@ -130,7 +146,7 @@
130146 #if 0
131147 static bool ast_read_data(struct drm_device *dev, u8 *data)
132148 {
133
- struct ast_private *ast = dev->dev_private;
149
+ struct ast_private *ast = to_ast_private(dev);
134150 u8 tmp;
135151
136152 *data = 0;
....@@ -169,9 +185,12 @@
169185
170186 bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size)
171187 {
172
- struct ast_private *ast = dev->dev_private;
188
+ struct ast_private *ast = to_ast_private(dev);
173189 u32 i, data;
174190 u32 boot_address;
191
+
192
+ if (ast->config_mode != ast_use_p2a)
193
+ return false;
175194
176195 data = ast_mindwm(ast, 0x1e6e2100) & 0x01;
177196 if (data) {
....@@ -185,11 +204,14 @@
185204
186205 static bool ast_launch_m68k(struct drm_device *dev)
187206 {
188
- struct ast_private *ast = dev->dev_private;
207
+ struct ast_private *ast = to_ast_private(dev);
189208 u32 i, data, len = 0;
190209 u32 boot_address;
191210 u8 *fw_addr = NULL;
192211 u8 jreg;
212
+
213
+ if (ast->config_mode != ast_use_p2a)
214
+ return false;
193215
194216 data = ast_mindwm(ast, 0x1e6e2100) & 0x01;
195217 if (!data) {
....@@ -252,56 +274,117 @@
252274
253275 u8 ast_get_dp501_max_clk(struct drm_device *dev)
254276 {
255
- struct ast_private *ast = dev->dev_private;
277
+ struct ast_private *ast = to_ast_private(dev);
256278 u32 boot_address, offset, data;
257279 u8 linkcap[4], linkrate, linklanes, maxclk = 0xff;
280
+ u32 *plinkcap;
258281
259
- boot_address = get_fw_base(ast);
282
+ if (ast->config_mode == ast_use_p2a) {
283
+ boot_address = get_fw_base(ast);
260284
261
- /* validate FW version */
262
- offset = 0xf000;
263
- data = ast_mindwm(ast, boot_address + offset);
264
- if ((data & 0xf0) != 0x10) /* version: 1x */
265
- return maxclk;
285
+ /* validate FW version */
286
+ offset = AST_DP501_GBL_VERSION;
287
+ data = ast_mindwm(ast, boot_address + offset);
288
+ if ((data & AST_DP501_FW_VERSION_MASK) != AST_DP501_FW_VERSION_1) /* version: 1x */
289
+ return maxclk;
266290
267
- /* Read Link Capability */
268
- offset = 0xf014;
269
- *(u32 *)linkcap = ast_mindwm(ast, boot_address + offset);
270
- if (linkcap[2] == 0) {
271
- linkrate = linkcap[0];
272
- linklanes = linkcap[1];
273
- data = (linkrate == 0x0a) ? (90 * linklanes) : (54 * linklanes);
274
- if (data > 0xff)
275
- data = 0xff;
276
- maxclk = (u8)data;
291
+ /* Read Link Capability */
292
+ offset = AST_DP501_LINKRATE;
293
+ plinkcap = (u32 *)linkcap;
294
+ *plinkcap = ast_mindwm(ast, boot_address + offset);
295
+ if (linkcap[2] == 0) {
296
+ linkrate = linkcap[0];
297
+ linklanes = linkcap[1];
298
+ data = (linkrate == 0x0a) ? (90 * linklanes) : (54 * linklanes);
299
+ if (data > 0xff)
300
+ data = 0xff;
301
+ maxclk = (u8)data;
302
+ }
303
+ } else {
304
+ if (!ast->dp501_fw_buf)
305
+ return AST_DP501_DEFAULT_DCLK; /* 1024x768 as default */
306
+
307
+ /* dummy read */
308
+ offset = 0x0000;
309
+ data = readl(ast->dp501_fw_buf + offset);
310
+
311
+ /* validate FW version */
312
+ offset = AST_DP501_GBL_VERSION;
313
+ data = readl(ast->dp501_fw_buf + offset);
314
+ if ((data & AST_DP501_FW_VERSION_MASK) != AST_DP501_FW_VERSION_1) /* version: 1x */
315
+ return maxclk;
316
+
317
+ /* Read Link Capability */
318
+ offset = AST_DP501_LINKRATE;
319
+ plinkcap = (u32 *)linkcap;
320
+ *plinkcap = readl(ast->dp501_fw_buf + offset);
321
+ if (linkcap[2] == 0) {
322
+ linkrate = linkcap[0];
323
+ linklanes = linkcap[1];
324
+ data = (linkrate == 0x0a) ? (90 * linklanes) : (54 * linklanes);
325
+ if (data > 0xff)
326
+ data = 0xff;
327
+ maxclk = (u8)data;
328
+ }
277329 }
278330 return maxclk;
279331 }
280332
281333 bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata)
282334 {
283
- struct ast_private *ast = dev->dev_private;
335
+ struct ast_private *ast = to_ast_private(dev);
284336 u32 i, boot_address, offset, data;
337
+ u32 *pEDIDidx;
285338
286
- boot_address = get_fw_base(ast);
339
+ if (ast->config_mode == ast_use_p2a) {
340
+ boot_address = get_fw_base(ast);
287341
288
- /* validate FW version */
289
- offset = 0xf000;
290
- data = ast_mindwm(ast, boot_address + offset);
291
- if ((data & 0xf0) != 0x10)
292
- return false;
342
+ /* validate FW version */
343
+ offset = AST_DP501_GBL_VERSION;
344
+ data = ast_mindwm(ast, boot_address + offset);
345
+ if ((data & AST_DP501_FW_VERSION_MASK) != AST_DP501_FW_VERSION_1)
346
+ return false;
293347
294
- /* validate PnP Monitor */
295
- offset = 0xf010;
296
- data = ast_mindwm(ast, boot_address + offset);
297
- if (!(data & 0x01))
298
- return false;
348
+ /* validate PnP Monitor */
349
+ offset = AST_DP501_PNPMONITOR;
350
+ data = ast_mindwm(ast, boot_address + offset);
351
+ if (!(data & AST_DP501_PNP_CONNECTED))
352
+ return false;
299353
300
- /* Read EDID */
301
- offset = 0xf020;
302
- for (i = 0; i < 128; i += 4) {
303
- data = ast_mindwm(ast, boot_address + offset + i);
304
- *(u32 *)(ediddata + i) = data;
354
+ /* Read EDID */
355
+ offset = AST_DP501_EDID_DATA;
356
+ for (i = 0; i < 128; i += 4) {
357
+ data = ast_mindwm(ast, boot_address + offset + i);
358
+ pEDIDidx = (u32 *)(ediddata + i);
359
+ *pEDIDidx = data;
360
+ }
361
+ } else {
362
+ if (!ast->dp501_fw_buf)
363
+ return false;
364
+
365
+ /* dummy read */
366
+ offset = 0x0000;
367
+ data = readl(ast->dp501_fw_buf + offset);
368
+
369
+ /* validate FW version */
370
+ offset = AST_DP501_GBL_VERSION;
371
+ data = readl(ast->dp501_fw_buf + offset);
372
+ if ((data & AST_DP501_FW_VERSION_MASK) != AST_DP501_FW_VERSION_1)
373
+ return false;
374
+
375
+ /* validate PnP Monitor */
376
+ offset = AST_DP501_PNPMONITOR;
377
+ data = readl(ast->dp501_fw_buf + offset);
378
+ if (!(data & AST_DP501_PNP_CONNECTED))
379
+ return false;
380
+
381
+ /* Read EDID */
382
+ offset = AST_DP501_EDID_DATA;
383
+ for (i = 0; i < 128; i += 4) {
384
+ data = readl(ast->dp501_fw_buf + offset + i);
385
+ pEDIDidx = (u32 *)(ediddata + i);
386
+ *pEDIDidx = data;
387
+ }
305388 }
306389
307390 return true;
....@@ -309,7 +392,7 @@
309392
310393 static bool ast_init_dvo(struct drm_device *dev)
311394 {
312
- struct ast_private *ast = dev->dev_private;
395
+ struct ast_private *ast = to_ast_private(dev);
313396 u8 jreg;
314397 u32 data;
315398 ast_write32(ast, 0xf004, 0x1e6e0000);
....@@ -382,7 +465,7 @@
382465
383466 static void ast_init_analog(struct drm_device *dev)
384467 {
385
- struct ast_private *ast = dev->dev_private;
468
+ struct ast_private *ast = to_ast_private(dev);
386469 u32 data;
387470
388471 /*
....@@ -409,7 +492,7 @@
409492
410493 void ast_init_3rdtx(struct drm_device *dev)
411494 {
412
- struct ast_private *ast = dev->dev_private;
495
+ struct ast_private *ast = to_ast_private(dev);
413496 u8 jreg;
414497
415498 if (ast->chip == AST2300 || ast->chip == AST2400) {
....@@ -431,12 +514,4 @@
431514 ast_init_analog(dev);
432515 }
433516 }
434
-}
435
-
436
-void ast_release_firmware(struct drm_device *dev)
437
-{
438
- struct ast_private *ast = dev->dev_private;
439
-
440
- release_firmware(ast->dp501_fw);
441
- ast->dp501_fw = NULL;
442517 }