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 <airlied@redhat.com>
27 */
28
29#include <linux/aperture.h>
30#include <linux/module.h>
31#include <linux/of.h>
32#include <linux/pci.h>
33
34#include <drm/clients/drm_client_setup.h>
35#include <drm/drm_atomic_helper.h>
36#include <drm/drm_drv.h>
37#include <drm/drm_fbdev_shmem.h>
38#include <drm/drm_gem_shmem_helper.h>
39#include <drm/drm_module.h>
40#include <drm/drm_print.h>
41#include <drm/drm_probe_helper.h>
42
43#include "ast_drv.h"
44
45static int ast_modeset = -1;
46
47MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
48module_param_named(modeset, ast_modeset, int, 0400);
49
50void ast_device_init(struct ast_device *ast,
51 enum ast_chip chip,
52 enum ast_config_mode config_mode,
53 void __iomem *regs,
54 void __iomem *ioregs,
55 const struct ast_device_quirks *quirks)
56{
57 ast->quirks = quirks;
58 ast->chip = chip;
59 ast->config_mode = config_mode;
60 ast->regs = regs;
61 ast->ioregs = ioregs;
62}
63
64void __ast_device_set_tx_chip(struct ast_device *ast, enum ast_tx_chip tx_chip)
65{
66 static const char * const info_str[] = {
67 "analog VGA",
68 "Sil164 TMDS transmitter",
69 "DP501 DisplayPort transmitter",
70 "ASPEED DisplayPort transmitter",
71 };
72
73 drm_info(&ast->base, "Using %s\n", info_str[tx_chip]);
74
75 ast->tx_chip = tx_chip;
76}
77
78/*
79 * DRM driver
80 */
81
82DEFINE_DRM_GEM_FOPS(ast_fops);
83
84static const struct drm_driver ast_driver = {
85 .driver_features = DRIVER_ATOMIC |
86 DRIVER_GEM |
87 DRIVER_MODESET,
88
89 .fops = &ast_fops,
90 .name = DRIVER_NAME,
91 .desc = DRIVER_DESC,
92 .major = DRIVER_MAJOR,
93 .minor = DRIVER_MINOR,
94 .patchlevel = DRIVER_PATCHLEVEL,
95
96 DRM_GEM_SHMEM_DRIVER_OPS,
97 DRM_FBDEV_SHMEM_DRIVER_OPS,
98};
99
100/*
101 * PCI driver
102 */
103
104#define PCI_VENDOR_ASPEED 0x1a03
105
106#define AST_VGA_DEVICE(id, info) { \
107 .class = PCI_BASE_CLASS_DISPLAY << 16, \
108 .class_mask = 0xff0000, \
109 .vendor = PCI_VENDOR_ASPEED, \
110 .device = id, \
111 .subvendor = PCI_ANY_ID, \
112 .subdevice = PCI_ANY_ID, \
113 .driver_data = (unsigned long) info }
114
115static const struct pci_device_id ast_pciidlist[] = {
116 AST_VGA_DEVICE(PCI_CHIP_AST2000, NULL),
117 AST_VGA_DEVICE(PCI_CHIP_AST2100, NULL),
118 {0, 0, 0},
119};
120
121MODULE_DEVICE_TABLE(pci, ast_pciidlist);
122
123static bool ast_is_vga_enabled(void __iomem *ioregs)
124{
125 u8 vgaer = __ast_read8(addr: ioregs, AST_IO_VGAER);
126
127 return vgaer & AST_IO_VGAER_VGA_ENABLE;
128}
129
130static void ast_enable_vga(void __iomem *ioregs)
131{
132 __ast_write8(addr: ioregs, AST_IO_VGAER, AST_IO_VGAER_VGA_ENABLE);
133 __ast_write8(addr: ioregs, AST_IO_VGAMR_W, AST_IO_VGAMR_IOSEL);
134}
135
136/*
137 * Run this function as part of the HW device cleanup; not
138 * when the DRM device gets released.
139 */
140static void ast_enable_mmio_release(void *data)
141{
142 void __iomem *ioregs = (void __force __iomem *)data;
143
144 /* enable standard VGA decode */
145 __ast_write8_i(addr: ioregs, AST_IO_VGACRI, index: 0xa1, AST_IO_VGACRA1_MMIO_ENABLED);
146}
147
148static int ast_enable_mmio(struct device *dev, void __iomem *ioregs)
149{
150 void *data = (void __force *)ioregs;
151
152 __ast_write8_i(addr: ioregs, AST_IO_VGACRI, index: 0xa1,
153 AST_IO_VGACRA1_MMIO_ENABLED |
154 AST_IO_VGACRA1_VGAIO_DISABLED);
155
156 return devm_add_action_or_reset(dev, ast_enable_mmio_release, data);
157}
158
159static void ast_open_key(void __iomem *ioregs)
160{
161 __ast_write8_i(addr: ioregs, AST_IO_VGACRI, index: 0x80, AST_IO_VGACR80_PASSWORD);
162}
163
164static int ast_detect_chip(struct pci_dev *pdev,
165 void __iomem *regs, void __iomem *ioregs,
166 enum ast_chip *chip_out,
167 enum ast_config_mode *config_mode_out)
168{
169 struct device *dev = &pdev->dev;
170 struct device_node *np = dev->of_node;
171 enum ast_config_mode config_mode = ast_use_defaults;
172 uint32_t scu_rev = 0xffffffff;
173 enum ast_chip chip;
174 u32 data;
175 u8 vgacrd0, vgacrd1;
176
177 /*
178 * Find configuration mode and read SCU revision
179 */
180
181 /* Check if we have device-tree properties */
182 if (np && !of_property_read_u32(np, propname: "aspeed,scu-revision-id", out_value: &data)) {
183 /* We do, disable P2A access */
184 config_mode = ast_use_dt;
185 scu_rev = data;
186 } else if (pdev->device == PCI_CHIP_AST2000) { // Not all families have a P2A bridge
187 /*
188 * The BMC will set SCU 0x40 D[12] to 1 if the P2 bridge
189 * is disabled. We force using P2A if VGA only mode bit
190 * is set D[7]
191 */
192 vgacrd0 = __ast_read8_i(addr: ioregs, AST_IO_VGACRI, index: 0xd0);
193 vgacrd1 = __ast_read8_i(addr: ioregs, AST_IO_VGACRI, index: 0xd1);
194 if (!(vgacrd0 & 0x80) || !(vgacrd1 & 0x10)) {
195
196 /*
197 * We have a P2A bridge and it is enabled.
198 */
199
200 /* Patch AST2500/AST2510 */
201 if ((pdev->revision & 0xf0) == 0x40) {
202 if (!(vgacrd0 & AST_IO_VGACRD0_VRAM_INIT_STATUS_MASK))
203 ast_2500_patch_ahb(regs);
204 }
205
206 /* Double check that it's actually working */
207 data = __ast_read32(addr: regs, reg: 0xf004);
208 if ((data != 0xffffffff) && (data != 0x00)) {
209 config_mode = ast_use_p2a;
210
211 /* Read SCU7c (silicon revision register) */
212 __ast_write32(addr: regs, reg: 0xf004, val: 0x1e6e0000);
213 __ast_write32(addr: regs, reg: 0xf000, val: 0x1);
214 scu_rev = __ast_read32(addr: regs, reg: 0x1207c);
215 }
216 }
217 }
218
219 switch (config_mode) {
220 case ast_use_defaults:
221 dev_info(dev, "Using default configuration\n");
222 break;
223 case ast_use_dt:
224 dev_info(dev, "Using device-tree for configuration\n");
225 break;
226 case ast_use_p2a:
227 dev_info(dev, "Using P2A bridge for configuration\n");
228 break;
229 }
230
231 /*
232 * Identify chipset
233 */
234
235 if (pdev->revision >= 0x50) {
236 chip = AST2600;
237 dev_info(dev, "AST 2600 detected\n");
238 } else if (pdev->revision >= 0x40) {
239 switch (scu_rev & 0x300) {
240 case 0x0100:
241 chip = AST2510;
242 dev_info(dev, "AST 2510 detected\n");
243 break;
244 default:
245 chip = AST2500;
246 dev_info(dev, "AST 2500 detected\n");
247 break;
248 }
249 } else if (pdev->revision >= 0x30) {
250 switch (scu_rev & 0x300) {
251 case 0x0100:
252 chip = AST1400;
253 dev_info(dev, "AST 1400 detected\n");
254 break;
255 default:
256 chip = AST2400;
257 dev_info(dev, "AST 2400 detected\n");
258 break;
259 }
260 } else if (pdev->revision >= 0x20) {
261 switch (scu_rev & 0x300) {
262 case 0x0000:
263 chip = AST1300;
264 dev_info(dev, "AST 1300 detected\n");
265 break;
266 default:
267 chip = AST2300;
268 dev_info(dev, "AST 2300 detected\n");
269 break;
270 }
271 } else if (pdev->revision >= 0x10) {
272 switch (scu_rev & 0x0300) {
273 case 0x0200:
274 chip = AST1100;
275 dev_info(dev, "AST 1100 detected\n");
276 break;
277 case 0x0100:
278 chip = AST2200;
279 dev_info(dev, "AST 2200 detected\n");
280 break;
281 case 0x0000:
282 chip = AST2150;
283 dev_info(dev, "AST 2150 detected\n");
284 break;
285 default:
286 chip = AST2100;
287 dev_info(dev, "AST 2100 detected\n");
288 break;
289 }
290 } else {
291 chip = AST2000;
292 dev_info(dev, "AST 2000 detected\n");
293 }
294
295 *chip_out = chip;
296 *config_mode_out = config_mode;
297
298 return __AST_CHIP_GEN(chip);
299}
300
301static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
302{
303 struct device *dev = &pdev->dev;
304 int ret;
305 void __iomem *regs;
306 void __iomem *ioregs;
307 enum ast_config_mode config_mode;
308 enum ast_chip chip;
309 unsigned int chip_gen;
310 struct drm_device *drm;
311 bool need_post = false;
312
313 ret = aperture_remove_conflicting_pci_devices(pdev, name: ast_driver.name);
314 if (ret)
315 return ret;
316
317 ret = pcim_enable_device(pdev);
318 if (ret)
319 return ret;
320
321 regs = pcim_iomap_region(pdev, bar: 1, name: "ast");
322 if (IS_ERR(ptr: regs))
323 return PTR_ERR(ptr: regs);
324
325 if (pdev->revision >= 0x40) {
326 /*
327 * On AST2500 and later models, MMIO is enabled by
328 * default. Adopt it to be compatible with ARM.
329 */
330 resource_size_t len = pci_resource_len(pdev, 1);
331
332 if (len < AST_IO_MM_OFFSET)
333 return -EIO;
334 if ((len - AST_IO_MM_OFFSET) < AST_IO_MM_LENGTH)
335 return -EIO;
336 ioregs = regs + AST_IO_MM_OFFSET;
337 } else if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) {
338 /*
339 * Map I/O registers if we have a PCI BAR for I/O.
340 */
341 resource_size_t len = pci_resource_len(pdev, 2);
342
343 if (len < AST_IO_MM_LENGTH)
344 return -EIO;
345 ioregs = pcim_iomap_region(pdev, bar: 2, name: "ast");
346 if (IS_ERR(ptr: ioregs))
347 return PTR_ERR(ptr: ioregs);
348 } else {
349 /*
350 * Anything else is best effort.
351 */
352 resource_size_t len = pci_resource_len(pdev, 1);
353
354 if (len < AST_IO_MM_OFFSET)
355 return -EIO;
356 if ((len - AST_IO_MM_OFFSET) < AST_IO_MM_LENGTH)
357 return -EIO;
358 ioregs = regs + AST_IO_MM_OFFSET;
359
360 dev_info(dev, "Platform has no I/O space, using MMIO\n");
361 }
362
363 if (!ast_is_vga_enabled(ioregs)) {
364 dev_info(dev, "VGA not enabled on entry, requesting chip POST\n");
365 need_post = true;
366 }
367
368 /*
369 * If VGA isn't enabled, we need to enable now or subsequent
370 * access to the scratch registers will fail.
371 */
372 if (need_post)
373 ast_enable_vga(ioregs);
374 /* Enable extended register access */
375 ast_open_key(ioregs);
376
377 ret = ast_enable_mmio(dev, ioregs);
378 if (ret)
379 return ret;
380
381 ret = ast_detect_chip(pdev, regs, ioregs, chip_out: &chip, config_mode_out: &config_mode);
382 if (ret < 0)
383 return ret;
384 chip_gen = ret;
385
386 switch (chip_gen) {
387 case 1:
388 drm = ast_2000_device_create(pdev, drv: &ast_driver, chip, config_mode,
389 regs, ioregs, need_post);
390 break;
391 case 2:
392 drm = ast_2100_device_create(pdev, drv: &ast_driver, chip, config_mode,
393 regs, ioregs, need_post);
394 break;
395 case 3:
396 drm = ast_2200_device_create(pdev, drv: &ast_driver, chip, config_mode,
397 regs, ioregs, need_post);
398 break;
399 case 4:
400 drm = ast_2300_device_create(pdev, drv: &ast_driver, chip, config_mode,
401 regs, ioregs, need_post);
402 break;
403 case 5:
404 drm = ast_2400_device_create(pdev, drv: &ast_driver, chip, config_mode,
405 regs, ioregs, need_post);
406 break;
407 case 6:
408 drm = ast_2500_device_create(pdev, drv: &ast_driver, chip, config_mode,
409 regs, ioregs, need_post);
410 break;
411 case 7:
412 drm = ast_2600_device_create(pdev, drv: &ast_driver, chip, config_mode,
413 regs, ioregs, need_post);
414 break;
415 default:
416 dev_err(&pdev->dev, "Gen%d not supported\n", chip_gen);
417 return -ENODEV;
418 }
419 if (IS_ERR(ptr: drm))
420 return PTR_ERR(ptr: drm);
421 pci_set_drvdata(pdev, data: drm);
422
423 ret = drm_dev_register(dev: drm, flags: ent->driver_data);
424 if (ret)
425 return ret;
426
427 drm_client_setup(dev: drm, NULL);
428
429 return 0;
430}
431
432static void ast_pci_remove(struct pci_dev *pdev)
433{
434 struct drm_device *dev = pci_get_drvdata(pdev);
435
436 drm_dev_unregister(dev);
437 drm_atomic_helper_shutdown(dev);
438}
439
440static void ast_pci_shutdown(struct pci_dev *pdev)
441{
442 drm_atomic_helper_shutdown(dev: pci_get_drvdata(pdev));
443}
444
445static int ast_drm_freeze(struct drm_device *dev)
446{
447 int error;
448
449 error = drm_mode_config_helper_suspend(dev);
450 if (error)
451 return error;
452 pci_save_state(to_pci_dev(dev->dev));
453 return 0;
454}
455
456static int ast_drm_thaw(struct drm_device *dev)
457{
458 struct ast_device *ast = to_ast_device(dev);
459 int ret;
460
461 ast_enable_vga(ioregs: ast->ioregs);
462 ast_open_key(ioregs: ast->ioregs);
463 ast_enable_mmio(dev: dev->dev, ioregs: ast->ioregs);
464
465 ret = ast_post_gpu(ast);
466 if (ret)
467 return ret;
468
469 return drm_mode_config_helper_resume(dev);
470}
471
472static int ast_drm_resume(struct drm_device *dev)
473{
474 if (pci_enable_device(to_pci_dev(dev->dev)))
475 return -EIO;
476
477 return ast_drm_thaw(dev);
478}
479
480static int ast_pm_suspend(struct device *dev)
481{
482 struct pci_dev *pdev = to_pci_dev(dev);
483 struct drm_device *ddev = pci_get_drvdata(pdev);
484 int error;
485
486 error = ast_drm_freeze(dev: ddev);
487 if (error)
488 return error;
489
490 pci_disable_device(dev: pdev);
491 pci_set_power_state(dev: pdev, PCI_D3hot);
492 return 0;
493}
494
495static int ast_pm_resume(struct device *dev)
496{
497 struct pci_dev *pdev = to_pci_dev(dev);
498 struct drm_device *ddev = pci_get_drvdata(pdev);
499 return ast_drm_resume(dev: ddev);
500}
501
502static int ast_pm_freeze(struct device *dev)
503{
504 struct pci_dev *pdev = to_pci_dev(dev);
505 struct drm_device *ddev = pci_get_drvdata(pdev);
506 return ast_drm_freeze(dev: ddev);
507}
508
509static int ast_pm_thaw(struct device *dev)
510{
511 struct pci_dev *pdev = to_pci_dev(dev);
512 struct drm_device *ddev = pci_get_drvdata(pdev);
513 return ast_drm_thaw(dev: ddev);
514}
515
516static int ast_pm_poweroff(struct device *dev)
517{
518 struct pci_dev *pdev = to_pci_dev(dev);
519 struct drm_device *ddev = pci_get_drvdata(pdev);
520
521 return ast_drm_freeze(dev: ddev);
522}
523
524static const struct dev_pm_ops ast_pm_ops = {
525 .suspend = ast_pm_suspend,
526 .resume = ast_pm_resume,
527 .freeze = ast_pm_freeze,
528 .thaw = ast_pm_thaw,
529 .poweroff = ast_pm_poweroff,
530 .restore = ast_pm_resume,
531};
532
533static struct pci_driver ast_pci_driver = {
534 .name = DRIVER_NAME,
535 .id_table = ast_pciidlist,
536 .probe = ast_pci_probe,
537 .remove = ast_pci_remove,
538 .shutdown = ast_pci_shutdown,
539 .driver.pm = &ast_pm_ops,
540};
541
542drm_module_pci_driver_if_modeset(ast_pci_driver, ast_modeset);
543
544MODULE_AUTHOR(DRIVER_AUTHOR);
545MODULE_DESCRIPTION(DRIVER_DESC);
546MODULE_LICENSE("GPL and additional rights");
547

source code of linux/drivers/gpu/drm/ast/ast_drv.c