| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* $Id: aty128fb.c,v 1.1.1.1.36.1 1999/12/11 09:03:05 Exp $ |
|---|
| 2 | 3 | * linux/drivers/video/aty128fb.c -- Frame buffer device for ATI Rage128 |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 161 | 162 | static int aty128_probe(struct pci_dev *pdev, |
|---|
| 162 | 163 | const struct pci_device_id *ent); |
|---|
| 163 | 164 | static void aty128_remove(struct pci_dev *pdev); |
|---|
| 164 | | -static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state); |
|---|
| 165 | | -static int aty128_pci_resume(struct pci_dev *pdev); |
|---|
| 165 | +static int aty128_pci_suspend_late(struct device *dev, pm_message_t state); |
|---|
| 166 | +static int __maybe_unused aty128_pci_suspend(struct device *dev); |
|---|
| 167 | +static int __maybe_unused aty128_pci_hibernate(struct device *dev); |
|---|
| 168 | +static int __maybe_unused aty128_pci_freeze(struct device *dev); |
|---|
| 169 | +static int __maybe_unused aty128_pci_resume(struct device *dev); |
|---|
| 166 | 170 | static int aty128_do_resume(struct pci_dev *pdev); |
|---|
| 171 | + |
|---|
| 172 | +static const struct dev_pm_ops aty128_pci_pm_ops = { |
|---|
| 173 | + .suspend = aty128_pci_suspend, |
|---|
| 174 | + .resume = aty128_pci_resume, |
|---|
| 175 | + .freeze = aty128_pci_freeze, |
|---|
| 176 | + .thaw = aty128_pci_resume, |
|---|
| 177 | + .poweroff = aty128_pci_hibernate, |
|---|
| 178 | + .restore = aty128_pci_resume, |
|---|
| 179 | +}; |
|---|
| 167 | 180 | |
|---|
| 168 | 181 | /* supported Rage128 chipsets */ |
|---|
| 169 | 182 | static const struct pci_device_id aty128_pci_tbl[] = { |
|---|
| .. | .. |
|---|
| 271 | 284 | .id_table = aty128_pci_tbl, |
|---|
| 272 | 285 | .probe = aty128_probe, |
|---|
| 273 | 286 | .remove = aty128_remove, |
|---|
| 274 | | - .suspend = aty128_pci_suspend, |
|---|
| 275 | | - .resume = aty128_pci_resume, |
|---|
| 287 | + .driver.pm = &aty128_pci_pm_ops, |
|---|
| 276 | 288 | }; |
|---|
| 277 | 289 | |
|---|
| 278 | 290 | /* packed BIOS settings */ |
|---|
| .. | .. |
|---|
| 333 | 345 | .name = "128-bit SDR SGRAM (1:1)", |
|---|
| 334 | 346 | }; |
|---|
| 335 | 347 | |
|---|
| 336 | | -static const struct aty128_meminfo sdr_64 = { |
|---|
| 337 | | - .ML = 4, |
|---|
| 338 | | - .MB = 8, |
|---|
| 339 | | - .Trcd = 3, |
|---|
| 340 | | - .Trp = 3, |
|---|
| 341 | | - .Twr = 1, |
|---|
| 342 | | - .CL = 3, |
|---|
| 343 | | - .Tr2w = 1, |
|---|
| 344 | | - .LoopLatency = 17, |
|---|
| 345 | | - .DspOn = 46, |
|---|
| 346 | | - .Rloop = 17, |
|---|
| 347 | | - .name = "64-bit SDR SGRAM (1:1)", |
|---|
| 348 | | -}; |
|---|
| 349 | | - |
|---|
| 350 | 348 | static const struct aty128_meminfo sdr_sgram = { |
|---|
| 351 | 349 | .ML = 4, |
|---|
| 352 | 350 | .MB = 4, |
|---|
| .. | .. |
|---|
| 397 | 395 | static bool mtrr = true; |
|---|
| 398 | 396 | |
|---|
| 399 | 397 | #ifdef CONFIG_FB_ATY128_BACKLIGHT |
|---|
| 400 | | -#ifdef CONFIG_PMAC_BACKLIGHT |
|---|
| 401 | | -static int backlight = 1; |
|---|
| 402 | | -#else |
|---|
| 403 | | -static int backlight = 0; |
|---|
| 404 | | -#endif |
|---|
| 398 | +static int backlight = IS_BUILTIN(CONFIG_PMAC_BACKLIGHT); |
|---|
| 405 | 399 | #endif |
|---|
| 406 | 400 | |
|---|
| 407 | 401 | /* PLL constants */ |
|---|
| .. | .. |
|---|
| 486 | 480 | const struct aty128fb_par *par); |
|---|
| 487 | 481 | static int aty128_decode_var(struct fb_var_screeninfo *var, |
|---|
| 488 | 482 | struct aty128fb_par *par); |
|---|
| 489 | | -#if 0 |
|---|
| 490 | | -static void aty128_get_pllinfo(struct aty128fb_par *par, void __iomem *bios); |
|---|
| 491 | | -static void __iomem *aty128_map_ROM(struct pci_dev *pdev, |
|---|
| 492 | | - const struct aty128fb_par *par); |
|---|
| 493 | | -#endif |
|---|
| 494 | 483 | static void aty128_timings(struct aty128fb_par *par); |
|---|
| 495 | 484 | static void aty128_init_engine(struct aty128fb_par *par); |
|---|
| 496 | 485 | static void aty128_reset_engine(const struct aty128fb_par *par); |
|---|
| .. | .. |
|---|
| 513 | 502 | (readb(bios + (v) + 3) << 24)) |
|---|
| 514 | 503 | |
|---|
| 515 | 504 | |
|---|
| 516 | | -static struct fb_ops aty128fb_ops = { |
|---|
| 505 | +static const struct fb_ops aty128fb_ops = { |
|---|
| 517 | 506 | .owner = THIS_MODULE, |
|---|
| 518 | 507 | .fb_check_var = aty128fb_check_var, |
|---|
| 519 | 508 | .fb_set_par = aty128fb_set_par, |
|---|
| .. | .. |
|---|
| 1664 | 1653 | struct aty128fb_par *par) |
|---|
| 1665 | 1654 | { |
|---|
| 1666 | 1655 | if (par->chip_gen == rage_M3) { |
|---|
| 1667 | | -#if 0 |
|---|
| 1668 | | - /* Note: For now, on M3, we set palette on both heads, which may |
|---|
| 1669 | | - * be useless. Can someone with a M3 check this ? |
|---|
| 1670 | | - * |
|---|
| 1671 | | - * This code would still be useful if using the second CRTC to |
|---|
| 1672 | | - * do mirroring |
|---|
| 1673 | | - */ |
|---|
| 1674 | | - |
|---|
| 1675 | | - aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | |
|---|
| 1676 | | - DAC_PALETTE_ACCESS_CNTL); |
|---|
| 1677 | | - aty_st_8(PALETTE_INDEX, regno); |
|---|
| 1678 | | - aty_st_le32(PALETTE_DATA, (red<<16)|(green<<8)|blue); |
|---|
| 1679 | | -#endif |
|---|
| 1680 | 1656 | aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & |
|---|
| 1681 | 1657 | ~DAC_PALETTE_ACCESS_CNTL); |
|---|
| 1682 | 1658 | } |
|---|
| .. | .. |
|---|
| 2102 | 2078 | |
|---|
| 2103 | 2079 | /* We have the resources. Now virtualize them */ |
|---|
| 2104 | 2080 | info = framebuffer_alloc(sizeof(struct aty128fb_par), &pdev->dev); |
|---|
| 2105 | | - if (info == NULL) { |
|---|
| 2106 | | - printk(KERN_ERR "aty128fb: can't alloc fb_info_aty128\n"); |
|---|
| 2081 | + if (!info) |
|---|
| 2107 | 2082 | goto err_free_mmio; |
|---|
| 2108 | | - } |
|---|
| 2083 | + |
|---|
| 2109 | 2084 | par = info->par; |
|---|
| 2110 | 2085 | |
|---|
| 2111 | 2086 | info->pseudo_palette = par->pseudo_palette; |
|---|
| .. | .. |
|---|
| 2349 | 2324 | return -EINVAL; |
|---|
| 2350 | 2325 | } |
|---|
| 2351 | 2326 | |
|---|
| 2352 | | -#if 0 |
|---|
| 2353 | | - /* |
|---|
| 2354 | | - * Accelerated functions |
|---|
| 2355 | | - */ |
|---|
| 2356 | | - |
|---|
| 2357 | | -static inline void aty128_rectcopy(int srcx, int srcy, int dstx, int dsty, |
|---|
| 2358 | | - u_int width, u_int height, |
|---|
| 2359 | | - struct fb_info_aty128 *par) |
|---|
| 2360 | | -{ |
|---|
| 2361 | | - u32 save_dp_datatype, save_dp_cntl, dstval; |
|---|
| 2362 | | - |
|---|
| 2363 | | - if (!width || !height) |
|---|
| 2364 | | - return; |
|---|
| 2365 | | - |
|---|
| 2366 | | - dstval = depth_to_dst(par->current_par.crtc.depth); |
|---|
| 2367 | | - if (dstval == DST_24BPP) { |
|---|
| 2368 | | - srcx *= 3; |
|---|
| 2369 | | - dstx *= 3; |
|---|
| 2370 | | - width *= 3; |
|---|
| 2371 | | - } else if (dstval == -EINVAL) { |
|---|
| 2372 | | - printk("aty128fb: invalid depth or RGBA\n"); |
|---|
| 2373 | | - return; |
|---|
| 2374 | | - } |
|---|
| 2375 | | - |
|---|
| 2376 | | - wait_for_fifo(2, par); |
|---|
| 2377 | | - save_dp_datatype = aty_ld_le32(DP_DATATYPE); |
|---|
| 2378 | | - save_dp_cntl = aty_ld_le32(DP_CNTL); |
|---|
| 2379 | | - |
|---|
| 2380 | | - wait_for_fifo(6, par); |
|---|
| 2381 | | - aty_st_le32(SRC_Y_X, (srcy << 16) | srcx); |
|---|
| 2382 | | - aty_st_le32(DP_MIX, ROP3_SRCCOPY | DP_SRC_RECT); |
|---|
| 2383 | | - aty_st_le32(DP_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM); |
|---|
| 2384 | | - aty_st_le32(DP_DATATYPE, save_dp_datatype | dstval | SRC_DSTCOLOR); |
|---|
| 2385 | | - |
|---|
| 2386 | | - aty_st_le32(DST_Y_X, (dsty << 16) | dstx); |
|---|
| 2387 | | - aty_st_le32(DST_HEIGHT_WIDTH, (height << 16) | width); |
|---|
| 2388 | | - |
|---|
| 2389 | | - par->blitter_may_be_busy = 1; |
|---|
| 2390 | | - |
|---|
| 2391 | | - wait_for_fifo(2, par); |
|---|
| 2392 | | - aty_st_le32(DP_DATATYPE, save_dp_datatype); |
|---|
| 2393 | | - aty_st_le32(DP_CNTL, save_dp_cntl); |
|---|
| 2394 | | -} |
|---|
| 2395 | | - |
|---|
| 2396 | | - |
|---|
| 2397 | | - /* |
|---|
| 2398 | | - * Text mode accelerated functions |
|---|
| 2399 | | - */ |
|---|
| 2400 | | - |
|---|
| 2401 | | -static void fbcon_aty128_bmove(struct display *p, int sy, int sx, int dy, |
|---|
| 2402 | | - int dx, int height, int width) |
|---|
| 2403 | | -{ |
|---|
| 2404 | | - sx *= fontwidth(p); |
|---|
| 2405 | | - sy *= fontheight(p); |
|---|
| 2406 | | - dx *= fontwidth(p); |
|---|
| 2407 | | - dy *= fontheight(p); |
|---|
| 2408 | | - width *= fontwidth(p); |
|---|
| 2409 | | - height *= fontheight(p); |
|---|
| 2410 | | - |
|---|
| 2411 | | - aty128_rectcopy(sx, sy, dx, dy, width, height, |
|---|
| 2412 | | - (struct fb_info_aty128 *)p->fb_info); |
|---|
| 2413 | | -} |
|---|
| 2414 | | -#endif /* 0 */ |
|---|
| 2415 | | - |
|---|
| 2416 | 2327 | static void aty128_set_suspend(struct aty128fb_par *par, int suspend) |
|---|
| 2417 | 2328 | { |
|---|
| 2418 | 2329 | u32 pmgt; |
|---|
| 2419 | | - struct pci_dev *pdev = par->pdev; |
|---|
| 2420 | 2330 | |
|---|
| 2421 | 2331 | if (!par->pdev->pm_cap) |
|---|
| 2422 | 2332 | return; |
|---|
| .. | .. |
|---|
| 2443 | 2353 | aty_st_le32(BUS_CNTL1, 0x00000010); |
|---|
| 2444 | 2354 | aty_st_le32(MEM_POWER_MISC, 0x0c830000); |
|---|
| 2445 | 2355 | msleep(100); |
|---|
| 2446 | | - |
|---|
| 2447 | | - /* Switch PCI power management to D2 */ |
|---|
| 2448 | | - pci_set_power_state(pdev, PCI_D2); |
|---|
| 2449 | 2356 | } |
|---|
| 2450 | 2357 | } |
|---|
| 2451 | 2358 | |
|---|
| 2452 | | -static int aty128_pci_suspend(struct pci_dev *pdev, pm_message_t state) |
|---|
| 2359 | +static int aty128_pci_suspend_late(struct device *dev, pm_message_t state) |
|---|
| 2453 | 2360 | { |
|---|
| 2361 | + struct pci_dev *pdev = to_pci_dev(dev); |
|---|
| 2454 | 2362 | struct fb_info *info = pci_get_drvdata(pdev); |
|---|
| 2455 | 2363 | struct aty128fb_par *par = info->par; |
|---|
| 2456 | | - |
|---|
| 2457 | | - /* Because we may change PCI D state ourselves, we need to |
|---|
| 2458 | | - * first save the config space content so the core can |
|---|
| 2459 | | - * restore it properly on resume. |
|---|
| 2460 | | - */ |
|---|
| 2461 | | - pci_save_state(pdev); |
|---|
| 2462 | 2364 | |
|---|
| 2463 | 2365 | /* We don't do anything but D2, for now we return 0, but |
|---|
| 2464 | 2366 | * we may want to change that. How do we know if the BIOS |
|---|
| .. | .. |
|---|
| 2518 | 2420 | return 0; |
|---|
| 2519 | 2421 | } |
|---|
| 2520 | 2422 | |
|---|
| 2423 | +static int __maybe_unused aty128_pci_suspend(struct device *dev) |
|---|
| 2424 | +{ |
|---|
| 2425 | + return aty128_pci_suspend_late(dev, PMSG_SUSPEND); |
|---|
| 2426 | +} |
|---|
| 2427 | + |
|---|
| 2428 | +static int __maybe_unused aty128_pci_hibernate(struct device *dev) |
|---|
| 2429 | +{ |
|---|
| 2430 | + return aty128_pci_suspend_late(dev, PMSG_HIBERNATE); |
|---|
| 2431 | +} |
|---|
| 2432 | + |
|---|
| 2433 | +static int __maybe_unused aty128_pci_freeze(struct device *dev) |
|---|
| 2434 | +{ |
|---|
| 2435 | + return aty128_pci_suspend_late(dev, PMSG_FREEZE); |
|---|
| 2436 | +} |
|---|
| 2437 | + |
|---|
| 2521 | 2438 | static int aty128_do_resume(struct pci_dev *pdev) |
|---|
| 2522 | 2439 | { |
|---|
| 2523 | 2440 | struct fb_info *info = pci_get_drvdata(pdev); |
|---|
| .. | .. |
|---|
| 2564 | 2481 | return 0; |
|---|
| 2565 | 2482 | } |
|---|
| 2566 | 2483 | |
|---|
| 2567 | | -static int aty128_pci_resume(struct pci_dev *pdev) |
|---|
| 2484 | +static int __maybe_unused aty128_pci_resume(struct device *dev) |
|---|
| 2568 | 2485 | { |
|---|
| 2569 | 2486 | int rc; |
|---|
| 2570 | 2487 | |
|---|
| 2571 | 2488 | console_lock(); |
|---|
| 2572 | | - rc = aty128_do_resume(pdev); |
|---|
| 2489 | + rc = aty128_do_resume(to_pci_dev(dev)); |
|---|
| 2573 | 2490 | console_unlock(); |
|---|
| 2574 | 2491 | |
|---|
| 2575 | 2492 | return rc; |
|---|